I'm new to Particle swarm optimization.
I have a surf plot of a 2D image as shown below:
And is it possible to fire up the particles randomly and make them find the maxima (global)?
If yes, Can anyone please provide an algorithm or a sample code.
Thank you.
EDIT:
Did some coding and got the answer, for a small number of iterations like 10-15 the particles swarm at the maxima but if the iterations are made more than 15 like 50 etc, the particles move away from the maxima.
Can someone give a solution for it, I've included the matlab code and a sample image:
img = imread('gray_scale_img.jpg');
%img is grayscale
a=10; b=0.2; %a is convergence and b is convergence rate
% range=[xmin xmax ymin ymax zmin zmax];
range=[0 440 0 228 0 255]; %<<<---size of the image
Num_iterations = 15;%<<<----problem exists if more iterations
n = 30; % number of particles
best=zeros(Num_iterations,3);
% ----- Start Particle Swarm Optimization -----------
% generating the initial locations of n particles
xrange=range(2)-range(1);
yrange=range(4)-range(3);
zrange=range(6)-range(5);
xn=(rand(1,n)*xrange+range(1));
yn=(rand(1,n)*yrange+range(3));
% Start iterations
for k=1:Num_iterations,
% Show the contour of the function
surfc(double(img)); hold on;
% Find the current best location (xo,yo)
for d = 1:n
xn = ceil(xn);
yn = ceil(yn);
zn(d)=img(yn(d),xn(d));
end
zn_min=max(max(zn));
xo=max(max(xn(zn==zn_min)));
yo=max(max(yn(zn==zn_min)));
zo=max(max(zn(zn==zn_min)));
% Trace the paths of all roaming particles
% Display these roaming particles
plot3(xn,yn,zn,'.',xo,yo,zo,'rp'); axis(range);
% Move all the particles to new locations
nn=size(yn,2); %a=alpha, b=beta
xn=xn.*(1-b)+xo.*b+a.*(rand(1,nn)-0.5);
yn=yn.*(1-b)+yo.*b+a.*(rand(1,nn)-0.5);
%zn=zn.*(1-b)+zo.*b+a.*(rand(1,nn)-0.5);
%To make sure the particles are well within the range
nn=length(yn);
for l=1:nn,
if xn(l)<=range(1), xn(l)=range(1); end
if xn(l)>=range(2), xn(l)=range(2); end
if yn(l)<=range(3), yn(l)=range(3); end
if yn(l)>=range(4), yn(l)=range(4); end
%if zn(l)<=range(5), yn(l)=range(5); end
%if zn(l)>=range(6), yn(l)=range(6); end
end
drawnow;
hold off;
best(k,1)=xo; best(k,2)=yo; best(k,3)=zo;pause(0.2);
end %%%%% end of iterations
x_best = best(k,1);
y_best = best(k,2);
z_best = best(k,3);
global_maxima_coordinate =[x_best,y_best]
figure(3);
imshow(A,[]);
hold on
plot(x_best, y_best, 'bx')
% Draw circle of required radius around the global maxima
theta = 0:pi/50:2*pi;
radius_1 = 15;
xunit_circle_1 = radius_1 * cos(theta) + x_best;
yunit_circle_1 = radius_1 * sin(theta) + y_best;
h_1 = plot(xunit_circle_1, yunit_circle_1,'r');
hold off
title('Global maxima');
Did some coding and got the answer, for a small number of iterations like 10-15 the particles swarm at the maxima but if the iterations are made more than 15 like 50 etc, the particles move away from the maxima.
Can someone give a solution for it, I've included the matlab code and a sample image:
img = imread('gray_scale_img.jpg');
%img is grayscale
a=10; b=0.2; %a is convergence and b is convergence rate
% range=[xmin xmax ymin ymax zmin zmax];
range=[0 440 0 228 0 255]; %<<<---size of the image
Num_iterations = 15;%<<<----problem exists if more iterations
n = 30; % number of particles
best=zeros(Num_iterations,3);
% ----- Start Particle Swarm Optimization -----------
% generating the initial locations of n particles
xrange=range(2)-range(1);
yrange=range(4)-range(3);
zrange=range(6)-range(5);
xn=(rand(1,n)*xrange+range(1));
yn=(rand(1,n)*yrange+range(3));
% Start iterations
for k=1:Num_iterations,
% Show the contour of the function
surfc(double(img)); hold on;
% Find the current best location (xo,yo)
for d = 1:n
xn = ceil(xn);
yn = ceil(yn);
zn(d)=img(yn(d),xn(d));
end
zn_min=max(max(zn));
xo=max(max(xn(zn==zn_min)));
yo=max(max(yn(zn==zn_min)));
zo=max(max(zn(zn==zn_min)));
% Trace the paths of all roaming particles
% Display these roaming particles
plot3(xn,yn,zn,'.',xo,yo,zo,'rp'); axis(range);
% Move all the particles to new locations
nn=size(yn,2); %a=alpha, b=beta
xn=xn.*(1-b)+xo.*b+a.*(rand(1,nn)-0.5);
yn=yn.*(1-b)+yo.*b+a.*(rand(1,nn)-0.5);
%zn=zn.*(1-b)+zo.*b+a.*(rand(1,nn)-0.5);
%To make sure the particles are well within the range
nn=length(yn);
for l=1:nn,
if xn(l)<=range(1), xn(l)=range(1); end
if xn(l)>=range(2), xn(l)=range(2); end
if yn(l)<=range(3), yn(l)=range(3); end
if yn(l)>=range(4), yn(l)=range(4); end
%if zn(l)<=range(5), yn(l)=range(5); end
%if zn(l)>=range(6), yn(l)=range(6); end
end
drawnow;
hold off;
best(k,1)=xo; best(k,2)=yo; best(k,3)=zo;pause(0.2);
end %%%%% end of iterations
x_best = best(k,1);
y_best = best(k,2);
z_best = best(k,3);
global_maxima_coordinate =[x_best,y_best]
figure(3);
imshow(A,[]);
hold on
plot(x_best, y_best, 'bx')
% Draw circle of required radius around the global maxima
theta = 0:pi/50:2*pi;
radius_1 = 15;
xunit_circle_1 = radius_1 * cos(theta) + x_best;
yunit_circle_1 = radius_1 * sin(theta) + y_best;
h_1 = plot(xunit_circle_1, yunit_circle_1,'r');
hold off
title('Global maxima');
And here is a sample image:
Related
I have implemented the Hermite-Gaussian function in matlab for producing different modes. The light beam along z direction can be seen as a complex matrix in the plane.
The function for HG modes is as below.
%Hermite polynomial
function hk = HermitePoly(n)
if n==0
hk = 1;
elseif n==1
hk = [2 0];
else
hkm2 = zeros(1,n+1);
hkm2(n+1) = 1;
hkm1 = zeros(1,n+1);
hkm1(n) = 2;
for k=2:n
hk = zeros(1,n+1);
for e=n-k+1:2:n
hk(e) = 2*(hkm1(e+1) - (k-1)*hkm2(e));
end
hk(n+1) = -2*(k-1)*hkm2(n+1);
if k<n
hkm2 = hkm1;
hkm1 = hk;
end
end
end
% this is the function of HG modes in z position.
function [HGBeam,X,Y] = Hermite_Gaussian(N,hx,hy,w0,delta,lamda,z)
[X Y]=meshgrid((-N/2:N/2-1)*delta);
[theta,rad] = cart2pol(X,Y);
k=2*pi/lamda;
zr=pi*w0^2/lamda;
wz=w0*sqrt(1+(z/zr)^2);
qz=z+1i*zr;
q0=1i*zr;
if z==0
rz=Inf;
else
rz=z*(1+(zr/z)^2);
end
AmpLGB=sqrt(2/(2^(hx+hy)*pi*factorial(hx)*factorial(hy)*w0^2)).*(q0/qz).*(-conj(qz)/qz)^((hx+hy)/2).*exp(-(rad.*rad)/(wz)^2).*polyval(HermitePoly(hx),sqrt(2)*X/wz).*polyval(HermitePoly(hy),sqrt(2)*Y/wz);
PsLGB=exp(-1i*(k*(rad.*rad)/(2*rz)+k*z-(hx+hy+1)*atan(z/zr)));
HGBeam=AmpLGB.*PsLGB;
end
Now I plot one example for HG(2,0) as the following (example1):
clc
clear all;
close all;
lambda=809e-9; % optical wavelength
w0=0.025; %optical beam waist 15mm
k=2*pi/lambda; % optical wavenumber
Zr=pi*w0^2/lambda; % Rayleigh range
z0=0; % start position z=0; but careful 0*Inf is undefined, here 0*Inf=NAN
N=1024; % samples/side length at source plane
D1=0.25; % side length [m] at source plane
delta1=D1/N; % grid spacing [m]
x1=-D1/2:delta1:D1/2-delta1; % source plane x and y coordinates
y1=x1;
%% HG modes
HGx=2;
HGy=0;
HGintheory=Hermite_Gaussian(N,HGx,HGy,w0,delta1,lambda,z0);
h7=figure(7);
imagesc(x1,y1,abs(HGintheory).^2);
title(sprintf('z=%d; HG(%d,%d)',z0,HGx,HGy))
xlabel('x (m)'); ylabel('y (m)');
The plot of the light field will be as the following picture in the left side (its intensity):
We can use rot90() function to rotate matrix HGintheory (which is add one line code: HGintheory=rot90(HGintheory);) and then the field will rotate 90 degree (right side of the intensity plot).
Because I want to work with the light field. So the question is how can I rotate the complex matrix HGintheory in
arbitrary angle? For example 45 degree?
Does anyone knows how to rotate a complex matrix with big size? If something is wrong or unclear, please pointing out and Thank you in advance!
You can decompose your complex field into two real fields (amplitude and phase), rotate both with imrotate, and combine them afterwards pixel-wise
Hamp=abs(HGintheory);
Hphase=angle(HGintheory);
RotAngle=45;
HampRot=imrotate(Hamp,RotAngle,'bilinear','crop');
HphaseRot=imrotate(Hphase,RotAngle,'bilinear','crop');
HfullRot=HampRot.*exp(1i*HphaseRot);
figure(1);
imagesc(x1,y1,abs(HGintheory).^2);
figure(2);
imagesc(x1,y1,abs(HfullRot).^2);
You can rotate your initial meshgrid using:
[X,Y] = meshgrid(x1,y1)
xyc = [mean(x1), mean(y1)];
angel = 45;
R = [cosd(angel), -sind(angel); sind(angel), cosd(angel)];
XY = xyc' + R * ([X(:) Y(:)]-xyc)';
XR = reshape(XY(1,:),size(X));
YR = reshape(XY(2,:),size(Y));
and then use those transformed coordinates to plot:
imagesc(XR,YR,IntensityHGin);
I wrote a code to create a movie of moving points. I used scatter to make points colored( color of points depends to the density of points of the area). x and y are position of points and I have put below code in a for loop for passing time:
figure(h1); % set figure 1 as current figure
cla
dens = zeros(size(x));
% Tolerence is distance betweeen points (squared)
tol = 1;
for ii = 1:numel(x)
% Loop through all points, count neighbours within tolerence
dens(ii) = sum((x - x(ii)).^2 + (y - y(ii)).^2 < tol);
end
% Normalise density onto range 0-1
dens = (dens/max(dens));
hold on
scatter(x,y, [], dens,'filled','d')
drawnow
currFrame = getframe;
writeVideo(vidObj,currFrame);
When I run the code, the movie is created but all points are green. Could anyone guess what is the reason and how to solve it?
Your dens calculation is dependent on the relation between the values of x and y, and the value of tol. If tol is too large, then all the points a counted as "in the region" of all other points, if it's too small, then all points are "alone". In both cases, dens has the same values for all points and scatter color them all in green.
I'm trying to plot the following equation (let's call it "Equation 1"):
This is the code I'm testing:
clear all;
xl=0; xr=1; % x domain [xl,xr]
J = 10; % J: number of division for x
dx = (xr-xl) / J; % dx: mesh size
tf = 0.1; % final simulation time
Nt = 60; % Nt: number of time steps
dt = tf/Nt/4;
x = xl : dx : xr; % generate the grid point
u_ex = zeros(J+1,Nt);
for n = 1:Nt
t = n*dt; % current time
for j=1:J+1
xj = xl + (j-1)*dx;
suma = zeros(100 , 1);
for k= 1:100
suma(k) = 4/(((2*k-1)^2) *pi*pi);
suma(k) = suma(k) * exp(-((2*k-1)^2) *pi*pi*t) * cos(2*k-1)*pi*xj;
end
m = sum(suma);
u_ex(j, n)= 0.5 - m;
end
end
tt = dt : dt : Nt*dt;
figure(1)
surf(x,tt, u_ex'); % 3-D surface plot
xlabel('x')
ylabel('t')
zlabel('u')
The problem is that all I get is a flat surface:
Equation 1 is suppossed to be the solution of the following parabolic partial differential equation with boundary values:
And after getting the numerical solution, it should look like this:
This plot gets the right values at the boundaries x = 0 and x = 1. The plot of Equation 1 doesn't have those values at the boundaries.
My complete .m code (that plots both the numerical solution and Equation 1) is:
clear all; % clear all variables in memory
xl=0; xr=1; % x domain [xl,xr]
J = 10; % J: number of division for x
dx = (xr-xl) / J; % dx: mesh size
tf = 0.1; % final simulation time
Nt = 60; % Nt: number of time steps
dt = tf/Nt/4;
mu = dt/(dx)^2;
if mu > 0.5 % make sure dt satisy stability condition
error('mu should < 0.5!')
end
% Evaluate the initial conditions
x = xl : dx : xr; % generate the grid point
% store the solution at all grid points for all time steps
u = zeros(J+1,Nt);
u_ex = zeros(J+1,Nt);
% Find the approximate solution at each time step
for n = 1:Nt
t = n*dt; % current time
% boundary condition at left side
gl = 0;
% boundary condition at right side
gr = 0;
for j=2:J
if n==1 % first time step
u(j,n) = j;
else % interior nodes
u(j,n)=u(j,n-1) + mu*(u(j+1,n-1) - 2*u(j,n-1) + u(j-1,n-1));
end
end
u(1,n) = gl; % the left-end point
u(J+1,n) = gr; % the right-end point
% calculate the analytic solution
for j=1:J+1
xj = xl + (j-1)*dx;
suma = zeros(100 , 1);
for k= 1:100
suma(k) = 4/(((2*k-1)^2) *pi*pi);
suma(k) = suma(k) * exp(-((2*k-1)^2) *pi*pi*t) * cos(2*k-1)*pi*xj;
end
m = sum(suma);
u_ex(j, n)= 0.5 - m;
end
end
% Plot the results
tt = dt : dt : Nt*dt;
figure(1)
colormap(gray); % draw gray figure
surf(x,tt, u'); % 3-D surface plot
xlabel('x')
ylabel('t')
zlabel('u')
title('Numerical solution of 1-D parabolic equation')
figure(2)
surf(x,tt, u_ex'); % 3-D surface plot
xlabel('x')
ylabel('t')
zlabel('u')
title('Analytic solution of 1-D parabolic equation')
maxerr=max(max(abs(u-u_ex))),
The code is taken from the book "Computational Partial Differential Equations Using MATLAB" by Yi-Tung Chen, Jichun Li, chapter 2, exercise 3.
In short: I'm not asking about the differential equation or the boundary problem, I want to know is: Why am I getting a flat surface when plotting Equation 1? Am I missing a parenthesis?
I do not want to use the symsum function because it never stop the script execution and I want to learn how to plot Equation 1 with no using symsum.
I've tested this code with Matlab R2008b and Octave 4.2.1. I got the same results (even with sums of 1000, 10000 and 50000 terms in the for loop with the k variable).
Edit!
Thanks, Steve!
I was missing a couple of parenthesis near the cosine, the right code is:
clear all; % clear all variables in memory
xl=0; xr=1; % x domain [xl,xr]
J = 10; % J: number of division for x
dx = (xr-xl) / J; % dx: mesh size
tf = 0.1; % final simulation time
Nt = 60; % Nt: number of time steps
dt = tf/Nt/4;
mu = dt/(dx)^2;
if mu > 0.5 % make sure dt satisy stability condition
error('mu should < 0.5!')
end
% Evaluate the initial conditions
x = xl : dx : xr; % generate the grid point
% store the solution at all grid points for all time steps
u = zeros(J+1,Nt);
u_ex = zeros(J+1,Nt);
% Find the approximate solution at each time step
for n = 1:Nt
t = n*dt; % current time
% boundary condition at left side
gl = 0;
% boundary condition at right side
gr = 0;
for j=2:J
if n==1 % first time step
u(j,n) = j;
else % interior nodes
u(j,n)=u(j,n-1) + mu*(u(j+1,n-1) - 2*u(j,n-1) + u(j-1,n-1));
end
end
u(1,n) = gl; % the left-end point
u(J+1,n) = gr; % the right-end point
% calculate the analytic solution
for j=1:J+1
xj = xl + (j-1)*dx;
suma = zeros(1000 , 1);
for k= 1:1000
suma(k) = 4/(((2*k-1)^2) *pi*pi);
suma(k) *= exp(-((2*k-1)^2) *pi*pi*t) * cos((2*k-1)*pi*xj);
end
m = sum(suma);
u_ex(j, n)= 0.5 - m;
end
end
% Plot the results
tt = dt : dt : Nt*dt;
figure(1)
colormap(gray); % draw gray figure
surf(x,tt, u'); % 3-D surface plot
xlabel('x')
ylabel('t')
zlabel('u')
title('Numerical solution of 1-D parabolic equation')
figure(2)
surf(x,tt, u_ex'); % 3-D surface plot
xlabel('x')
ylabel('t')
zlabel('u')
title('Analytic solution of 1-D parabolic equation')
Now my Equation 1 looks much better:
Also Steve was right when pointing out that my numerical solution may be wrong. I didn't notice that the boundary values are for the derivatives of my function, not the actual values of the function. I'll ask my teacher about this.
Edit2!
Ok, I got it. To calculate the derivatives at the boundaries you have to use hint 2.21 in the same book:
% hint 2.21 given by the book
% it is better to calculate the boundary values after calculating the inner points inside the for j = 1:m loop because you will need them:
u(1, n) = u(2, n) - dx * gl; % the left-end point
u(J+1,n) = u(J, n) + dx * gr; % the right-end point
Now my numerical solution looks like my analytic solution :D
Matlab R2008b can't recognize the *= operator that Octave does. I'm not tested this operator in other versions of Matlab because I'm too poor.
Yvon: I think the analytical solution formula comes from the real part of a Fourier expansion, but authors don't tell how they got it.
I want to produce a animated gif of a solution to a partial differential equation. That is the gif should show the solution at specific time.
Currently I can only make pictures in which all times are plotted.
Below is my entire program, with figure(3) being my attempt of making a gif.
clear all;
close all;
%%%%%%%%%%%%
% For slide 27 of Diffusion 1D
% The equation to be graphed in latex form is
% u(x,t)=\frac{1}{L}+\frac{2}{L}\sum^{\infty}_{n=1}cos(\frac{n\pi x_0}{L})cos(\frac{n\pi x}{L})e^{-k(\frac{n\pi}{L})^2t}
%%%%%%%%%%%%
%define constants
%note that the constants listed in the file are arbitrary
L = 2; %length of the rod
k= 0.01; % Diffusivity, which is assume to be constant but can be a function of x
x0 = 1; %location of the inital condition i.e. f(x)=delta(x-x0)
tmax= 50; %maximum amount of time the simulation runs
nmax = 200; % maximum value for n, increase to accuracy
tgrid = 21; %The number of points to be evaluated in the time domain
xgrid = 51; %The number of points to be evaluated in the space domain
%initialize variables
u=zeros(tgrid,xgrid); %preallocate array used for storing values of the solution
t=linspace(0,tmax,tgrid);%We assume that time is evenly distributed
x=linspace(0,L,xgrid); %We assume that space is evenly distributed
%Plotting variables
figure(1);
hold on;
axis([0 L -inf inf]);
xlabel('x');
ylabel('u(x,t)');
%Calculation,
for i=1:tgrid
for j=1:xgrid
seriesSum=0;
%Calculate the fourier series up to nmax for each point u(x,t)
for n= 1:nmax
seriesSum= seriesSum + cos(n*pi*x0/L)*cos(n*pi*x(j)/L)*exp(-k*t(i)*(n*pi/L)^2);
end
%Finish calcuation for solution at a specific point
u(i,j)= 1/L+(2/L)*seriesSum;
end
%After we have calculated all points at time t, we graph it for time t
plot(x,u(i,:),'linewidth',4);
end
saveas(gcf,'PDE_sol.png')%Save figure as png in current directory
%run a second loop that does not include the initial condition to get a
%better view of the long term behaviour.
%Plotting variables
figure(2);
hold on;
axis([0 L -inf inf]);
xlabel('x');
ylabel('u(x,t)');
for i=2:tgrid
plot(x,u(i,:),'linewidth',4);
end
saveas(gcf,'PDE_sol_without_inital.png')%Save figure as png in current directory
%Create a gif verison of figure 2
figure(3);
axis([0 L -inf inf]);
xlabel('x');
ylabel('u(x,t)');
filename = 'PDE_sol.gif';
for i=2:tgrid
plot(x,u(i,:),'linewidth',4);
drawnow
frame = getframe(1);
im = frame2im(frame);
[imind,cm] = rgb2ind(im,256);
if i == 2;
imwrite(imind,cm,filename,'gif', 'Loopcount',inf);
else
imwrite(imind,cm,filename,'gif','WriteMode','append');
end
end
The output gif that I get is
which is clearly not animated.
Note: If you think there is a better place to post this question please direct me to it. As my issue is with the MATLAB programming language and not the math involved I thought this would be the best place to post my question.
The first input to getframe is the handle of the figure that you'd like to take a screenshot of. As you have it written, you are grabbing figure 1 which is actually referring to the first figure that you create that you aren't updating within your loop.
You have assigned a numeric handle of 3 to the figure that you create right before your last loop so you'll want to tell getframe to use that figure instead.
Additionally, I would create one plot object and update the XData and YData rather than continuously creating new plot objects. The issue with calling plot continuously is that it's slow AND it completely resets all of your axes settings such as x and y labels as well as x and y limits.
% Store the handle to the figure in hfig
hfig = figure(3);
% Create the initial plot object
hplot = plot(NaN, NaN, 'LineWidth', 4);
axis([0 L 0 2]);
xlabel('x');
ylabel('u(x,t)');
filename = 'PDE_sol.gif';
for i=2:tgrid
% Update the plot appearance
set(hplot, 'XData', x, 'YData', u(i,:));
drawnow
% Get a screenshot of THIS figure
frame = getframe(hfig);
im = frame2im(frame);
[imind,cm] = rgb2ind(im,256);
if i == 2;
imwrite(imind,cm,filename,'gif', 'Loopcount',inf);
else
imwrite(imind,cm,filename,'gif','WriteMode','append');
end
end
I've made an experiment with directional beams and I would like to visualise it. The set-up was like this:
I've measured my values at 22, 15, 10, 5 and 0 degrees in a distance of 100, 75, 50 and 25 cm.
Now I would like to bring this Data into a 3D waterfall() diagram where the source is the highest peak and you can see that the voltage decreases in all directions.
So my first thought was to fit all distances individually and these functions I would like to put them into the waterfall(). But this doesn't work very well, because the begin and end different layers of values (have a look at the example code) after I calculate them to the x, y system was different.
So, how can I bring my data into a waterfall diagram?
clearvars
x=-1:0.1:1;
%________________________________________________________measured Values (layers)
A=[208; 256; 480; 704; 776; 752; 672; 480; 264]; % 0.25m
B=[104; 156; 304; 388; 432; 440; 340; 280; 140]; % 0.50m
C=[ 54; 104; 250; 264; 320; 270; 252; 144; 70]; % 0.75m
D=[ 32; 64; 142; 198; 228; 208; 130; 86; 46;]; % 1.00m
% plot(A)
% figure(2)
% plot(B)
% figure(3)
% plot(C)
% figure(4)
% plot(D)
%________________________________________________________to x,y System
dist1=[tand(-22)*0.25; tand(-15)*0.25; tand(-10)*0.25; tand(-5)*0.25; tand(0)*0.25; tand(5)*0.25; tand(10)*0.25; tand(15)*0.25; tand(22)*0.25;];
dist2=[tand(-22)*0.50; tand(-15)*0.50; tand(-10)*0.50; tand(-5)*0.50; tand(0)*0.50; tand(5)*0.50; tand(10)*0.50; tand(15)*0.50; tand(22)*0.50;];
dist3=[tand(-22)*0.75; tand(-15)*0.75; tand(-10)*0.75; tand(-5)*0.75; tand(0)*0.75; tand(5)*0.75; tand(10)*0.75; tand(15)*0.75; tand(22)*0.75;];
dist4=[tand(-22); tand(-15); tand(-10); tand(-5); tand(0); tand(5); tand(10); tand(15); tand(22)];
plot(dist1,A)
figure(2)
plot(dist2,B)
figure(3)
plot(dist3,C)
figure(4)
plot(dist4,D)
% func1= fit(dist1,A,'poly2')
%
% plot(dist1, func1(dist1))
Furthermore:
As a result I would like to create something like this:
http://de.mathworks.com/help/matlab/ref/waterfall.html
or maybe a surface:
http://de.mathworks.com/help/matlab/ref/surf.html
But I don't know how I can convert my current data into a format, which fits the requirements of the waterfall() or surf() function
It's all about organizing your data. As Daniel said, waterfall (or even surf for that matter) require a mesh as input (your data need to be matrices).
So let's build a proper mesh with your data:
%% // measured Values (layers)
A = [208; 256; 480; 704; 776; 752; 672; 480; 264] ; %// 0.25m
B = [104; 156; 304; 388; 432; 440; 340; 280; 140] ; %// 0.50m
C = [ 54; 104; 250; 264; 320; 270; 252; 144; 70] ; %// 0.75m
D = [ 32; 64; 142; 198; 228; 208; 130; 86; 46] ; %// 1.00m
%% // Building the mesh
%// primary parameters
x = (0.25:0.25:1).' ; %'// ignore that comment
angles = [-22 -15 -10 -5 0 5 10 15 22] ;
%// mesh matrices
X = x * ones(1,numel(angles)) ; %// distance to source
Y = x * tand(angles) ; %// lateral spread due to angle
V = [A B C D].' ; %'// measurements (voltages)
At this point, you have 3 matrices X,Y and V which are perfect input for most 3D graphing functions like surf or waterfall. So it becomes quite straightforward:
%% // Waterfall visualisation
hf = figure ;
hw = waterfall(X,Y,V) ;
If you want to add some refinements :
%% // refinements
shading interp
xlabel('Distance to source')
ylabel('Lateral spread')
zlabel('Voltage')
hold on
plot3(0,0,0,'or','MarkerSize',10,'LineWidth',4) %// show the source position
and/or even more information on the figure:
%% // displays the base rays
xrays = [0;x] ;
yrays = [zeros(1,numel(angles)) ; Y] ;
set(0,'DefaultAxesColorOrder',[0 0 0] , 'DefaultAxesLineStyleOrder','--|:' )
plot(xrays,yrays,'Marker','.')
At this stage, it yields the following figure, but you can keep it simple or adjust many other properties of all the graphic object to personalize your display:
You can also play with the surf function instead of waterfall, and use the same matrices as input.
Another way to better link the voltage recorded for every sensor position would be to use a stem plot. Unfortunately the stem function does not take 3D arrays as input, however, the ZData property still exist so we can instantiate the stem plot first then loop through them to set their ZData:
%% // STEM waterfall variant
hsf = figure ; hold on
hs = stem(X.',Y.',':ob') ;
for k=1:4
set(hs(k),'ZData',V(k,:))
end
With all the refinements above, it yields:
This variant doesn't color code the voltage but it shows exactly the position where it was recorded.
Easiest way is to mesh your data first (i.e. put them in X, Y and Z matrices):
%Z:
dist1234=[dist1 dist2 dist3 dist4];
%Y:
ABCD=[A B C D];
%X:
[n1,n2]=size(ABCD);
X=repmat(1:n2,n1,1); % or whatever your x-axis is, here it is 1, 2, 3...
% Take your pick:
figure(1)
surf(X,dist1234,ABCD);title('surf')
figure(2)
waterfall(X',dist1234',ABCD');title('waterfall')
figure(3)
mesh(X,dist1234,ABCD);title('mesh')