Перевод команды map и нескольких других из Mathematica в MATLAB - PullRequest
1 голос
/ 17 февраля 2011

Я сделал это до сих пор:

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

Единственная проблема сейчас заключается в том, что 2-й столбец «данных» должен давать мне значения около

10
30
50
70
90

но не совсем. Только приблизительно. Например, «данные» должны быть:

10  10.184
30  27.51
50  50.306
70  68.394
90  90.414

Sth не так с суммой, может быть?

Ответы [ 3 ]

3 голосов
/ 17 февраля 2011

Хотя Matlab поддерживает анонимные функции и имеет элементарную поддержку для функционального программирования, он не особенно хорошо поддерживается или идиоматичен. Подход Matlab состоит в том, чтобы вместо этого использовать векторы (имя Matlab для массивов) везде, где это возможно, и использовать функции, которые оцениваются по этим векторам.

Вместо

Walk1D =@ (n) cumsum(steps(n));

, который не работает, потому что аргумент cumsum (который ожидает вектор) просто steps(n) (единственный элемент вектора steps!), Идиоматический подход Matlab заключается в том, чтобы сделать что-то вроде:

Nsteps = 100;  
steps = randn(1, Nsteps);
walk1D = cumsum(steps);

и т.д.

Если вам это нужно, эквивалентами Matlab оператору "map" функционального программирования являются cellfun и arrayfun.

(Кроме того: наследие Matlab коренится в Fortran, по сравнению с Mathematica, которая вдохновлена ​​Lisp. Анонимные функции в Matlab ограничены простыми выражениями, поэтому часто необходимо использовать традиционную именованную функцию, хранящуюся в отдельной. Я часто чувствую, что функциональные программные конструкции в Matlab в основном новы, хотя иногда они полезны.)

2 голосов
/ 17 февраля 2011

Я бы немного прокомментировал ваш вклад в Mathematica, предлагая улучшения эффективности

Walk1D[n_] :=  Join[{0},Accumulate[steps[n]]]
LastPoint1D[n_] := Total[steps[n]]

Вот время, показывающее разницу

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}
1 голос
/ 22 февраля 2011

Из вашего кода, я думаю, вы хотите рассчитать среднее квадратное расстояние для 1D случайного блуждания.

Среднеквадратичное расстояние при лаге tt - это среднеквадратичная разница между двумя позициями вдоль случайного блуждания, разделенных tt шагами. Я предполагаю, что data должен быть массивом, где первый столбец равен tt, а второй столбец соответствует соответствующему среднеквадратичному расстоянию, и где есть дополнительный параметр, который указывает общее количество шагов в вашей случайной прогулке.

Вот как я бы рассчитал 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')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...