Translating the map command and few others from Mathematica to MATLAB
I did these so far:
EDIT---------------
steps=@ (m) 2*randi([0,1],[1,m])-1;
Walk1D =@ (n) [0,cumsum(steps(n))];
findend=@ (x) x(end);
LastPoint1D=@(n) findend(Walk1D(n));
nsteps=200;
nsq=floor(sqrt(nsteps));
MeanSquareDistance1D= @ (n,m) m.*sum((LastPoint1D(n)).^2)./m;
r2D=MeanSquareDistance1D(100,1000)
data=[ ];
for i=10:20:90
data=[data; i , MeanSquareDistance1D(i,2000)]
end
The only problem now,is that the 2nd column of "data" must give me values around
10
30
50
70
90
but not exactly.Only approximately.For example ,the "data" must be:
10 10.1开发者_开发知识库84
30 27.51
50 50.306
70 68.394
90 90.414
Sth is wrong with the sum maybe?
Although Matlab supports anonymous functions and has rudimentary support for functional programming, it is not particularly well-supported or idiomatic. The Matlab approach is to instead use vectors (the Matlab name for arrays) wherever possible, and use functions which are evaluated over these vectors.
Instead of
Walk1D =@ (n) cumsum(steps(n));
which does not work because the argument to cumsum
(which expects a vector) is simply steps(n)
(a single element of the vector steps
!), the idiomatic Matlab approach is to do something like:
Nsteps = 100;
steps = randn(1, Nsteps);
walk1D = cumsum(steps);
etc.
If you do need it, the Matlab equivalents to the functional programming "map" operator are cellfun
and arrayfun
.
(Aside: Matlab's heritage is rooted in Fortran, compared to Mathematica, which is inspired by Lisp. Anonymous functions in Matlab are limited to simple expressions, so it is often necessary to use a traditional named function stored in a separate .m file. I often feel that the functional programming constructs in Matlab are mostly a novelty, though they are sometimes useful.)
I would comment on your Mathematica input a little, suggesting efficiency improvements
Walk1D[n_] := Join[{0},Accumulate[steps[n]]]
LastPoint1D[n_] := Total[steps[n]]
Here are timings showing the difference
In[51]:= steps[n_Integer] := RandomInteger[{-10, 10}, n]
In[52]:= Walk1D[n_] := Join[{0}, Accumulate[steps[n]]]
In[53]:= Walk1Da[n_] := FoldList[Plus, 0, steps[n]]
In[56]:= BlockRandom[SeedRandom[1]; AbsoluteTiming[r = Walk1D[10^7];]]
Out[56]= {0.3650000, Null}
In[57]:= BlockRandom[SeedRandom[1]; AbsoluteTiming[r = Walk1Da[10^7];]]
Out[57]= {1.1370000, Null}
From your code I guess you want to calculate the mean squared distance for a 1D random walk.
The mean squared distance at lag tt
is the average squared difference between two positions along the random walk separated by tt
steps. I assume that data
should be an array where the first column is tt
and the second column the corresponding mean squared distance, and where there is an additional parameter that indicates the total number of steps in your random walk.
Here's how I'd calculate data
%# define parameters
nSteps = 2000;
listOfLags = 10:20:90; %# must be 1-by-n vector
%# create random walk
%# steps can be +1 or -1, add all of them via cumsum
randomWalk = cumsum(randi([0 2],nSteps)-1);
%# calculate msd for the desired lags
%# use a loop for readability
nLags = length(listOfLags);
data = zeros(nLags,2);
data(:,1) = listOfLags;
for lag = listOfLags
%# lag takes on every lag value, so use logical indexing to find
%# which lag (in terms of entry into data) we're currently working on
%# This line corresponds to
%# 1. get all distances traveled within a duration of `lag`
%# vectorOfDistances = randomWalk(lag+1:end) - randomWalk(1:nSteps-lag)
%# i.e. the first element is randomWalk(lag+1)-randomWalk(1)
%# 2. square all: (vectorOfDistances).^2
%# 3. average all squared distances
data(listOfLags==lag,2) = mean( (randomWalk(lag+1:end) - randomWalk(1:end-lag)).^2);
end
%# plot the results
plot(data(:,1),data(:,2),'.')
xlabel('lag'),ylabel('mean squared displacement')
精彩评论