How can I concatenate many column vectors into one matrix? - matlab

I want to concatenate 100 column vectors into one matrix. The code is the following:
for i = 1:100
X = mean(TMP(i).SonarReturnData.BeamsOutput(1:200, 25:35), 2);
end
What I want is to concatenate all 100 column vectors (each 200x1 length vectors) into one matrix (which should become a 200x100 matrix). I tried to use C = cat(2,X(:)), but it didn't work. Does anyone have an idea? Thank you.

Just pre-allocate X with your desired 200x100 size and then index into columns of X appropriately in your loop. I.e.,
X = zeros(200, 100);
for i = 1:100
X(:,i) = mean(TMP(i).SonarReturnData.BeamsOutput(1:200, 25:35), 2);
end

Related

Divide a matrix and its corresponding vector into submatrices and subvectors in MATLAB

I have two matrices X (122 x 125973) and Y (1 x 125973). I want to split in the same way X and Y into smaller matrices and vectors of 122 x 1024 (column division) in Matlab.
I have tried several methods (mat2cell, loops, etc), but I think I am missing the syntax. Any help ?
Note: 125973 can't be divided by 1024, so the last matrix (and vector) will the have the size of (122 x 21) (and (1 x 21) respectively). Thank you for your help!
Since your sub-matrices do not have equal size, you cannot put them in a 3D array (without NaN or zero padding). So you can use a cell. To do this with mat2cell you have to specify how many rows of the original matrix should be put in each individual entry of the cell:
X = rand(122,125973);
Y = rand(1,125973);
% your number of rows per 'block'
n = 1024;
% the number of cols per cell entry:
colDist = [repelem(n, floor(size(X,2)/n)) rem(size(X,2),n)];
Xcell = mat2cell(X, size(X,1), colDist);
Ycell = mat2cell(Y, size(Y,1), colDist);
Here repelem(n, floor(size(X,2)/n)) repeats n for the number of times n fits in the number of columns of X. Then I append the remainder for the number of columns at the end (rem(size(X,2),n)) of this division to this row vector colDist.
When calling mat2cell (mat2cell(X, rowDist, colDist)) the second argument rowDist should then contain the number of rows per cell entry, which for each cell entry will be equal to the number of rows in X or Y.
Alternatively, you can use a loop to divide the matrix and vector in sub-matrices and put them in the appropriate cell.
Xcell = cell(ceil(size(X,2)/n),1);
Ycell = cell(ceil(size(X,2)/n),1);
% put in the blocks of n rows
for k = 1:floor(size(X,2)/n)
indices = n*(k-1)+1:n*k;
Xcell{k} = X(:,indices);
Ycell{k} = Y(:,indices);
end
% and the remainder:
Xcell{end} = X(:, indices(end)+1:end);
Ycell{end} = Y(:, indices(end)+1:end);

How to stack submatrices of a matrix to reduce dimensionality

I couldn't find a good solution for this:
I have a matrix of this size: 60x10x3
And I want to transform it into a matrix of this size: 600x3
Basically I want to stack the 10 matrices with the dimension 60x3 next to each other in the first dimension.
How can I achieve that elegantly in matlab?
It seems that I don't understand what the intended output is, but here are two different ways to achieve it. I added the loop to create different numbers so the results can be studied.
Method 1 - Stack Vertically or Horizontally
s = zeros(60,10,3);
for x = 1:9
s(:,x,:) = x;
end
t = reshape(s, 600, 3); %vert
u = t'; %hori
Method 2 - Stack 3rd dimension Vertically or horizontally
s = zeros(60,10,3);
for x = 1:9
s(:,x,:) = x;
end
t = [s(:,:,1) , s(:,:,2), s(:,:,3)]; % hori
t = [s(:,:,1) ; s(:,:,2); s(:,:,3)]; % vert
Hope it helps, but this shows that there are multiple ways to achieve the same output in Matlab. Very powerful tool indeed.
A = rand(60, 10, 3);
B = reshape(A, [], size(A, 3));
should work for any dimensions of A.
Here is a solution that
stack[s] the 10 matrices with the dimension 60x3 next to each other in the first dimension.
a = rand(60,3,10);
% swap the 2nd and 3rd dimention
b = permute(a,[1,3,2]);
% condense to 2d
c = b(:,:);
% reshape x, y and z seperately so each group of 60 xs/ys/zs appends to the end of the previous group
x=reshape(c(:,1:3:end),[],1);
y=reshape(c(:,2:3:end),[],1);
z=reshape(c(:,3:3:end),[],1);
% condense to one 600*3 matrix
d = [x y z];

