i want to interpolate a vector y1 of length 3 to get a vector y2 of length 6.which of the functions interp1 or resample should i use?
ex.
y1=[1 2 3];
y2=[1 2 3 4 5 6 ];
resample(y1,length(y2),length(y1))
Use interp1.
Ex: You have a sinusoidal signal sampled every pi/4.
x = 0:pi/4:2*pi;
v = sin(x);
Now to want a finer sampling xq (every pi/16):
xq = 0:pi/16:2*pi;
The result will be:
vq1 = interp1(x,v,xq);
Where vq1 is a vector whose values are interpolated from vto satisfy the new sampling xq
PD: You can also pass as a parameter which type of interpolation you want: 'linear', 'nearest', 'cubic', etc...
Related
I have a 3D matrix:
A = [5 7 8; 0 1 9; 4 3 6];
A(:,:,2) = [1 0 4; 3 5 6; 9 8 7]
I want to apply a 3D FFT in this matrix using decomposition of 1D FFT. I read that it I should apply 1D FFT in each dimension.
How can I do this?
For x and y, I do this:
for k=0:2
y1 = A(:,k+1,:);
A(:,k+1,:) = fft(y1);
end
for k=0:2
y2 = A(k+1,:,:);
A(k+1,:,:) = fft(y2);
end
For the dimension z, I don't know how to do this.
The fft function accepts a third input specifiying dimension, and is vectorized with respect to the other dimensions. So you can simply use:
result = fft(fft(fft(A, [], 1), [], 2), [], 3);
First, your loops should look like this:
for k=1:size(A,2)
y = A(:,k,:);
A(:,k,:) = fft(y);
end
Second, the loop above is identical to (as #Luis Mendo said in his answer):
A = fft(A,[],2);
There is no need to write a loop at all.
Third, to compute the 1D FFT along the 3rd dimension, you use:
fft(A,[],3);
You could write this as a loop (just to answer your explicit question, I don't recommend you do this):
for k=1:size(A,3)
y = A(:,:,k);
A(:,:,k) = fft(y);
end
If, for some reason, that doesn't work in your version of MATLAB because of the shape of y, you can reshape y to be a column vector:
... fft(y(:));
Finally, to compute the 3D FFT using 1D decompositions, you can simply write
A = fftn(A);
This follows the exact same process you are trying to implement, except it does it much faster.
Consider a set of points (just an example)
x = [0 1 2 5 4 8 5 6];
y = [5 8 4 2 5 6 4 5];
and another reference point:
xc=1;
yc=1;
In which I use to represent these points as vectors:
vec=[x-xc y-yc];
I wish to obtain a matrix with all the angles between all vectors which is obtained by the calculation (for single vectors)
angle = acosd(dot(v,u)/norm(u)*norm(v));
How can I obtain this calculation in a few lines without going vector by vector in a loop? In my calculation the number of points is very very large.
I think you mean vec = [x-xc; y-yc];. To calucate the dotproduct between all rows, you can use
vec.'*vec
The norm (Euclidean) of each vector can be determined as
no = sqrt(sum(vec.*vec,1))
The product of the different norms can be calculated the same as for vec:
no.'*no
The angles can thus be found as
no = sqrt(sum(vec.*vec,1));
angles = acosd(vec.'*vec./(no.'*no));
I have a data set with 5 repeats for each sample and 25 variables.
I am trying to make a Mahalanobis distance matrix between all of the samples using these parameters. I used the "mahal" function, but this gives a vector of all of the distances for each repeat. How can I make a matrix of distances between samples (38*38) and not a vector (1*190)?
For some test data:
X = rand(38,25); % some random test data with 38 observations and 25 variables
X = repmat(X,5,1); % 5 duplicates of each observation
You could use:
X = unique(X,'rows'); % remove duplicate observations
D = pdist(X,'mahalanobis'); % distance between all remaining observations
Z = squareform(D); % to square matrix format
On a stem plot, how can I add points that have the same values of x but different values of y?
For example, given the following code:
x = [1 2 3 6 6 4 5];
y = [3 6 1 8 9 4 2];
stem(x,y);
If you plot x, and y, this will be the output:
I want to add up (6,8) and (6,9) so it becomes (6,17), just like what the image is showing.
How can I achieve this?
Use accumarray with x and y so you can bin or group like entries together that share the same x. Once these values are binned, you can sum all of the values that share the same bin together. As such, we see that for x = 6, we have y = 8 and y = 9. accumarray allows you to group multiple y values together that share the same x. Once these values are grouped, you then apply a function to all of the values in the same group to produce a final output for each group. In our case, we want to sum them, so we need to use the sum function:
x = [1 2 3 6 6 4 5];
y = [3 6 1 8 9 4 2];
Z = accumarray(x(:), y(:), [], #sum);
stem(unique(x), Z);
xlim([0 7]);
We use unique on X so that we have no repeats for X when plotting the stem plot. unique also has the behaviour of sorting your x values. Doing x(:) and y(:) is so that you can make your input data either as row or column vectors independently. accumarray accepts only column vectors (or matrices, but we won't go there) and so doing x(:) and y(:) ensures that both inputs are column vectors.
We get:
The above code assumes that x is integer and starting at 1. If it isn't, then use the third output of unique to assign each number a unique ID, then run this through accumarray. When you're done, use the output of accumarray like normal:
[xu,~,id] = unique(x);
Z = accumarray(id, y(:), [], #sum);
stem(xu, Z);
I have a set of x,y and z data (each is a 3000 by 1 matrix) and I would like to interpolate this data to have a set of values for the z height at evenly spaced x and y values. I assume I need to mesh grid the x and y data sets, but I don't know how to interpolate for the z data. The data points are the unique vertices taken from an STL file, and so I'm looking to smooth out the resulting surface.
Any help much appreciated ,
Tom.
you have the matlab function interp2
then your code will be zi = interp2(x,y,z,xi,yi);
you can generate evenly spaced xi and yi using mesh grid
xi and yi will be the value of x and y at which you will make the interpolation, they are on a square form. E.g., if you want to interpolate at xi = 1 2 3 and yi = 4 5, then
xi will look like
[1 2 3;
1 2 3]
and yi,
[4 4 4;
5 5 5]
hope it helps!