calculating for mean square displacement - matlab

clear all; close all; clc;
figure(1)
set(gcf,'Units','normalized','Position',[0 0 1 1])
N = 100;
M = 100;
x(1,M) = 0;
y(1,M) = 0;
for n = 2:1:N
bx = randi([0,1],1,M)*2-1; % binary random number
by = randi([0,1],1,M)*2-1; % binary random number
x(n,:) = x(n-1,:) + bx;
y(n,:) = y(n-1,:) + by;
subplot(1,2,1)
plot(x(:,1),y(:,1),'k')
xlabel('x')
ylabel('y')
axis equal
set(gca,'FontSize',20)
subplot(3,2,6)
plot([0:1:n],sqrt(2*[0:1:n]),'r')
hold on
plot(sqrt(mean(x.^2+y.^2,2)),'k')
xlim([0 N])
xlabel('t')
ylabel('MSD(t)')
set(gca,'FontSize',12)
drawnow()
end
msd = mean(sqrt(2*[0;1;n]));
disp(msd);
msds = mean(sqrt(mean((x.^2+y.^2),2)));
disp(msds);
------ i have tried running and modified the codes above, and fortunately, it was very successful ... its just that the values that will be displayed on "msd" and "msds" have a very large difference .. the values of both must be closer or almost equal .. well, the command i used for calculating both has been successful for the same simulation but its in one-dimensional .. and the above code is two dimensional .. what must i do ??

You have a typo at line 39. Try:
msd = mean(sqrt(2*[0:1:n]));
instead of:
msd = mean(sqrt(2*[0;1;n]));
Then I have the same value for msd and msds.

Related

Animating 3D Random Walk Matlab

I am writing a code to simulate random walk in 3D space on Matlab. However, there seems to be a problem with my number of simulations, M. I want to animate multiple simulations on the same graph but I am only get 1 simulation. My input of M instead becomes the number of steps. How can I fix this code? Thank you.
I want it to look like the animation in this video: https://www.youtube.com/watch?v=7A83lXbs6Ik
But after each simulation is complete, another one starts on the same graph but a different color.
The end result should be like this
final
clc;
clearvars;
N = input('Enter the number of steps in a single run: '); % Length of the x-axis and random walk.
M = input('Enter the number of simulation runs to do: '); % The number of random walks.
x_t(1) = 0;
y_t(1) = 0;
z_t(1) = 0;
for m=1:M
for n = 1:N % Looping all values of N into x_t(n).
A = sign(randn); % Generates either +1/-1 depending on the SIGN of RAND.
x_t(n+1) = x_t(n) + A;
A = sign(randn); % Generates either +1/-1 depending on the SIGN of RAND.
y_t(n+1) = y_t(n) + A;
A = sign(randn);
z_t(n+1) = z_t(n) + A;
end
plot3([x_t(1) x_t(n+1)], [y_t(1) y_t(n+1)], [z_t(1) z_t(n+1)], 'g');
hold on
grid on
x_t = x_t(n+1);
y_t = y_t(n+1);
z_t = z_t(n+1);
drawnow;
end
You are plotting in the wrong place:
clc;
clearvars;
N = 100
M = 5
x_t(1) = 0;
y_t(1) = 0;
z_t(1) = 0;
c=lines(M) % save colors so each m has its own
for m=1:M
for n = 1:N % Looping all values of N into x_t(n).
A = sign(randn); % Generates either +1/-1 depending on the SIGN of RAND.
x_t(n+1) = x_t(n) + A;
A = sign(randn); % Generates either +1/-1 depending on the SIGN of RAND.
y_t(n+1) = y_t(n) + A;
A = sign(randn);
z_t(n+1) = z_t(n) + A;
plot3([x_t(n) x_t(n+1)], [y_t(n) y_t(n+1)], [z_t(n) z_t(n+1)],'color',c(m,:));
hold on
grid on
drawnow;
end
end

Looping my algorithm to plot for a different parameter value on the same graph(MATLAB)

