Placing gaussian function at different points on mesh - matlab

I am looking to create a random distribution of gaussian curve shapes on a large mesh. I basically want to take this function :
Z = 0.3*exp(-5*(x.^2+y.^2))-0.1;
Z(Z<0)=0;
and be able to choose its location (in x & y coords), and have multiple plots.
So at the moment, I have this:
But I would like to have this generated:
Is there a reasonably simple way to do this? I have tried to play around with the code but I am afraid I'm not a mathematics, nor a MATLAB expert.
Any help would be much appreciated.

Look at this!
the way this works:
Generate random point
Check if point is closer than sigma
If its not, then create a gaussian there!
repeat until Ngaussians reached
code:
clear
n_gaussians=15;
gaussians=0;
sigma=1; % std
mindist=sigma; % if distance is smaller than this gaussians "collide"
[x,y]= meshgrid(-5:0.1:5,-5:0.1:5);
used=[];
Z=zeros(size(x));
while gaussians<n_gaussians
xm=(rand(1)-0.5)*10;
ym=(rand(1)-0.5)*10;
notvalid=0;
for ii=1:size(used,2)
% if we are too close to any point.
if norm([xm-used(1,ii),ym-used(2,ii)])<mindist
notvalid=1; % do not add this gauusian
end
end
if notvalid
continue
end
used(:,end+1)=[xm;ym];
Zaux = 0.3/sigma*exp(-5*((x-xm).^2+(y-ym).^2)/sigma.^2)-0.1;
Zaux(Zaux<0)=0;
Z=Z+Zaux;
gaussians=gaussians+1;
end
surf(x,y,Z);
axis equal

Related

Find volume of 3d peaks in matlab

right now I have a 3d scatter plot with peaks that I need to find the volumes for. My data is from an image, so the x- and y- values indicate the pixel positions on the xy-plane, and the z value is the pixel value for each pixel.
Here's my scatter plot:
scatter3(x,y,z,20,z,'filled')
I am trying to find the "volume" of the peaks of the data, like drawn below:
I've tried findpeaks() but it gives me many local maxima without the the two prominent peaks that I'm looking for. In addition, I'm really stuck on how to establish the "base" of my peaks, because my data is from a scatter plot. I've also tried the convex hull and a linear surface fit, and get this:
But I'm still stuck on how to use any of these commands to establish an automated peak "base" and volume. Please let me know if you have any ideas or code segments to help me out, because I am stumped and I can't find anything on Stack Overflow. Sorry in advance if this is really unclear! Thank you so much!
Here is a suggestion for dealing with this problem:
Define a threshold for z height, or define in any other way which points from the scatter are relevant (the black plane in the leftmost figure below).
Within the resulted points, find clusters on the X-Y plane, to define the different regions to calculate. You will have to define manually how many clusters you want.
for each cluster, perform a Delaunay triangulation to estimate its volume.
Here is an example code for all that:
[x,y,z] = peaks(30); % some data
subplot 131
scatter3(x(:),y(:),z(:),[],z(:),'filled')
title('The original data')
th = 2.5; % set a threshold for z values
hold on
surf([-3 -3 3 3],[-4 4 -4 4],ones(4)*th,'FaceColor','k',...
'FaceAlpha',0.5)
hold off
ind = z>th; % get an index of all values of interest
X = x(ind);
Y = y(ind);
Z = z(ind);
clustNum = 3; % the number of clusters should be define manually
T = clusterdata([X Y],clustNum);
subplot 132
gscatter(X,Y,T)
title('A look from above')
subplot 133
hold on
c = ['rgb'];
for k = 1:max(T)
valid = T==k;
% claculate a triangulation of the data:
DT = delaunayTriangulation([X(valid) Y(valid) Z(valid)]);
[K,v] = convexHull(DT); % get the convex hull indices
% plot the volume:
ts = trisurf(K,DT.Points(:,1),DT.Points(:,2),DT.Points(:,3),...
'FaceColor',c(k));
text(mean(X(valid)),mean(Y(valid)),max(Z(valid))*1.3,...
num2str(v),'FontSize',12)
end
hold off
view([-45 40])
title('The volumes')
Note: this code uses different functions from several toolboxes. In any case that something does not work, first make sure that you have the relevant toolbox, there are alternatives to most of them.
Having already a mesh, maybe you could use the process described in https://se.mathworks.com/matlabcentral/answers/277512-how-to-find-peaks-in-3d-mesh .
If not, making a linear regression on (x,z) or (y,z) plane could make a base for you to find the peaks.
Out of experience in data with plenty of noise, selecting the peaks manually is often faster if you have small set of data to make the analysis. Just plot every peak with its number from findpeaks() and select the ones that are relevant to you. An interpolation to a smoother data can help to solve the problem in the long term (but creates a problem by itself).
Other option will be searching for peaks in the (x,z) and (y,z) planes, then having the amplitude of each peak in an (x) [or (y)] interval and from there make a integration for every area.

