Suppose I have a 3x4 matrix
Now how to calculate a matrix of the same size, which contains each element being a sum of itself and all elements, which are higher and lefter than it?
You must be looking for cumsum:
integ = cumsum( cumsum( A, 1 ), 2 );
For example:
A = [1 2 3;
4 5 6];
cumsum( cumsum( A, 1 ), 2 )
Results with:
1 3 6
5 12 21
PS,
This operation is sometimes refereed to as integral image.
Related
I got a vector of numbers with length 6 like this a = [1 2 3 4 5 6] and I want to reconstruct the corresponding 4-by-4 matrix A like this where all the element from the diagonal to the other lower diagonal are all zero.
A = [0 1 2 3
0 0 4 5
0 0 0 6
0 0 0 0]
The relationship between the vector a and the corresponding matrix A is that if the dimension of the matrix is K then the length of vector a is K(K-1)/2. In this case the length of a is 6 which mean K = 4.
Another example case would be a = [1 2 3] then
A = [0 1 2
0 0 3
0 0 0
How can I do this?
If you have the Statistics Toolbox, just use squareform and triu:
a = [1 2 3 4 5 6];
A = triu(squareform(a, 'tomatrix'));
Without the toolbox:
a = [1 2 3 4 5 6];
n = (1 + sqrt(1+8*numel(a)))/2; % size of matrix
A = zeros(n); % initiallize
A((1:n).'>(1:n)) = a; % build logical mask using implicit expansion, and fill the
% lower half of the matrix with the desired values in column-major order
A = A.'; % transpose to put the values into the upper half in row-major order
I am trying to sort an array based on another array. I tried the sort method with index return, but it is somehow behaving strangely.
y = [1 2 3; 2 3 4]
x = [1 3 4; 2 2 3]
[yy, ii] = sort(y,'descend');
yy =
2 3 4
1 2 3
ii =
2 2 2
1 1 1
But my x(ii) is not the matrix sorted based on y.
x(ii) =
2 2 2
1 1 1
I am expecting the matrix to be:
x(ii) =
2 2 3
1 3 4
How can I sort the matrix x according to another matrix y?
ii are row subscripts but are being inputted by you as linear indices.
You need to convert them to relevant linear indices before proceeding i.e.
>> szx = size(x);
>> x(sub2ind(szx, ii, repmat(1:szx(2),szx(1),1)))
ans =
2 2 3
1 3 4
I have two vectors, R and C, which have the number of rows and columns, respectively, of submatrices that I need to assemble in a ones matrix I (40x20). There's 12 submatrices total.
R = [4 2 4 4 2 4];
C = [4 16 16 4];
Moreover, all the elements of each submatrix have its value stored in vector k:
k = [3 2 3 3 2 3 2 1 2 2 1 2 2 1 2 2 1 2 3 2 3 3 2 3 ]; % 24 elements
Thus for instance, submatrix M(1:4,1:4) has 4 rows, and 4 columns and value equal to k(1) = 1.
QUESTION: How can I assemble matrix M with all submatrices?
Any ideas?
Thanks!
EDIT:
The matrix M should look like this:
and the submatrices:
and the values of k:
Here is a vectorized solution:
R1 = repelem(1:numel(R), R);
C1 = repelem(1:numel(C), C);
[CC RR] = meshgrid(C1, R1);
idx = sub2ind([numel(R), numel(C)], RR, CC);
result = k(idx);
Instead you can use cell array, fill it with sub matrices and then convert the cell array to a matrix.
carr = cell(numel(R), numel(C));
k1 = reshape(k,numel(R),numel(C));
for ii = 1:numel(R)
for jj = 1:numel(C)
carr(ii,jj)=repmat(K1(ii,jj), R(ii), C(jj));
end
end
result = cell2mat(carr)
Is there a way to create matrix that is consisted of a certain numbers that are stored in an array? For example, I want to create a 10-by-1 matrix consisting only of numbers from an array a = [6,2,15,24], that are randomly stored in matrix elements. The final product should look something like this:
M = [15,24,2,15,2,6,24,15,2,15]
If you have the Statistics toolbox, you can use randsample with the third argument set to true to indicate that the data a is to be sampled with replacement:
a = [6 2 15 24];
M = randsample(a,10,true)
function b = resample( a, size )
indices = randi( numel( a ), size );
b = a( indices );
Example:
>> resample( [6,2,15,24], [4,5] )
ans =
2 6 15 2 6
2 2 15 15 6
24 6 6 2 6
2 6 24 6 2
Suppose A is a 3-D matrix as below (2 rows-2 columns-2 pages).
A(:,:,1)=[1,2;3,4];
A(:,:,2)=[5,6;7,8];
I want to have a vector, say "a", whose inputs are the average of diagonal elements of matrices on each page. So in this simple case, a=[(1+4)/2;(5+8)/2].
But I have difficulties in matlab to do so. I tried the codes below but failed.
mean(A(1,1,:),A(2,2,:))
You can use "partially linear indexing" in the two dimensions that define the diagonal, as follows:
Since partially linear indexing can only be applied on trailing dimensions, you first need to apply permute to rearrange dimensions, so that the first and second dimensions become second and third.
Now you leave the first dimension untouched, linearly-index the diagonals in the second and third dimensions (which effectly reduces those two dimensions to one), and apply mean along the (combined) second dimension.
Code:
B = permute(A, [3 1 2]); %// step 1: permute
result = mean(B(:,1:size(A,1)+1:size(A,1)*size(A,2)), 2); %// step 2: index and mean
In your example,
A(:,:,1)=[1,2;3,4];
A(:,:,2)=[5,6;7,8];
this gives
result =
2.5000
6.5000
You can use bsxfun for a generic solution -
[m,n,r] = size(A)
mean(A(bsxfun(#plus,[1:n+1:n^2]',[0:r-1]*m*n)),1)
Sample run -
>> A
A(:,:,1) =
8 4 1
7 6 3
1 5 8
A(:,:,2) =
1 7 6
8 5 2
1 2 7
A(:,:,3) =
6 2 8
1 1 6
1 4 5
A(:,:,4) =
8 1 6
1 5 1
9 2 7
>> [m,n,r] = size(A);
>> sum(A(bsxfun(#plus,[1:n+1:n^2]',[0:r-1]*m*n)),1)
ans =
22 13 12 20
>> mean(A(bsxfun(#plus,[1:n+1:n^2]',[0:r-1]*m*n)),1)
ans =
7.3333 4.3333 4 6.6667