I've implemented an algorithm for my physics project which does exactly what I want. The problem that I'm stuck which is not the Physics content itself hence I think it might be somewhat trivial to explain what my code does. I'm mainly stuck with the way MATLAB's plotting works if I was to loop over the same algorithm to produce similar graphs with a slight change of a value of my parameter. Here's my code below:
clear; clc; close all;
% Parameters:
z_nn = 4; % Number of nearest-neighbour in lattice (square = 4).
z_nnn = 4; % Number of next-nearest-neighbours in lattice (square = 4).
Lx = 40; % Number of sites along x-axis.
Ly = 40; % Number of sites along y-axis.
sigma = 1; % Size of a site (defines our units of length).
beta = 1.2; % Inverse temperature beta*epsilon.
mu = -2.53; % Chemical potential mu/epsilon.
mu_2 = -2.67; % Chemical potential mu/epsilon for 2nd line.
J = linspace(1, 11, 11);%J points for the line graph plot
potential = zeros(Ly);
attract = 1.6; %wall attraction constant
k = 1; %wall depth
rho_0 = 0.4; % Initial density.
tol = 1e-12; % Convergence tolerance.
count = 30000; % Upper limit for iterations.
alpha = 0.01; % Mixing parameter.
conv = 1; cnt = 1; % Convergence value and counter.
rho = rho_0*ones(Ly); % Initialise rho to the starting guess(i-th rho_old) in Eq(47)
rho_rhs = zeros(Ly); % Initialise rho_new to zeros.
% Solve equations iteratively:
while conv>=tol && cnt<count
cnt = cnt + 1; % Increment counter.
% Loop over all lattice sites:
for j=1:Ly
%Defining the Lennard-Jones potential
if j<k
potential(j) = 1000000000;
else
potential(j) = -attract*(j-k)^(-3);
end
% Handle the periodic boundaries for x and y:
%left = mod((i-1)-1,Lx) + 1; % i-1, maps 0 to Lx.
%right = mod((i+1)-1,Lx) + 1; % i+1, maps Lx+1 to 1.
if j<k+1 %depth of wall
rho_rhs(j) = 0;
rho(j) = 0;
elseif j<(20+k)
rho_rhs(j) = (1 - rho(j))*exp((beta*((3/2)*rho(j-1) + (3/2)*rho(j+1) + 2*rho(j) + mu) - potential(j)));
else
rho_rhs(j) = rho_rhs(j-1);
end
end
conv = sum(sum((rho - rho_rhs).^2)); % Convergence value is the sum of the differences between new and current solution.
rho = alpha*rho_rhs + (1 - alpha)*rho; % Mix the new and current solutions for next iteration.
end
% disp(['conv = ' num2str(conv_2) ' cnt = ' num2str(cnt)]); % Display final answer.
% figure(2);
% pcolor(rho_2);
figure(1);
plot(J, rho(1:11));
hold on;
% plot(J, rho_2(1,1:11));
hold off;
disp(['conv = ' num2str(conv) ' cnt = ' num2str(cnt)]); % Display final answer.
figure(3);
pcolor(rho);
Running this code should give you a graph like this
Now I want to produce a similar graph but with one of the variable's value changed and plotted on the same graph. My approach that I've tried is below:
clear; clc; close all;
% Parameters:
z_nn = 4; % Number of nearest-neighbour in lattice (square = 4).
z_nnn = 4; % Number of next-nearest-neighbours in lattice (square = 4).
Lx = 40; % Number of sites along x-axis.
Ly = 40; % Number of sites along y-axis.
sigma = 1; % Size of a site (defines our units of length).
beta = 1.2; % Inverse temperature beta*epsilon.
mu = [-2.53,-2.67]; % Chemical potential mu/epsilon.
mu_2 = -2.67; % Chemical potential mu/epsilon for 2nd line.
J = linspace(1, 10, 10);%J points for the line graph plot
potential = zeros(Ly, length(mu));
gamma = zeros(Ly, length(mu));
attract = 1.6; %wall attraction constant
k = 1; %wall depth
rho_0 = 0.4; % Initial density.
tol = 1e-12; % Convergence tolerance.
count = 30000; % Upper limit for iterations.
alpha = 0.01; % Mixing parameter.
conv = 1; cnt = 1; % Convergence value and counter.
rho = rho_0*[Ly,length(mu)]; % Initialise rho to the starting guess(i-th rho_old) in Eq(47)
rho_rhs = zeros(Ly,length(mu)); % Initialise rho_new to zeros.
figure(3);
hold on;
% Solve equations iteratively:
while conv>=tol && cnt<count
cnt = cnt + 1; % Increment counter.
% Loop over all lattice sites:
for j=1:Ly
for i=1:length(mu)
y = 1:Ly;
MU = mu(i).*ones(Ly)
%Defining the Lennard-Jones potential
if j<k
potential(j) = 1000000000;
else
potential(j) = -attract*(j-k).^(-3);
end
% Handle the periodic boundaries for x and y:
%left = mod((i-1)-1,Lx) + 1; % i-1, maps 0 to Lx.
%right = mod((i+1)-1,Lx) + 1; % i+1, maps Lx+1 to 1.
if j<k+1 %depth of wall
rho_rhs(j) = 0;
rho(j) = 0;
elseif j<(20+k)
rho_rhs(j) = (1 - rho(j))*exp((beta*((3/2)*rho(j-1) + (3/2)*rho(j+1) + 2*rho(j) + MU - potential(j)));
else
rho_rhs(j) = rho_rhs(j-1);
end
end
end
conv = sum(sum((rho - rho_rhs).^2)); % Convergence value is the sum of the differences between new and current solution.
rho = alpha*rho_rhs + (1 - alpha)*rho; % Mix the new and current solutions for next iteration.
disp(['conv = ' num2str(conv) ' cnt = ' num2str(cnt)]); % Display final answer.
figure(1);
pcolor(rho);
plot(J, rho(1:10));
end
hold off;
The only variable that I'm changing here is mu. I would like to loop my first code so that I can enter an arbitrary amount of different values of mu and plot them on the same graph. Naturally I had to change all of the lists dimension from (1 to size of Ly) to (#of mu(s) to size of Ly), such that when the first code is being looped, the i-th mu value in that loop is being turned into lists with dimension as long as Ly. So I thought I would do the plotting within the loop and use "hold on" encapsulating the whole loop so that every plot that was generated in each loop won't be erased. But I've been spending hours on trying to figure out the semantics of MATLAB but ultimately I can't figure out what to do. So hopefully I can get some help on this!
hold on only applies to the active figure, it is not a generic property shared among all figures. What is does is changing the value of the current figure NextPlot property, which governs the behavior when adding plots to a figure.
hold on is equivalent to set(gcf,'NextPlot','add');
hold off is equivalent to set(gcf,'NextPlot','replace');
In your code you have:
figure(3); % Makes figure 3 the active figure
hold on; % Sets figure 3 'NextPlot' property to 'add'
% Do some things %
while conv>=tol && cnt<count
% Do many things %
figure(1); % Makes figure 1 the active figure; 'hold on' was not applied to that figure
plot(J, rho(1:10)); % plots rho while erasing the previous plot
end
You should try to add another hold on statement after figure(1)
figure(1);
hold on
plot(J, rho(1:10));

Errorbar line missing in Matlab

The following code produces the image shown:
probabilities = datasetlist(1,:);
avgscores = datasetlist(2,:);
x = probabilities;
y = probabilities;
err = avgscores;
hold on
for k = 1:length(x)
e1 = errorbar(x(k),y(k),err(k),'-');
if err(k) == min(err)
set(e1,'Color','r')
set(e1,'MarkerEdgeColor','r')
set(e1,'Marker','*')
else
set(e1,'Color','k')
set(e1,'MarkerEdgeColor','k')
set(e1,'Marker','.')
end
end
hold on
e1.LineStyle = '-';
But, there should be a line connecting the datapoints. I even set the e1.LineStyle, but that didn't work. How can I produce that line?
You have no line because you don't plot vectors, but single values each time, which is why you get something that is closer to a scatter plot.
Below are two of the ways to fix this:
Solution 1 is a workaround that changes your existing code minimally.
Solution 2 is much shorter code that achieves a same-looking result, by plotting vectors directly. (recommended).
function q40765062
%% Prepare the data:
datasetlist = [0.4:0.05:0.7; abs(randn(1,7))];
probabilities = datasetlist(1,:);
avgscores = datasetlist(2,:);
x = probabilities;
y = probabilities;
err = avgscores;
%% Solution 1:
figure();
hold on
for k = 1:length(x)
e1 = errorbar(x(k),y(k),err(k),'-');
if err(k) == min(err)
set(e1,'Color','r')
set(e1,'MarkerEdgeColor','r')
set(e1,'Marker','*')
else
set(e1,'Color','k')
set(e1,'MarkerEdgeColor','k')
set(e1,'Marker','.')
end
end
plot(x,y,'-k'); % < The main difference in this solution.
%% Solution 2:
figure();
[~,I] = min(err); % < We compute the index of the minimal value before plotting anything.
errorbar(x,y,err,'-*k'); hold on; % < Notice how we use the entire vectors at the same time.
errorbar(x(I),y(I),err(I),'-*r'); % < We only plot one value this time; in red.

Weird thing with matlab's plotting

When I execute this plot function trying to plot my data as a solid red line it will not plot anything.
plot(1:n, exp(x), '-r')
However, if I change the specification from a solid red line to a green line of circles still using the exact same data as so,
plot(1:n, exp(x), 'og')
it will plot! Why??
Here is all the code if needed.
clear all;
close all;
fprintf('\n\nJustin White Th-9\n\n')
x = input('Input the value of x to be approximated: ');
se = input('Input the target approximate perecent relative error, se: ');
[apre, macexp, n] = f_macexpF15(x, se);
macexp = macexp(1:end-1);
plotyy( 1:n, macexp, 1:n, apre);
hold on;
plot(1:n, exp(x), '-r')
And function it calls here
function[apre, macexp, n] = f_macexpF15(x, se)
fprintf('\nJustin White Th-9\n')
apre = 100*ones(1,3);
ms = [36 22 10];
macexp(1) = 1;
j = 1;
n = 1;
%% comments
while apre >= se
macexp(j+1) = macexp(j) + x^j/factorial(j);
apre(j) = 100 * ((macexp(j+1)-macexp(j))/macexp(j+1));
j = j + 1;
n = n + 1;
end
n = n - 1;
end
Thanks in advance
Easy, 1:n is a vector of length n, whereas x is only a scalar value if not entered correctly. So first of all check whether or not both vectors (1:n and x) are of same size.
Why? If you have two entries for the plot command, and one entry is a vector and the other is a scalar, then MATLAB treats that as if you entred n different plot commands (n for the length of the vector).

K-Means Clustering of random numbers in Matlab

I have a program that generates 10 fixed points and 3 random points when run. I would like the 10 fixed points to use K-means clustering but don't know where to begin. My code is below
function TESTING (re_point)
%***********************NOTE*************************************
% if re_point = 0 [default]
% points generated for xtemp and y_temp remain fixed
% if re_point = 1
% new points are generated for x_temp and y_temp
% Variable definitions for tags and figure window
persistent xtemp ytemp hFig
% Initialisiation of re_point
if nargin<1
re_point = 0; % If 0, the points are fixed, if 1 they move
end
A1 = 30; % area defined as 30 X 30 grid
N = 10;
R = 3; % 3 readers
s = rng; % fixed tags does not change position when simulated repatedly
rng(s)
if (isempty(xtemp) && isempty(xtemp)) || re_point == 1
% Generate x and y position of tags
xtemp = A1*rand(1,N);
ytemp = A1*rand(1,N);
end
if isempty(hFig)
hFig = figure;
end
% Generate x and y position of red points
xtemp_2 = A1*rand(1,R);
ytemp_2 = A1*rand(1,R);
% plot data
plot(xtemp,ytemp,'.',xtemp_2,ytemp_2,'rs','LineWidth',1,'MarkerEdgeColor','k','MarkerFaceColor','r','MarkerSize',14);
% Labelling of the red markers
for iter = 1:numel(xtemp_2)
text(xtemp_2(iter),ytemp_2(iter), num2str(iter),...
'FontSize',8,'HorizontalAlignment','center',...
'Color','White','FontWeight','bold');
end
grid on
hold off
axis([0 A1 0 A1])
% Tag formatting
xoffset = 0;
yoffset = -1;
fsize = 8;
temp_str = mat2cell(num2str([xtemp(:) ytemp(:)], '(%.2f,%.2f)'), ones(1,N));
text(xtemp+xoffset, ytemp+yoffset, temp_str,'fontsize', fsize)
% distance function calculator
cDistance = distanceCalc()
function S = distanceCalc
S = size(numel(xtemp),numel(xtemp_2));
for ri = 1:numel(xtemp)
for fi = 1:numel(xtemp_2)
S(ri,fi) = pdist([xtemp(ri),ytemp(ri);...
xtemp_2(fi),ytemp_2(fi)],...
'euclidean');
end
end
end
end
This particular snippet from the block above generates the 10 fixed points that need to be clustered
if (isempty(xtemp) && isempty(xtemp)) || re_point == 1
% Generate x and y position of tags
xtemp = A1*rand(1,N);
ytemp = A1*rand(1,N);
end
It's not clear at all from your question what you want to do with kmeans, for instance how many clusters are you looking for? I recommend looking at the first example in the MATLAB ref guide
For your data you can try e.g.
X = [xtemp(:) ytemp(:)];
Nclusters = 3;
[idx,C] = kmeans(X,Nclusters);
For plotting something like the following should work:
figure, hold on
plot(X(idx==1,1),X(idx==1,2),'b*')
plot(X(idx==2,1),X(idx==2,2),'g*')
plot(X(idx==3,1),X(idx==3,2),'r*')
to get started. This will attempt to classify your random points into 3 clusters. The cluster into which each point has been classified is defined in idx.