Matlab dwt across specified dimension - matlab

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.

Related

extrapolating a 2D matrix to predict a future output

I have a 2D 2401*266 matrix K which corresponds to x values (t: stored in a 1*266 array) and y values(z: stored in a 1*2401 array).
I want to extrapolate the matrix K to predict some future values (corresponding to t(1,267:279). So far I have extended t so that it is now a 1*279 matrix using a for loop:
for tq = 267:279
t(1,tq) = t(1,tq-1)+0.0333333333;
end
However I am stumped on how to extrapolate K without fitting a polynomial to each individual row?
I feel like there must be a more efficient way than this??
There are countless of extrapolation methods in the literature, "fitting a polynomial to each row" would be just one of them, not necessarily invalid, not sure why you mention that you do no wan't to do it. For 2D data perhaps fitting a surface would lead to better results though.
However, if you want an easy, simple way (that might or might not work with your problem), you can always use the function interp2, for interpolation. If you chose spline or makima as interpolation functions, it will also extrapolate for any query point outside the domain of K.

Grouping Data in a Matrix in MATLAB

I've got a really big matrix which I should "upscale" (i.e.: create another matrix where the elements of the first are grouped 40-by-40). For every 40-by-40 group I should evaluate a series of parameters (i.e.: frequencies, average and standard deviation).
I'm quite sure I can make such thing with a loop, but I was wondering if there was a more elegant vectorized method...
You might find blockproc useful. This command allows you to apply a function (e.g. #mean, #std etc.) to each distinct block in a 2D matrix.

MATLAB - apply multiple convolution masks to a single matrix

I need to convolve a matrix with many other matrices with few calls to convn.
for example: I have size(MyMat)=[fm, fm ,1, bSize] and size(masks)=[s, s, maskNum]
I want res(:,:,k,:) to be the product of convolving masks(:,:,k) with MyMat
res(:,:,k,:)=convn(MyMat,masks(:,:,k));
since the convolution takes up over 80% of the running time for my script and is called hundreds of thousands of times, I don't want to use a loop.
I'm looking for the fastest way to do this. basically, you could say I have bSize matrices, and I want to apply convolution masks masks to all of them with as few calls as possible to convolution.
The matrices are all small,non-sparse, fft-based convolution will probably slow it down (as a commentor here verified :) )
(The reason I have a 1 in the size of MyMat is because I actually have more elements in that dimension, but I compute the convolution for each element in that dimension in a loop)
The main goal is simply to eliminate the need for the following loop, or make it parallel with very little overhead, if possible:
for i=1:length
res(:,:,:,i)=convn(MyArray,convMask(:,:,i));
end
parallelizing for the GPU would be great if there's a way to do this with less overhead than the usual parfor
Thank you!
I assume that you are preallocating the array res correctly? Without a simple demo of what your doing and an idea of the size of fm, s, etc., one can only make guesses to help you. If the sizes of your matrices are large enough you might look into FFT-based convolution methods (there are some for convn on the Matlab File Exchange). If the data is sparse (> 50% zeros), you could try converting this to matrix multiplication and use sparse data types. You could also try gpuArray/convn if you have a decent one.

Cross-correlation in matlab without using the inbuilt function?

can someone tell how to do the cross-correlation of two speech signals (each of 40,000 samples) in MATLAB without using the built-in function xcorr and the correlation coefficient?
Thanks in advance.
You can do cross-correlations using fft. The cross-correlation of two vectors is simply the product of their respective Fourier transforms, with one of the transforms conjugated.
Example:
a=rand(5,1);
b=rand(5,1);
corrLength=length(a)+length(b)-1;
c=fftshift(ifft(fft(a,corrLength).*conj(fft(b,corrLength))));
Compare results:
c =
0.3311
0.5992
1.1320
1.5853
1.5848
1.1745
0.8500
0.4727
0.0915
>> xcorr(a,b)
ans =
0.3311
0.5992
1.1320
1.5853
1.5848
1.1745
0.8500
0.4727
0.0915
If there some good reason why you can't use the inbuilt, you can use a convolution instead. Cross-correlation is simply a convolution without the reversing, so to 'undo' the reversing of the correlation integral you can first apply an additional reverse to one of your signals (which will cancel out in the convolution).
Well yoda gave a good answer but I thought I mention this anyway just in case. Coming back to the definition of the discrete cross correlation you can compute it without using (too much) builtin Matlab functions (which should be what Matlab do with xcorr). Of course there is still room for improvment as I did not try to vectorize this:
n=1000;
x1=rand(n,1);
x2=rand(n,1);
xc=zeros(2*n-1,1);
for i=1:2*n-1
if(i>n)
j1=1;
k1=2*n-i;
j2=i-n+1;
k2=n;
else
j1=n-i+1;
k1=n;
j2=1;
k2=i;
end
xc(i)=sum(conj(x1(j1:k1)).*x2(j2:k2));
end
xc=flipud(xc);
Which match the result of the xcorr function.
UPDATE: forgot to mention that in my opinion Matlab is not the appropriate tool for doing real time cross correlation of large data sets, I would rather try it in C or other compiled languages.

3D Gaussian Filter in MATLAB

Is there a 3D eqivalent of imfilter available for MATLAB? I wish to apply Gaussian filtering to a 3D histogram. I was going to implement it myself, by creating a (3D) Gaussian filter, then looping over each element in my histogram, and summing up the corresponding data entries.
However, I didn't want to implement it myself in a slow and inefficient way if there's something already out there, or a cleverer way of doing it.
There are two ways to solve this in order to do the filtering in an efficient manner:
(1) Use CONVN three times to filter your data with three 1D Gaussians, one x-by-1-by-1, one 1-by-y-by-1, and one 1-by-1-by-z.
(2) If you have the signal processing toolbox, use FFTFILT to perform filtering in inverse space (or use any one of the fft-convolution algorithms on the file exchange).
[(3) Send me an email and I'll send you my fftFilterImage, which does 3D Gauss filtering.]
imfilter can already do 3D filtering, as long as the data matrix and the filter you give it are 3D. See the imfilter page.
This task can be handled with the new (as of R2015a) imgaussfilt3 function.
The basic syntax is as follows:
B = imgaussfilt3(A,sigma)
There are also a number of name-value pair arguments:
'FilterSize': Size of the Gaussian filter, defaulting to a cube of size 2*ceil(2*sigma)+1.
'Padding': Type of padding ('replicate' (default) | 'circular' | 'symmetric').
'FilterDomain': Perform convolution in domain: 'frequency' or 'spatial' (default auto).