Translating the map command and few others from Mathematica to MATLAB

后端 未结 3 1609
我寻月下人不归
我寻月下人不归 2020-12-11 13:18

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         


        
相关标签:
3条回答
  • 2020-12-11 13:34

    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.)

    0 讨论(0)
  • 2020-12-11 13:35

    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 讨论(0)
  • 2020-12-11 13:39

    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}
    
    0 讨论(0)
提交回复
热议问题