Interpolating data in 1D with 2D sample points and a 2D matrix - matlab

I have a matrix of Temperatures ( T - [120xN] ) at different heights ( H - [120xN] ).
I want to obtain the Temperatures at a set vector of heights ( Hnew - [100x1] ], where N is the total number of lines I want to independently interpolate in 1D.
I can solve this with a loop quite easily
Tnew = zeros(length(Hnew),N);
for i-1:N
Tnew(:,i) = interp1(H(:,i),T(:,i),Hnew);
end
But since I have many iterations to perform (N ~ 2 million), I am looking for a solution without a loop.
What is the optimum way to do this in matlab?

Related

Create sum of sine wave series as matrix

I want to create a function that represents a sum of sine waves of different frequencies modulated by n (which should run from 2 to 10, with interval of 1)
This function is then a function of time which will be a linear space from 0 to 3 second. And I need the result to be presented in a matrix. I have the problems with matrix dimensions and i dont know how to fix this.
t1 = linspace (0,3,1000);
n = 2:1:10;
S1 = sin(1/4 - 1/n.^2)*2*pi.*t1*440
I think what you wanna do is something like:
S1 = sin(1/4 - 1./n.^2)*2*pi.*t1'*440
The vector n is sized (1x9) and t1 is sized (1,1000), so you just have to transposed the vector t1 with the symbol ' to respect the Algebra multiplication of matrices/vectors.
Hope it helped!

How to sum 3d Matrix row by interval in Matlab?

I have a 36x256x2232 3d matrix in Matlab created by M = ones(36,256,2232) and I want to reduce the size of the matrix by sum rows by interval 3. The result matrix should be 12x256x2232 and each cell should have the value 3.
I tried using reshape and sum function but I get 1x256x2232 matrix.
How can I do this without using the for-loop ?
This should do it:
M = ones(36,256,2232)
reduced = reshape(sum(reshape(M, 3,[], 256,2232), 1),[], 256, 2232);
reshape makes a 4d matrix with the given intervals
sum reduce it
second reshape transform it to 3d again
you can use also squeeze, which removes singleton dimensions:
reduced = squeeze(sum(reshape(M, 3,[], 256,2232), 1));
You can use the new-ish splitapply function (which is similar to accumarray but can handle data with multiple dimensions). This approach works even if the number of rows is not a multiple of the group size:
M = ones(4,5,2); % example data
n = 3; % group size
result = splitapply(#(x)sum(x,1), M, floor((0:size(M,1)-1).'/n)+1);

Vectorization for PCA in Matlab

I have a matrix A of 3D point coordinates, so the size of A is N by 3, where N is the number of points. I did a knnsearch on A for 20 neighbors and got a index matrix idN, which is N by 21. Then I want to calculate PCA for each point with its 20 neighbors. For example, the first point in matrix A, it would be
pca(A(idN(1,2:end),:))
And I want to calculate this for all the points. I can use a loop to do this but it will be very slow when the number of points is high. Is there a way I can calculate pca without using loop or at least a way to make this process faster?
Loop part of the code
idN = knnsearch(A,A,'k',21);
result = zeros(N,12);
for i = 1:N
[coef,~,latent] = pca(A(idN(i,2:end),:));
result(i,1:9) = coef(:)';
result(i,10:12) = latent';
end

Reducing dimensionality of features with PCA in MATLAB

I'm totally confused regarding PCA. I have a 4D image of size 90x60x12x350. That means that each voxel is a vector of size 350 (time series).
Now I divide the 3D image (90x60x12) into cubes. So let's say a cube contains n voxels, so I have n vectors of size 350. I want to reduce this n vectors to only one vector and then calculate the correlations between all vectors of all cubes.
So for a cube I can construct the matrix M where I just put each voxel after each other, i.e. M = [v1 v2 v3 ... vn] and each v is of size 350.
Now I can apply PCA in Matlab by using [coeff, score, latent, ~, explained] = pca(M); and taking the first component. And now my confusion begins.
Should I transpose the matrix M, i.e. PCA(M')?
Should I take the first column of coeff or of score?
This third question is now a bit unrelated. Let's assume we have a
matrix A = rand(30,100) where the rows are the datapoints and the
columns are the features. Now I want to reduce the dimensionality of
the feature vectors but keeping all data points.
How can I do this with PCA?
When I do [coeff, score, latent, ~, explained] = pca(M); then
coeff is of dimension 100x29 and score is of size 30x29. I'm
totally confused.
Yes, according to the pca help, "Rows of X correspond to observations and columns to variables."
score just tells you the representation of M in the principal component space. You want the first column of coeff.
numberOfDimensions = 5;
coeff = pca(A);
reducedDimension = coeff(:,1:numberOfDimensions);
reducedData = A * reducedDimension;
I disagree with the answer above.
[coeff,score]=pca(A)
where A has rows as observations and column as features.
If A has 3 featuers and >3 observations (Let's say 100) and you want the "feature" of 2 dimensions, say matrix B (the size of B is 100X2). What you should do is:
B = score(:,1:2);

plot two matrices both of (4*36 double) size in mat lab

I would like to plot two matrices both of (4*36 double) size. The first contains rho and the second contains depths for the 36 locations
well I looked into surf but it reads two arrays and one matrix rather than two matrices and yes I would like to plot them as column graph
here is an example
rho= magic(36);
rho(5:1:end,:)=[];
D= magic(36);
D(5:1:end,:)=[];
D=sort(depth);
So right now the matrix rho contains the densities for the 36 location at four different depths. The matrix D contains the four different depths at which the reading at rho is found. The first element in the first matrix corresponds to the first element in the second matrix and so on
in the end what I would like to have is the 36 column with the different reading from (rho) plotted against appropriate depth in (D)
I hope I helped make it clearer somehow
Simple example of plotting four sets of X and Y data:
X = repmat(1:36, [4 1]);
Y(1,:) = rand(1,36);
Y(2,:) = 0.2 * (1:36);
Y(3,:) = 5 * sin(linspace(-pi,pi,36));
Y(4,:) = 0.1 * (1:36).^2;
figure
plot(X', Y')
This results in
Note - in order to get four series to plot like this, the data has to be in COLUMNS. The original data was in 4x36 matrix, so it was in ROWS. I used the transpose operator (apostrophe - X' rather than just X) to get the data organized in columns.
Maybe this helps...