How to use ndgrid with interp2 - matlab

Matlab infamously has two functions for creating gridded data, ndgrid and meshgrid. meshgrid is very annoying because it mixes up rows and columns whereas ndgrid keeps it consistent. So I like to stick with ndgrid.
But it turns out, in order to interpolate using interp2, I need meshgrid style gridded data. But the rest of my code cannot handle if I used meshgrid, I want to stick to ndgrid. How do I make ndgrid work with interp2, and what is the method to this madness? I am sick of randomly transposing matrices until the code works.
[X, Y]=ndgrid(0:0.1:1,0:0.1:2);
F=cos(X).*sin(Y);
[X2, Y2]=ndgrid(0:0.05:1,0:0.05:2);
F2=interp2(X,Y,F,X2,Y2);
I know there is a way to get this to work by transposing bunch of stuff, what is the right way to do this? It is so immensely confusing when ndgrid and meshgrid are flipping rows and columns around, there has to be a "right way" to navigate this. Over the course of past six years, I have been brought to tears by the frustration caused by ndgrid and meshgrid flipping around rows and columns.

Try griddedIntepolant, which makes ndgrid-like assumptions. For your example:
[X, Y]=ndgrid(0:0.1:1,0:0.1:2);
Z=cos(X).*sin(Y);
F=griddedInterpolant(X, Y, Z);
[X2, Y2]=ndgrid(0:0.05:1,0:0.05:2);
Z2=F(X2,Y2);
If you need to use interp2 for 2-D cases like your example, then it suffices to know that [X, Y]=ndgrid(x,y) is equivalent to [Y, X]=meshgrid(y,x). So for your example, you could do:
[X, Y]=ndgrid(0:0.1:1,0:0.1:2);
F=cos(X).*sin(Y);
[X2, Y2]=ndgrid(0:0.05:1,0:0.05:2);
F2=interp2(Y,X,F,Y2,X2);
Lastly, this is supposedly the general method to covert from meshgrid to ndgrid in 3-D.

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.

i have 100*100 matrix, how can i make plot3 graph?

I have a 100 x 100 matrix and i have to use plot3 in MATLAB environment to graph this data. I tried plot3(matrix name) but I faced this error "not enough input arguments". I think plot3 needs 3 input arguments, but I only have this matrix of data. could anyone help me to solve this problem? Is there any alternative for plot3 when we don't have enough arguments?
I need a graph like this:
I think you want to plot the values in a figure as a sort of surface element. What you can do then is:
[X,Y] = size(matrix);
figure;
surface(1:X,1:Y,matrix);
What this does is that it creates a vector for both X and Y indices, as possible in surface. The X and Y indices are obtained by setting them as integers from 1:size, so basically you assign the location of each matrix element to an index.
Note that you can strictly speaking use surface(matrix) as well, but the former approach allows you to use custom indexing, as long as the lengths of the vectors X and Y are the same as the size of your matrix.
For the waterfall use:
figure;
waterfall(matrix);
Sample code:
A=rand(100);
figure;
waterfall(1:100,1:100,A);
Gives:
where you can play around with the name-value pairs, see the documentation on that.
I think what you need is mesh or surf instead of plot3.
plot3 draws a line in 3d-space, so it will need three vectors of the same length (one for each dimension).
When you have a matrix, one reasonable way of displaying it is as a surface in 3d space, which is done by the functions mesh and surf.
Try it out! I hope i helps!

Creating a 3D function in Matlab using meshgrid

This should be a really simple question, but for some reason I'm getting unreasonably confused and the Matlab documentation isn't helping.
Given a uniform grid of coordinates (x_i,y_j,z_k), I want to make a 3-dimensional array F in Matlab such that F(i,j,k)=f(x_i,y_j,z_k). The following is obviously incorrect:
x=linspace(-1,1,100) % uniform mesh on [-1,1]^3
[X,Y,Z]=meshgrid(x);
f=X.*Y.*sin(pi*Y.*Z) % for example
Do I need to use permute somewhere? I know that I could simply make a triple loop, but as we know that is slow.
Thanks!
Use ndgrid instead of meshgrid to avoid the unwanted permutation between first and second dimensions.
From the documentation (see also here):
MESHGRID is like NDGRID except that the order of the first two input
and output arguments are switched (i.e., [X,Y,Z] = MESHGRID(x,y,z)
produces the same result as [Y,X,Z] = NDGRID(y,x,z))

meshgrid visualization for irregularly spaced data

I want to visualize vector G, measured at locations from vector X and Y, spaced irregularly. The meshgrid, surf, countour etc. functions all want a regular meshgrid and much more points from G than I have. How can I do this? plot3 is not a good solution.
For irregularly spaced samples, you want scattered data interpolation. See my previous answer on TriScatteredInterp. By the way, there is a new object oriented interface called scatteredInterpolant, but the idea is the same.

Gridding non-uniformly sampled data to a uniformly spaced Cartesian grid via convolution

I am trying to re-grid non-uniform data onto a uniform grid defined in a 4-D space. The data measurement is given by a function d = f(xp,yp,zp,wp), where xp, yp, zp, and wp are the 4-D coordinates. I would like to re-grid the non-uniformaly spaced xp, yp, zp, and wp onto a uniformly spaced grid of x, y , z, and w.
For ease of conversation, let's define the gridding kernel to be the product of separable Hanning kernels:
1/a(1+cos(2*pi*x/a))
1/b(1+cos(2*pi*y/b))
1/c(1+cos(2*pi*z/c))
1/d(1+cos(2*pi*w/d))
Then, I believe to re-grid what I need to do is perform a 4-D convolution and resample onto the uniform grid. However, I'm not sure how to implement this using discrete data. My questions are as follows:
1) How should I sample each of the gridding kernels? For example, should I use the non-uniform xp, yp, zp, and wp values when calculating my discrete convolution values? Or should I use the uniformly spaced values, x, y, z, and w? Or are neither of those ideas correct?
2) How can I then implement the 4-D convolutions? I think I may need to use four for loops but am not exactly sure how to organize my data, i.e., a 4-D data structure or simply a matrix with 4 columns?
I'm not interested in the fastest approach but more so in finding the most intuitive or straight forward approach.
I believe I understand the basics of sinc interpolation and gridding algorithms. I have read multiple papers including such classics by J.D. O'Sullivan and J.I. Jackson, discussing the properties and differences in different gridding kernels. I've also read some papers from MRI reconstruction that use gridding but most of these methods assume a 2-D grid.
I am at a loss of how to actually implement the method, preferably in Matlab, or else C++, in a discrete manner and even more confused how to implement such a thing in four dimensions.
I've looked at several threads and my problem is somewhat similar to these, however I want to use convolution with a general kernel, not linear interpolation, and neither of these really suggest how to organize the 4-D data or perform the convolution:
Python 4D linear interpolation on a rectangular grid
Python 4D linear interpolation on a rectangular grid
Thanks for any advice, insight, or suggestions!
Can you use the interpn function?
[X Y Z W]=ndgrid(x,y,z,w); % unequally spaced
[XR YR ZR WR]=ndgrid(x_regular,y_regular,z_regular,w_regular); % equally spaced
volume=interpn(X,Y,Z,W,d,XR,YR,ZR,WR);
The documentation for interpn and ndgrid give more details; their usage would give you a framework for how to construct d.
EDIT: Oh sorry sorry, I saw your comment about not wanting to use interpolation after posting this.
Well, you could use interpolation as above to position your values onto the grid linearly, and then use
volume=convn(volume,general_kernel);
To convolve the values with your kernel?