How to create noise for a 2D Gaussian? - matlab

I'm trying to practice curve fitting on a 2D Gaussian, but in order to do that I need to add random noise to my predefined Gaussian. My first instinct was to cycle through two for loops and create two matrices X and Y with random numbers, but when I tried that (I don't have the code anymore) Matlab wouldn't let me plot the Gaussian because I didn't generate my X and Y values using the meshgrid function. Since I seem to need to use meshgrid, can anyone help me figure out how to generate a random meshgrid so I can add some noise to my Gaussian?
amp = 1;
x0 = 0;
y0 = 0;
sigmaX = 1;
sigmaY = 1;
%X = 1:1:100;
%Y = 1:1:100;
[X,Y] = meshgrid(-3:.1:3);
%Z = X .* exp(-X.^2 - Y.^2);
Z = amp*exp(-((X-x0).^2/(2*sigmaX^2)+(Y-y0).^2/(2*sigmaY^2)));
surf(X, Y, Z);
%Add noise now
EDIT: So I found out that rand can return a random matrix which will work with the surf function (for some reason it wasn't working for me earlier though). The result looks something like this: noisy 2D gaussian
amp = 1;
x0 = 0;
y0 = 0;
sigmaX = 1;
sigmaY = 1;
[X,Y] = meshgrid(-3:.1:3);
%Z = X .* exp(-X.^2 - Y.^2);
Z = amp*exp(-((X-x0).^2/(2*sigmaX^2)+(Y-y0).^2/(2*sigmaY^2)));
surf(X, Y, Z);
%Make some noise
[xRows, xColumns] = size(X);
[yRows, yColumns] = size(Y);
figure(2)
X = -.1 + (.1+.1)*rand(61,61);
Y = -.1 + (.1+.1)*rand(61,61);
Z = amp*exp(-((X-x0).^2/(2*sigmaX^2)+(Y-y0).^2/(2*sigmaY^2)));
surf(X, Y, Z)
But I feel like the Gaussian has largely lost it's typical bell shape and looks more like a slope field than anything. I'm going to try and refine it but I would love any input.

That's what i would do.
amp=1;
x0=0;
y0=0;
sigmaX=1;
sigmaY=1;
noiseAmp=.1;
x=[-2:.1:2];
y=[-2:.1:2];
%Create two Noise Vectors
noisez1=noiseAmp.*rand(1,length(x));
noisez2=noiseAmp.*rand(1,length(x));
% Make an meshgrid out of the two Vectors
[noiseZ1,noiseZ2]=meshgrid(noisez1,noisez2);
% Add the Meshgrids togehter
Noise=noiseZ1+noiseZ2;
[X,Y]=meshgrid(x,y);
% Add the Noise to the result of Z
Z=amp*exp(-((X-x0).^2/(2*sigmaX^2)+(Y-y0).^2/(2*sigmaY^2)))+Noise;
surf(X,Y,Z);

if you just want a 2D plot you can try this
amp=1;
noiseAmp=0.01;
x0=0;
y0=0;
sigmaX=1;
sigmaY=1;
x=[-5:.01:5];
noiseY=noiseAmp*rand(1,length(x));
y=noiseY+amp*exp(-((x-x0).^2/(2*sigmaX^2)));
plot(x,y);
where noiseAmp is the Amplitude of the noise.
But if you still want to create a 3D plot with the surf() function, you have to add a random meshgrid to the Z result.

Related

Matlab meshgrid surface understanding problem

I have difficluties at understanding the Matlab documentation for the meshgrid, contour or surf functions. I simply do not understand how the matrix Z must be created to display values for x and y vectors.
Basically, I have loop that calculates x(n), y(n) and a value z(n) with n is the index. Now how do I map this into the meshgrid function to create a contour plot from this data?
for i = 1:n
x(n) = i;
y(n) = i;
z(n) = rand();
end
Now:
[X,Y] = meshgrid(x,y);
Z = ???;
contour(X,Y,Z)

Extracting Z values after 3D plot is generated by 2D curve revolution with repmat

I am stuck with an apparently simple problem. I have to revolve of 360° a 2D curve around an axis, to obtain a 3D plot. Say, I want to do it with this sine function:
z = sin(r);
theta = 0:pi/20:2*pi;
xx = bsxfun(#times,r',cos(theta));
yy = bsxfun(#times,r',sin(theta));
zz = repmat(z',1,length(theta));
surf(xx,yy,zz)
axis equal
I now want to visualize the numerical values of the Z plane, stored in a matrix. I would normally do it this way:
ch=get(gca,'children')
X=get(ch,'Xdata')
Y=get(ch,'Ydata')
Z=get(ch,'Zdata')
If I visualize Z with
imagesc(Z)
I don't obtain the actual values of Z of the plot, but the "un-revolved" projection. I suspect that this is related to the way I generate the curve, and from the fact I don't have a function of the type
zz = f(xx,yy)
Is there any way I can obtain the grid values of xx and yy, as well as the values of zz at each gridpoint?
Thank you for your help.
Instead of bsxfun you can use meshgrid:
% The two parameters needed for the parametric equation
h = linspace(0,2) ;
th = 0:pi/20:2*pi ;
[R,T] = meshgrid(h,th) ;
% The parametric equation
% f(x) Rotation along Z
% ↓ ↓
X = sin(R) .* cos(T) ;
Y = sin(R) .* sin(T) ;
% Z = h
Z = R ;
surf(X,Y,Z,'EdgeColor',"none")
xlabel('X')
ylabel('Y')
zlabel('Z')
Which produce:
And if you want to extract the contour on the X plane (X = 0) you can use contour:
contour(Y,Z,X,[0,0])
Which produce:

How to make a grid In matlab with loop

I want to make a grid (Uniform Mapping) in matlab without Meshgrid.
I have make grid with meshgrid but now I just want to make it with a loop or any Second Method (without meshgrid)
This is my code using meshgrid:
figure(6)
[X,Y] = meshgrid(-1:0.1:1, -1:0.1:1)
plot(X,Y,'k-')
hold on
plot(Y,X,'k-');
use repmat, or multiply by ones vectors for even more basic functionality:
x = -1:0.1:1;
y = -1:0.1:1;
% with repmat
X1 = repmat(x(:)',[numel(y),1]);
Y1 = repmat(y(:),[1,numel(x)]);
% multiply with ones
X2 = ones(numel(y),1)*x(:)';
Y2 = y(:)*ones(1,numel(x));
% meshgrid
[X3,Y3] = meshgrid(x, y);
isequal(X1,X2,X3) && isequal(Y1,Y2,Y3) % true
plot(X1,Y1,'k');
hold on
plot(Y1,X1,'k');

Plotting Ellipse for complex values in matlab

I am trying to plot the elliptical trajectory of a particle, but my matlab code runs and gives me warning that I m trying to plot imaginary values. How can I remove this error?
My Matlab code is as follows:
% plot of trajectory of the particle in flexural gravity wave
U =5;
t=1;
y1=0;
h=50;
k=2*pi/100;
w=pi;
X= (-80*pi:pi:80*pi);
Y= (-80*pi:pi:80*pi);
H=1;
A= (H/2)*cosh(k*(h+y1))/sinh(k*h);
B= (H/2)*sinh(k*(h+y1))/sinh(k*h);
Y = B.* ((1-((X-U*t)./A).^2).^(1/2));
plot(X,Y);
xlabel('X');
ylabel('Y');
The warning matlab shows is:
Warning: Imaginary parts of complex X and/or Y arguments ignored
Please help me out with this.
If you want to plot imaginary number only,
Please change the code, plot(X,Y); as plot(X,imag(Y)).
In case of real value, plot(X,real(Y)).
If you are interested in magnitude of complex number, plot(X,abs(Y)).
I got the answer to my question.
I can plot it by using general coordinates of the ellipse, ie, using x=acos(t) and y=asin(t). and that really worked.
% plot of trajectory of the particle in flexural gravity wave
U = 5;
t = 1;
y1 = 0;
h = 50;
k = 2*pi/100;
w = pi;
x0 = U*t;
y0 = 0;
H = 1;
A = (H/2)*cosh(k*(h+y1))/sinh(k*h);
B = (H/2)*sinh(k*(h+y1))/sinh(k*h);
z = -2*pi:0.01:2*pi;
X = x0 + A*cos(z);
Y = y0 + B*sin(z);
plot(X,Y);
xlabel('X');
ylabel('Y');

Surf function won't graph 2D Gaussian

I'm trying to graph a simple 2D Gaussian in MATLAB using the surf function, but I'm getting an error saying that the last value in surf must be a matrix and not a vector. I don't understand how to graph the function then as every other example I've found while searching has had the third value as a vector. I feel as if I'm completely off base here with the surf function. Any ideas?
amp = 10;
x0 = 0;
y0 = 0;
sigmaX = 10
sigmaY = 10
X = 1:1:100;
Y = 1:1:100;
Z = amp*exp(-(X-x0).^2/(2*sigmaX^2)+(Y-y0).^2/(2*sigmaY^2));
disp(size(Z))
surf(X, Y, Z);
Edit
When I plot this using #Suever's answer, I get something that doesn't look like a Gaussian at all.
Here's the plot
amp = 1;
x0 = 0;
y0 = 0;
sigmaX = 1;
sigmaY = 1;
%X = 1:1:100;
%Y = 1:1:100;
[X,Y] = meshgrid(-3:.1:3);
%Z = X .* exp(-X.^2 - Y.^2);
Z = amp*exp(-(X-x0).^2/(2*sigmaX^2)+(Y-y0).^2/(2*sigmaY^2));
surf(X, Y, Z);
You have used X and Y to define a 2D domain over which you would like to compute your gaussian. If you want Z to be a function of X and Y, you need to define Z for all permutations of X and Y. If you don't provide a matrix of Z values, MATLAB has no idea how to create a surface over the X Y ranges you've provided.
You can create all permutations of X and Y using meshgrid and then compute Z over this entire domain. Then you will be able to display the result with surf.
amp = 10; x0 = 50; y0 = 50; sigmaX = 10; sigmaY = 10;
[X, Y] = meshgrid(1:100, 1:100);
% Z as you had it written (see correct version below)
Z = amp*exp(-(X-x0).^2./(2*sigmaX^2)+(Y-y0).^2./(2*sigmaY^2));
surf(X, Y, Z);
Update
Your equation for the 2D Gaussian is wrong. The - sign should be outside of the addition of the two components. The way that you had it written, you negated the X-component and then added to the Y component.
Z = amp*exp(-((X-x0).^2./(2*sigmaX^2)+(Y-y0).^2./(2*sigmaY^2)));