Do 1-D convolution along each row of a matrix - matlab

Did a quick search and couldn't find much about this. Say I have a 2D matrix and a 1D 'response function'. I want to convolve each row of the 2D matrix with the response function. I can do this by:
for i=1:numrows
answer(:,i) = conv(2dmatrix(:,i),response_function,'same');
end
but it's super slow! Any tips to accelerate this?
Thanks

This code reproduces your results on randomly generated matrices:
conv2(response_function,1,2dmatrix,'same')
conv2 allows you to convolute along rows and columns separately, so do nothing to the rows, 1, and convolve the columns by response_function.
To convolve along each row, swap the order of the first two function arguments.

conv2 has somewhat weird syntax, I would prefer using convn for generalized n dimensional convolution. When one of the inputs is just a row vector then convolution in every other dimension is essentially a convolution with [1] so it doesn't change anything, only preforming convolution along each row. Similarly if your a matrix convoluted with a column vector then it would do convolution along each column.
answer = convn(2dmatrix, response_function);

Related

3D Convolution in MATLAB

I'm currently trying to use convolution to average blocks in my data and turn my current, 336x264x25x27, grid into a new, 100x100x27, grid.
To achieve this I've been trying to use convolution.
In a 2-D setting I've been able to convert a 336x264 matrix to 100x100 using the conv2 function in matlab. I'm now trying to use convn to accomplish a similar task in 4-D.
As stated, currently I'm using the convn function. I'm trying to average out cells over the first two dimensions so that I end up with a 100x100x27 matrix. My code is as follows:
A = rand(336,264,25,27); % Sample Data
A = A(:,:,13,:); % This line and the following line eliminate the third dimension (time) which will be constant throughout my output. Now "A" is 336x264x27 after using "squeeze".
A = squeeze(A);
B = ones(100,100,27); % This is the size of matrix that I would like to achieve. I was under the impression that "B" was the size matrix that you want to inevitably end up with but I believe I am mistaken.
C = convn(A,B); % C would hopefully by my 100x100x27 matrix.
Currently, this is resulting in a 435x363x53 matrix. If you could help me with my logic and show me how I might turn "A" into a 100x100x27 matrix using convolution it would be much appreciated!

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.

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)

MATLAB: plotting multiple columns of a matrix

Inside a MATLAB function I have built a matrix A, whose dimensions M and N are set as parameters of the function. I would like to plot all the columns of this matrix, given a vector of indices B with length M. Hence, I use these lines:
figure
plot(B,A)
I specified figure as the MATLAB function returns more different plots.
My problem is that the program plots just two columns of the matrix with different colours (blue and violet). Where is my mistake?
Thank you for your attention.
go for
plot(repmat(B,1,N),A);
or
plot(repmat(B,N,1),A);
(depending on your rows/columns). You need to have same size matrices in plot.
Moreover, if B are just consecutive indexes, you may want to consider Plot(A) (or Plot(A')).
I noticed that there was an error which caused the overlap of the different curves, so the way which I used to plot the colums of a matrix is valid. However, the method proposed by Acorbe is a possibility, too.

Correlation matrix to set of vectors

I try to calculate the correlation matrix of a set of histogram vectors. But the result is a truncated version of what I (think) I want. I have 200 histograms by 32 bins each. The result from
correlation_matrix = corrcoef(set_of_histograms)
is a 32 by 32 matrix.
I want to use this to calculate how my original histograms match up. (this by later using eigs and other stuff).
But which correlation method is right for this? I have tried "corrcoef" but there are "corr" and "cov" as well. Can't understand their differences by reading matlab help...
correlation_matrix = corrcoef(set_of_histograms')
(Note the ')
1) corrcoef treats every column as an observation, and calculates the correlations between each pair. I'm assuming your histograms matrix is 200x32; hence, in your case, every row is an observation. If you transpose your histograms matrix before running corrcoef, you should get the 200x200 result you're looking for:
[rho, p] = corrcoef( set_of_histograms' );
(' transposes the matrix)
2) cov returns the covariance matrix, not the correlation; while the covariance matrix is used in calculating the correlation, it is not the measure you're looking for.
3) As for corr and corrcoef, they have a few implementation differences between them. As long as you are only interested in Pearson's correlation, they are identical for your purposes. corr also has an option to calculate Spearman's or Kendall's correlations, which corrcoef does not have.