MATLAB Sum along some columns within 3D matrix - matlab

Let's assume I have a 8x6x2 matrix signals. I would like to sum along the columns excluding the first column. When using the following code, MATLAB concatenates the 3D matrix to a big 2D (8x11) matrix, which is different from the result I am looking for.
sum(signals(:, 2:end), 2)
I am actually looking for a 8x1x2 3D vector comprising the sums of column 2 to six from each third dimension.

Since your matrix is a 3D matrix, you need to include a colon as the third subscript in your indexing. If you only specify two subscripts, then MATLAB will collapse all trailing dimensions into the last dimension you've specified.
sum(signals(:, 2:end, :), 2)

Related

Principle of FFT in multidimensional array

How can one explain the principle of fft in a multidimensional array?
Y = fft(X)
If X is a multidimensional array, then fft(X) treats the values along the first array dimension whose size does not equal 1 as vectors and returns the Fourier transform of each vector.
I don't understand it very well.
X=[1 2 ; 3 4];
X(:,:,2)=[5 6 ; 7 8]
Let's take the 2D case for simplicity.
Given a 2D matrix of data, X, one can treat each row vector individually and perform a one-dimensional discrete Fourier transform. This will decompose each row into one dimensional frequency components. No attention is given to whether the rows of the matrix are correlated, and so every row of the output matrix will have some non-zero components.
Alternatively, using fft2, one can decompose X into its constituent two-dimensional frequency components. I find this easiest to think about in analogy with the DCT, where you can visualize the 2D basis easily
With the 2D FFT, correlations between rows would affect the output of the FFT. It's possible a single 2D frequency component (which is more like a surface than a wave) could contain all the energy of the 2D FFT, and so the output matrix could be much sparser than when treating the rows individually.
This analogy can be continued in to n-dimensions, with higher dimensional frequency components potentially capturing the higher dimensional structure in your data.

How to compute the outer product of two binary vectors

I am generating a random binary matrix with a specific number of ones in each row. Now, I want to take each row in the matrix and multiply it by its transpose (i.e row1'*row1).
So, I am using row1=rnd_mat(1,:) to get the first row. However, in the multiplication step I get this error
"Both logical inputs must be scalar. To compute elementwise TIMES, use TIMES (.*) instead."
Knowing that I don't want to compute element-wise, I want to generate a matrix using the outer product. I tried to write row1 manually using [0 0 1 ...], and tried to find the outer product. I managed to get the matrix I wanted.
So, does anyone have some ideas on how I can do this?
Matrix multiplication of logical matrices or vectors is not supported in MATLAB. That is the reason why you are getting that error. You need to convert your matrix into double or another valid numeric input before attempting to do that operation. Therefore, do something like this:
rnd_mat = double(rnd_mat); %// Cast to double
row1 = rnd_mat(1,:);
result = row1.'*row1;
What you are essentially computing is the outer product of two vectors. If you want to avoid casting to double, consider using bsxfun to do the job for you instead:
result = bsxfun(#times, row1.', row1);
This way, you don't need to cast your matrix before doing the outer product. Remember, the outer product of two vectors is simply an element-wise multiplication of two matrices where one matrix is consists of a row vector where each row is a copy of the row vector while the other matrix is a column vector, where each column is a copy of the column vector.
bsxfun automatically broadcasts each row vector and column vector so that we produce two matrices of compatible dimensions, and performs an element by element multiplication, thus producing the outer product.

Multiplying a 3D Matrix with a 1D

I attempted to use the solution from this post: Multiply a 3D matrix with a 2D matrix, to vectorize the multiplication of a one dimensional with a three dimensional, but to no avail. Any help would be greatly appreciated!
for s = 1: s_length
for a = 1: a_length
for g = g_length
two_dim(s,a) = two_dim(s,a) + one_dim(g) * three_dim(s,a,g);
end
end
end
I think this does what you want.
two_dim = reshape(three_dim, [], size(three_dim,3))*one_dim(:);
two_dim = reshape(two_dim, size(three_dim,1), size(three_dim,2));
This works as follows:
First line reshapes your 3D array into a matrix, collapsing the first two dimensions into one. That way the operation you want is standard multiplication of the resulting matrix times a column vector.
Second line reshapes the result into matrix shape.
mtimes does not work with inputs with dimension larger than 2, so you have to find a way to do the multiplication by yourself. The solution of Luis Mendo is a nice solution; here is another one using bsxfun:
two_dim = two_dim + squeeze(sum(bsxfun(#times, three_dim, reshape(one_dim,[1 1 g_length])),3));
Here is how it works:
reshape makes the vector one_dim looking like a 3D array. This must be done because the multiplication between the vector and the 3D array is performed along the 3rd dimension, so Matlab need a hint on sizes.
bsxfun perfoms the element-wise multiplcation, so the result must be sumed up along the 3rd dimension (and squeezed to be compliant with a 2D matrix format)

Extracting vectors along 3-D array in opencv

Is there an efficient way (i.e., without copying data) in openCV to create vector along the third dimension of a 3D Mat, like in MATLAB:
X=rand(3,4,5);
V=squeeze(X(2,2,:));% vector along the third dimension of elements in second row and col.
Thanks

Making a 3D plot of multiple column vectors

I have multiple vectors of varying lengths that I would like to plot next to each other in 3D space in Matlab.
As an example:
Say I have three vectors:
X is a 5x2 vector,
Y is a 10x2 vector and
Z is a 15x2 vector.
Each element of every vector has the format:
x value, y value
but the x values of the various vectors do not match.
I would like to plot these vectors in 3D space, next to each other. The reason why I don't want to plot them using "hold" is because most of the data have the same values, but I would like to see how many of the plots have the same value at a specific time.
I hope my questions makes sense. Please just ask if anyone is unsure.
I think you are looking for the function ribbon.
Documentation: http://www.mathworks.fr/help/techdoc/ref/ribbon.html
EDIT:
if your x's do not have the same length, you can combine it with interp1 as follow:
x1=0:0.1:1;
x2=0:0.02:1.5;
y1=x1.^2;
y2=sqrt(x2);
y2=interp1(x2,y2,x1);
ribbon(x1',[y1;y2]')