I would like to reduce the dimension of the matrices that I obtain using meshgrid because I'm interested in a thick mesh in the center of the matrix because is where I have many variations of my variable, while a wider mesh going far from the center.
The thing that I want to underline is that I DON'T want a finite method kind of function, but just a function that works like meshgrid generating the two matrices like meshgrid but with different steps. I know that I could implement a finite element method or something else, but what I want to do is just reduce as much as possible the computations needed to generate the matrices and have a faster code.
Is it possible?
I am not sure how meshgrid isn't the fit here for this. If I understand you I simply concatenated three vectors for instance on some interval with one denser than the other and I get the following for this little function.
x1 = linspace(0,5,10);
x2 = linspace(5,10,100);
x3 = linspace(10,15,10);
x = [x1,x2,x3];
y = x;
[X,Y] = meshgrid(x,y);
R = sqrt(X.^2 + Y.^2) + eps;
Z = sin(R)./R;
mesh(X,Y,Z)
Related
I have coordinate vectors X and Y and corresponding vector of function values Z. I need to plot a surface Z(X,Y), and I need to put Z values on a regular mesh, right now X and Y define points distributed irregularly. What is the best way to do it in matlab?
Thanks!
If you have a function such as z=f(x,y) then you could use fsurf().
fsurf(#(x,y) x^2+y^2);
Or else, if you have data points then you could use surf()
[x, y]=meshgrid(-5:0.1:5);
z = x.^2 + y.^2;
mesh(x,y,z);
You could specify the axis as per your need.
The following worked for me:
Zinter = scatteredInterpolant(Xs,Ys,Z) %defines interpolant for scattered data and allows to calculate values of z for any point
I have a vector of x and y coordinates drawn from two separate unknown Gaussian distributions. I would like to fit these points to a three dimensional Gauss function and evaluate this function at any x and y.
So far the only manner I've found of doing this is using a Gaussian Mixture model with a maximum of 1 component (see code below) and going into the handle of ezcontour to take the X, Y, and Z data out.
The problems with this method is firstly that its a very ugly roundabout manner of getting this done and secondly the ezcontour command only gives me a grid of 60x60 but I need a much higher resolution.
Does anyone know a more elegant and useful method that will allow me to find the underlying Gauss function and extract its value at any x and y?
Code:
GaussDistribution = fitgmdist([varX varY],1); %Not exactly the intention of fitgmdist, but it gets the job done.
h = ezcontour(#(x,y)pdf(GaussDistributions,[x y]),[-500 -400], [-40 40]);
Gaussian Distribution in general form is like this:
I am not allowed to upload picture but the Formula of gaussian is:
1/((2*pi)^(D/2)*sqrt(det(Sigma)))*exp(-1/2*(x-Mu)*Sigma^-1*(x-Mu)');
where D is the data dimension (for you is 2);
Sigma is covariance matrix;
and Mu is mean of each data vector.
here is an example. In this example a guassian is fitted into two vectors of randomly generated samples from normal distributions with parameters N1(4,7) and N2(-2,4):
Data = [random('norm',4,7,30,1),random('norm',-2,4,30,1)];
X = -25:.2:25;
Y = -25:.2:25;
D = length(Data(1,:));
Mu = mean(Data);
Sigma = cov(Data);
P_Gaussian = zeros(length(X),length(Y));
for i=1:length(X)
for j=1:length(Y)
x = [X(i),Y(j)];
P_Gaussian(i,j) = 1/((2*pi)^(D/2)*sqrt(det(Sigma)))...
*exp(-1/2*(x-Mu)*Sigma^-1*(x-Mu)');
end
end
mesh(P_Gaussian)
run the code in matlab. For the sake of clarity I wrote the code like this it can be written more more efficient from programming point of view.
I fail to think how should I proceed for plotting x=y plane withing a 2x2x2 space.
I create a 2x2 meshgrid
[X,Y]=meshgrid(-1:0.1:1,-1:0.1:1);
then I come to define Z - I get stuck
My thoughts go like this
I need to create a 21x21 array for Z ( I use surf function.. and the dimensions of X, Y, Z must match. Right?).
I need to populate only those values of Z that follow x==y
Now for each such point i.e. x==y Z will vary -1:0.1:1 .. Does This require that I iterate again and again on the x==y and keep drawing Z with values from -1:0.1:1?
Am I going the right way about plotting this plane? Kindly help.
You simply need to define X and Z, Y is equal to X by definition:
[X Z] = meshgrid(-1:.1:1,-1:.1:1);
figure;
surf(X,X,Z);xlabel('x');ylabel('y');zlabel('z');
Results with
You are actually trying to do something two dimensional in a 3 dimensional setting.
A bit unintuitive, but that does not mean it can't be done, for example:
[X,Y]=meshgrid(-1:0.1:1,-1:0.1:1);
Z = zeros(size(X)); % Perhaps you want NaN rather than zeros
idx = X==Y;
Z(idx)=X(idx).^2+Y(idx) % Of course identical to X(idx).^2+X(idx)
surf(Z)
I'm trying to write a script so that one can put his hand on the screen, click a few points with ginput, and have matlab generate an outline of the persons hand using splines. However, I'm quite unsure how you can have splines connect points that result from your clicks, as they of course are described by some sort of parametrization. How can you use the spline command built into matlab when the points aren't supposed to be connected 'from left to right'?
The code I have so far is not much, it just makes a box and lets you click some points
FigHandle = figure('Position', [15,15, 1500, 1500]);
rectangle('Position',[0,0,40,40])
daspect([1,1,1])
[x,y] = ginput;
So I suppose my question is really what to do with x and y so that you can spline them in such a way that they are connected 'chronologically'. (And, in the end, connecting the last one to the first one)
look into function cscvn
curve = cscvn(points)
returns a parametric variational, or natural, cubic spline curve (in ppform) passing through the given sequence points(:j), j = 1:end.
An excellent example here:
http://www.mathworks.com/help/curvefit/examples/constructing-spline-curves-in-2d-and-3d.html
I've found an alternative for using the cscvn function.
Using a semi-arclength parametrisation, I can create the spline from the arrays x and y as follows:
diffx = diff(x);
diffy = diff(y);
t = zeros(1,length(x)-1);
for n = 1:length(x)-1
t(n+1) = t(n) + sqrt(diffx(n).^2+diffy(n).^2);
end
tj = linspace(t(1),t(end),300);
xj = interp1(t,x,tj,'spline');
yj = interp1(t,y,tj,'spline');
plot(x,y,'b.',xj,yj,'r-')
This creates pretty decent outlines.
What this does is use the fact that a curve in the plane can be approximated by connecting a finite number of points on the curve using line segments to create a polygonal path. Using this we can parametrize the points (x,y) in terms of t. As we only have a few points to create t from, we create more by adding linearly spaced points in between. Using the function interp1, we then find the intermediate values of x and y that correspond to these linearly spaced t, ti.
Here is an example of how to do it using linear interpolation: Interpolating trajectory from unsorted array of 2D points where order matters. This should get you to the same result as plot(x,y).
The idea in that post is to loop through each consecutive pair of points and interpolate between just those points. You might be able to adapt this to work with splines, you need to give it 4 points each time though which could cause problems since they could double back.
To connect the start and end though just do this before interpolating:
x(end+1) = x(1);
y(end+1) = y(1);
Given 3 vector-pair, X, Y and Z, how to generate the contour? I understand that we need to make use of the contour plot. But the thing is that we need to pass in a 2x2 matrix for this argument, which presumably, is a matrix of Z corresponding to each X,Y pair. But this would mean that I have to go extra miles to create such a matrix by using griddata interpolation first before talking about contour generation.
Is there any other more succinct method?
Yes. Use the Tricontour tool. It is found on the file exchange (on Matlab Central.) This does the contouring as you desire directly, without forcing you to use meshgrid and griddata.
MATLAB addresses this need of yours fairly succinctly.
What you need to do is use meshgrid to two-dimensionalize your X and Y vectors. Here is a simple example to demonstrate how to generate a contour plot of z = sin (x^2 + x*y^2):
x = -10:0.1:10;
y = -10:0.1:10;
[x,y] = meshgrid(x,y);
z = sin(x.^2+x.*y.^2);
contour(x,y,z)
Note the use of the .^ and .* notations, which forces MATLAB to conduct an element-by-element evaluation of the z matrix, making it 2D in the process.