Q on plotting function against t and trajectory in phase space(matlab)

I am very beginner for matlab and try to solve this question. But so far it is not successful. I have spent quite a time and I think I need some help. I would appreciate any help!!!
I need to plot v against time and trajectory of v and w in phase space. The whole question is below and my code for previous question connected to this question is also below. I can go with subplot(2,1,1) for the first graph and subplot(2,1,2) for the next graph. But I am not sure what I have to do other than this. I kind of found ode45 command. But not sure how to use it and if it is the right one to use here. I have tried to use ode45. But it shows many errors that I don't understand.....Please help me on this. Thanks a lot!
'Create a figure which contains two graphs, using subplot. In the first graph, plot the temporal evolution of the membrane potential v(t) against time t. In the second graph, plot the corresponding trajectory (v(t); w (t)) in (the so-called) phase space.'
% my code is below.
a=0.08;
b=3.6;
c=0.7;
T=2; % this can be any number
I_ext=20; % this can be any number
dt=0.01; % this can be any number
function [ v,w ] = fhnn( a,b,c,I_ext,T,dt)
v=zeros(1,numel(T/dt));
w=zeros(1,numel(T/dt));
for n=1:numel(T/dt)
v(n+1)=(v(n)-v(n)^3/3-w(n)+I_ext)*dt+v(n);
w(n+1)=a*(v(n)-b*w(n)+c)*dt+w(n);
end
I gather you have a differential equation and are trying to directly plot that. You might find a better approach would be to actually solve the equation if that is possible.
Either way, recognising that:
numel returns the length of an array and dT/dt is always a scalar so the length is always one.
fhnn is not used here.
You still need a vector t.
If what is in your for loop is correct, the following should work:
a=0.08; b=3.6; c=0.7; T=2; I_ext=20; dt=0.01;
t = 0:dt:T;
v = zeros(1,round(T/dt));
w = zeros(1,round(T/dt));
for n=1:round(T/dt)-1
v(n+1)=(v(n)-v(n)^3/3-w(n)+I_ext)*dt+v(n);
w(n+1)=a*(v(n)-b*w(n)+c)*dt+w(n);
end
subplot(2,1,1)
plot(t,v)
xlabel('t')
ylabel('v')
subplot(2,1,2)
plot(v,w)
xlabel('v')
ylabel('w')

For loop in matlab plot

Hello i am having some problems understading basic plotting in matlab.
I can understand why you would use a for loop when plotting data?
Can anybody explain this to me?
I am making a simple linear plot. Is there any reason this should be inside a loop
If you are making a simple plot there is virtually no reason to use a loop.
If you check doc plot you will find that plot can take some vectors as input, or even matrices for more interesting situations.
Example:
x=0:0.01:1;
y=sin(x);
plot(x,y)
No there is no need in Matlab to use a for loop for plotting. If you are looking for a simple linear plot your code could look like this:
x=1:100;
y=3*x+4;
plot(x,y)
As you see there is no for loop needed. Same goes for nearly all plots and visualization.
A possible reason to use a for loop to plot thing may be having several data to plot in a single matrix. Say you have two matrix Ax (MxN) and Ay (MxN) where N the length of each data and M is the amount of different data wanted to plot. For example like in this case N is 201 and M is 3:
% Create Ax and Ay
Ax=meshgrid(0:0.1:20,1:3);
Ay=zeros(size(Ax));
% Sinusoidals with different frequencies
for k=1:3
Ay(k,:)=sin(k.*Ax(k,:));
end
% create colours
colorVec = hsv(3);
% Plot
hold on
for k=1:3
plot(Ax(k,:),Ay(k,:),'Color',colorVec(k,:))
end
hold off
You get:

MATLAB program about sine and cosine functions