Matlab code for generating a particular class of matrices

I need to generate all square matrices of order n with given properties.
Matrices are symmetric.
Entries are 0 and 1.
Diagonal elements are zeros.
I am using Matlab2012b. Can you help me with the code?
I was trying to write it down. It needs a long sequences of for loops. Any simpler technique?
Try this:
N = 4; %// matrix size
M = (N^2-N)/2; %// number of values to fill in each matrix
P = 2^M; %// number of matrices
x = dec2bin(0:P-1)-'0'; %// each row contains the values of a matrix, "packed" in a vector
result = NaN(N,N,P); %// preallocate
for k = 1:P
result(:,:,k) = squareform(x(k,:)); %// unpack values
end
The matrices are result(:,:,1), result(:,:,2) etc.

Sum over blocks in a 3D matrix - MATLAB

For a 3N by 3N by 3N matrix A, I would like to derive a N by N by N matrix B whose entries come from summation over blocks in A.
For example, B(1,1,1) = sum of all elements of A(1:3,1:3,1:3).
Basically, A is kind of a high resolution matrix and B is a low resolution matrix from summing over entries in A.
If memory is not a concern, you can use a "labelling" approach: build a 3-component label to group the elements of A, and use that label as the first input argument to accumarray to do the sum. The label uses integers from 1 to N, so the result of accumarray already has the desired shape (NxNxN).
N = 5;
F = 3; %// block size per dimension
A = rand(15,15,15); %// example data. Size FN x FN x FN
[ii jj kk] = ind2sub(size(A), 1:numel(A));
label = ceil([ii.' jj.' kk.']/F);
result = accumarray(label, A(:));
reshape + sum based approach and as such has to be pretty efficient -
sumrows = sum(reshape(A,3,[]),1); %// Sum along rows
sumcols = sum(reshape(sumrows,N,3,[]),2); %// Sum along cols
B = reshape(sum(reshape(sumcols,N*N,3,[]),2),N,N,N); %// Sum along 3rd dim
If you are crazy about one-liners, here's that combining all steps into one -
B = reshape(sum(reshape(sum(reshape(sum(reshape(A,3,[]),1),N,3,[]),2),N*N,3,[]),2),N,N,N);
For a 2D matrix, this would work:
B = reshape(sum(im2col(A, [3 3], 'distinct')), [N N]);
NB: You need the image processing toolbox.
But for 3D matrices, I don't know of any built-in function equivalent to im2col. You might have to use a loop. Left as an exercise to the reader ;)

Matlab: Access matrix elements using indices stored in other matrices

I am working in matlab. I have five matrices in ,out, out_temp,ind_i , ind_j, all of identical dimensions say n x m. I want to implement the following loop in one line.
out = zeros(n,m)
out_temp = zeros(n,m)
for i = 1:n
for j = 1:m
out(ind_i(i,j),ind_j(i,j)) = in(ind_i(i,j),ind_j(i,j));
out_temp(ind_i(i,j),ind_j(i,j)) = some_scalar_value;
end
end
It is assured that the values in ind_i lies in range 1:n and values in ind_j lies in range 1:m.
I believe a way to implement line 3 would give the way to implement line 4 , but I wrote it to be clear about what I want.
Code
%// Calculate the linear indices in one go using all indices from ind_i and ind_j
%// keeping in mind that the sizes of both out and out_temp won't go beyond
%// the maximum of ind_i for the number of rows and maximum of ind_j for number
%// of columns
ind1 = sub2ind([n m],ind_i(:),ind_j(:))
%// Initialize out and out_temp
out = zeros(n,m)
out_temp = zeros(n,m)
%// Finally index into out and out_temp and assign them values
%// using indiced values from in and the scalar value respectively.
out(ind1) = in(ind1);
out_temp(ind1) = some_scalar_value;