I am trying to do a 'convolution' of an arbitrary N-dimensional surface with a vector. More specifically, I am trying to get the output of an N-th order Volterra kernel (see http://www.scholarpedia.org/article/Volterra_and_Wiener_series, eq.1)
Thus, for a 1-dimensional kernel, the output is the simple sliding convolution of the 1st order kernel with the past input epoch. It essentially multiplies/weights every value in the past input epoch with a coefficient.
The 2nd order kernel output is a 'convolution' of a 2d matrix with a signal. This kernel weighs the product of every pair of points in the past with a coefficient.
The 3rd order kernel, a 3d matrix, weighs every triplet of points in the past memory epoch.
Also, I dont know the dimension/order of the kernel before hand. It is an input parameter..
I know I can probably do this very unelegantly and slowly by going through with several for loops point by point, but I was wondering if there was a way to do this very quickly and elegantly in matlab?
Thanks
you can check the dimension of a variable with ndims(array), and do convolutions on the needed dimensions: conv() or conv2() for one-dimension and 2-dimensions respectively. If you need to do a convolution on a higher dimension, you can reshape your variable with the reshape command and then use the previous commands.
Related
I have a Simulink simulation that takes a control input U on an Inport, and simulates the state of the system based on that input. I want the simulation to use a variable time-step ode solver, but U is going to be defined as discrete time points (that aren't evenly spaced) that certainly aren't going to align with the times that are generated by (say) ode15s.
I want Simulink to take the U vector and a time vector, and use cubic spline interpolation to determine the value of U for times that do not align with the given U vector--similar to the 'Interpolate Data' option in the Inport preferences, except again my data is neither evenly spaced, nor do I want linear interpolation. How can I do this?
A possible way to achieve this is the following. I am assuming the U vector is already known beforehand. This is implied from the fact the vector values are given at random sample moments which are not matching with the solver sample moments.
Take an '1-D interpolation table' block and connect a 'Clock' block as input. In the 1-D interpolation table you are able to specify 'Table data' in your case the values of the U vector. And you are able to specify the breakpoints that are in your case the time points. These can be variables from your workspace.
Then under the tabled 'Algorithm' you choose 'Cubic spline' for the interpolation method.
That should do the trick.
Can someone explain to me the correlation function corr2 in MATLAB? I know that it is for 2D comparing similarities of objects, but in the equation I have doubts what it is A and B (probably matrices for comparison), and also Amn and Bmn.
I'm not sure how MATLAB executes this function, because I have found in several cases that the correlation is not executed for the entire image (matrix) but instead it divides the image into blocks and then compares blocks of one picture with blocks of another picture.
In MATLAB's documentation, the corr2 equation is not put as referral point to the way the equation itself is calculated, like in other functions in MATLAB's documentation, such as referring to what book it is taken from and where it is explained.
The correlation coefficient is a number representing the similarity between 2 images in relation with their respective pixel intensity.
As you pointed out this function is used to calculate this coefficient:
Here A and B are the images you are comparing, whereas the subscript indices m and n refer to the pixel location in the image. Basically what Matab does is to compute, for every pixel location in both images, the difference between the intensity value at that pixel and the mean intensity of the whole image, denoted as a letter with a straightline over it.
As Kostya pointed out, typing edit corr2 in the command window will show you the code used by Matlab to compute the correlation coefficient. The formula is basically this:
a = a - mean2(a);
b = b - mean2(b);
r = sum(sum(a.*b))/sqrt(sum(sum(a.*a))*sum(sum(b.*b)));
where:
a is the input image and b is the image you wish to compare to a.
If we break down the formula, we see that a - mean2(a) and b-mean2(b) are the elements in the numerator of the above equation. mean2(a) is equivalent to mean(mean(a)) or mean(a(:)), that is the mean intensity of the whole image. This is only calculated once.
The 3rd line of code calculates the coefficient. Here sum(sum(a.*b)) calculates the double-sum present in the formula element-wise, that is considering each pixel location separately. Be aware that using sum(a) calculates the sum in every column individually, hence in order to get a single value you need to apply sum twice.
That's pretty much the same happening in the denominator, however calculations are performed on a-mean2(a)^2 and b-mean2(b)^2. You can see this a some kind of normalization process in which you consider the pixel intensity difference among each individual image.
As for your last comment, you can break down an image into small blocks and calculate the correlation coefficient on them; that might save some time for very large images but since everything is vectorized the calculation is quite fast. It might be useful in distributed processing I guess. Of course the correlation coefficient between 2 blocks of images is not necessarily identical to that of the whole image.
For the sake of curiosity you can look at this paper which highlights some caveats in using the correlation coefficient for image comparison.
Hope that makes things a bit clearer!
I'm currently doing a fluid simulation. The flow is calculated in discretized steps of 0.0625 s. I think the flow is periodic in all points because it is periodic in some points.
I also calculated the Fourier Transform of this. There was a minor peak at 0.5356 Hz (and some more at higher frequencies). So the period is 1.8671 s. This was consistent with the corresponding signal.
But now I want to prove that this counts for all the nodes of my mesh (around 7000 nodes). Is there a fast way for doing this in MATLAB?
Thanks
(I would have loved to add pictures but I couldn't)
Yes.
If the input X is a matrix, Y = fft(X) returns the Fourier transform of each column of the matrix. This is considerably faster than looping through each column and calling fft(x) one at a time.
You will need to reshape your input data into a 2-D matrix, where the row dimension is time, for the analysis.
In MATLAB I need to generate a second derivative of a gaussian window to apply to a vector representing the height of a curve. I need the second derivative in order to determine the locations of the inflection points and maxima along the curve. The vector representing the curve may be quite noise hence the use of the gaussian window.
What is the best way to generate this window?
Is it best to use the gausswin function to generate the gaussian window then take the second derivative of that?
Or to generate the window manually using the equation for the second derivative of the gaussian?
Or even is it best to apply the gaussian window to the data, then take the second derivative of it all? (I know these last two are mathematically the same, however with the discrete data points I do not know which will be more accurate)
The maximum length of the height vector is going to be around 100-200 elements.
Thanks
Chris
I would create a linear filter composed of the weights generated by the second derivative of a Gaussian function and convolve this with your vector.
The weights of a second derivative of a Gaussian are given by:
Where:
Tau is the time shift for the filter. If you are generating weights for a discrete filter of length T with an odd number of samples, set tau to zero and allow t to vary from [-T/2,T/2]
sigma - varies the scale of your operator. Set sigma to a value somewhere between T/6. If you are concerned about long filter length then this can be reduced to T/4
C is the normalising factor. This can be derived algebraically but in practice I always do this numerically after calculating the filter weights. For unity gain when smoothing periodic signals, I will set C = 1 / sum(G'').
In terms of your comment on the equivalence of smoothing first and taking a derivative later, I would say it is more involved than that. As which derivative operator would you use in the second step? A simple central difference would not yield the same results.
You can get an equivalent (but approximate) response to a second derivative of a Gaussian by filtering the data with two Gaussians of different scales and then taking the point-wise differences between the two resulting vectors. See Difference of Gaussians for that approach.
I have a dataset Sig of size 65536 x 192 in Matlab. If I want to take the one-dimensional fft along the second dimension, I could either do a for loop:
%pre-allocate ect..
for i=1:65536
F(i,:) = fft(Sig(i,:));
end
or I could specify the dimension and do it without the for loop:
F = fft(Sig,[],2);
which is about 20 times faster for my dataset.
I have looked for something similar for the discrete wavelet transform (dwt), but been unable to find it. So I was wondering if anyone knows a way to do dwt across a specified dimension in Matlab? Or do I have to use for loops?
In your loop FFT example, it seems you operate on lines. Matlab use a Column-major order. It may explain the difference of performance. Is the performance the same if you operate on columns ?
If this is the right explanation, you could use dwt in a loop.
A solution if you really need performance is to do your own MEX calling a C discrete wavelet transform library the way you want.
I presume you're using the function from the Wavelet Toolbox: http://www.mathworks.co.uk/help/toolbox/wavelet/ref/dwt.html
The documentation doesn't seem to describe acting on an array, so it's probably not supported. If it does allow you to input an array, then it will operate on the first non-singleton dimension or it will ignore the shape and treat it as a vector.