So I plot sine(w*time) vs cosine(w*time)
w being angular frequency.
Hope I'm not wasting anyone's time if I ask:
Would this look like a circle?
I've researched a whole bunch but most websites only graph sine and cosine side-by-side and show comparisons.
I got it to look like a circle and I was just wondering if this is correct.
Also, What can I call this plot? I just gave it a title "plot of a circle". But I am wondering if that is professional enough since I am doing it for class.
Thanks for your time and answers. Greatly appreciated.
My MATLAB code for anyone interested:
clear all; clc; % clear the Workspace and the Command Window
f = 2; w = 2*pi*f; % specify a frequency in Hz and convert to rad/sec
T = 0.01; % specify a time increment
time = 0 : T : 0.5; % specify a vector of time points
x = sin(w*time); % evaluate the sine function for each element of the vector time
y = cos(w*time);
plot(x,y)
axis equal
grid on
xlabel('sin(w*time)');ylabel('cos(w*time)');title('Plot of a Circle');
axis([-1.1 1.1 -1.1 1.1]);
print
Here is a link to a Wolfram Alpha query I just did:
http://www.wolframalpha.com/input/?i=x%3Dsin%28t%29%2C+y%3Dcos%28t%29
I am not sure if it what you want to see, but that site (WolframAlpha.com) is a great place to explore and challenge mathematical concepts that are new to you.
Also, I would call it a plot of a circle since that is what the output looks like.
You are making a Lissajous curve. Keep in mind that a cosine is just a sine offset by pi/2 radians, and so plotting a sine against a cosine will indeed result in a circle. Changing the frequency and/or relative phase between x(t) and y(t) will result in many different interesting patterns.

How to create 3D joint density plot MATLAB?

I 'm having a problem with creating a joint density function from data. What I have is queue sizes from a stock as two vectors saved as:
X = [askQueueSize bidQueueSize];
I then use the hist3-function to create a 3D histogram. This is what I get:
http://dl.dropbox.com/u/709705/hist-plot.png
What I want is to have the Z-axis normalized so that it goes from [0 1].
How do I do that? Or do someone have a great joint density matlab function on stock?
This is similar (How to draw probability density function in MatLab?) but in 2D.
What I want is 3D with x:ask queue, y:bid queue, z:probability.
Would greatly appreciate if someone could help me with this, because I've hit a wall over here.
I couldn't see a simple way of doing this. You can get the histogram counts back from hist3 using
[N C] = hist3(X);
and the idea would be to normalise them with:
N = N / sum(N(:));
but I can't find a nice way to plot them back to a histogram afterwards (You can use bar3(N), but I think the axes labels will need to be set manually).
The solution I ended up with involves modifying the code of hist3. If you have access to this (edit hist3) then this may work for you, but I'm not really sure what the legal situation is (you need a licence for the statistics toolbox, if you copy hist3 and modify it yourself, this is probably not legal).
Anyway, I found the place where the data is being prepared for a surf plot. There are 3 matrices corresponding to x, y, and z. Just before the contents of the z matrix were calculated (line 256), I inserted:
n = n / sum(n(:));
which normalises the count matrix.
Finally once the histogram is plotted, you can set the axis limits with:
xlim([0, 1]);
if necessary.
With help from a guy at mathworks forum, this is the great solution I ended up with:
(data_x and data_y are values, which you want to calculate at hist3)
x = min_x:step:max_x; % axis x, which you want to see
y = min_y:step:max_y; % axis y, which you want to see
[X,Y] = meshgrid(x,y); *%important for "surf" - makes defined grid*
pdf = hist3([data_x , data_y],{x y}); %standard hist3 (calculated for yours axis)
pdf_normalize = (pdf'./length(data_x)); %normalization means devide it by length of
%data_x (or data_y)
figure()
surf(X,Y,pdf_normalize) % plot distribution
This gave me the joint density plot in 3D. Which can be checked by calculating the integral over the surface with:
integralOverDensityPlot = sum(trapz(pdf_normalize));
When the variable step goes to zero the variable integralOverDensityPlot goes to 1.0
Hope this help someone!
There is a fast way how to do this with hist3 function:
[bins centers] = hist3(X); % X should be matrix with two columns
c_1 = centers{1};
c_2 = centers{2};
pdf = bins / (sum(sum(bins))*(c_1(2)-c_1(1)) * (c_2(2)-c_2(1)));
If you "integrate" this you will get 1.
sum(sum(pdf * (c_1(2)-c_1(1)) * (c_2(2)-c_2(1))))