开发者

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')
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