Можете ли вы выполнить отложенный набор (: = в Mathematica) в Matlab? - PullRequest
5 голосов
/ 30 июля 2011

Итак, я недавно перешел из Mathematica в Matlab, и, хотя Matlab обладает большинством полезных функций Mathematica, я не могу понять, как выполнить эквивалент операции отложенного набора Mathematica ': =', которая назначает переменную aзначение ленивым образом.

Например, в Mathematica:

y = 2;

x: = y;

y =3;

x

даст значение x как 3, тогда как единственный способ получить такое же поведение в Matlab:

y = 2;

x = @ () (y);

y = 3;

x ()

, что в то время какТехнически отвечая на мой вопрос, это довольно специальная работа вокруг и требует обработки x как функции.

Так есть ли более естественный способ сделать это - Matlab?

РЕДАКТИРОВАТЬ:

мое специальное решение работает только тогда, когда y является полем класса дескриптора,Я оставил это из кода для ясности (это должен быть someclass.y).Желательно, чтобы в ответе на мой вопрос не было этого ограничения, но я бы все же согласился, если бы оно имело место.

Ответы [ 2 ]

5 голосов
/ 30 июля 2011

Ленивая оценка в основном используется в функциональных языках программирования, а MATLAB - процедурный / ООП.Таким образом, эквивалент SetDelayed не существует.Если вы попытаетесь использовать анонимные функции, как вы продемонстрировали, это не сработает, как уже указывал Amro.

Однако, если у вас есть доступ к инструментарию символьных вычислений, вы можете обойтись чем-то, что можно было бы считать эквивалентом := (хрупкая эквивалентность, если вы спросите меня).Вот пример:

syms x y z; %#Declare x, y and z as symbolic variables
x=y+2; %#Define some value for x
f=@(x)x.^2; %#Define an anonymous function. 

f(x)

ans =

(y + 2)^2

%#Check with z
f(z)

ans =

z^2   

Вы можете видеть, что оно использует фактическое определение f и не фиксирует определение x, как это было в вашем числовом примере.Вы также можете изменить определение x, сказав, что x=1/y и f(x) теперь будут использовать текущее определение x.Обратите внимание, что f является просто дескриптором функции и будет принимать числовые / символические аргументы.Например,

f(1:5)

ans =

     1     4     9    16    25

Часть, в которой он не похож на :=, состоит в том, что он применяет определения только для терминов, присутствующих в выражении, и не углубляется (т. Е.не оценивает определения для другого набора переменных, которые могут возникнуть в результате первой оценки).Это вряд ли удивительно, поскольку MATLAB не является языком, основанным на правилах.Чтобы проиллюстрировать мою мысль:

y=z^3; %#Define y
f(x)

ans = 
(y + 2)^2 %#The definition for y is not used.

, тогда как Mathematica дала бы вам (z^3+2)^2.

Clear[y, z, x, f]
f[x_] := x^2;
y := z^3; x := y + 2;

f[x]

Out[1]= (2 + z^3)^2

Лучше всего, если вы учтете различия в двух языках ипытался придерживаться того, что идиоматично в каждом.Попытка отрицать это и программировать в одном, как в другом, может сделать вашу жизнь несчастной (например, начинать с фона C и непреклонно писать циклы For в Mathematica).

3 голосов
/ 30 июля 2011

На самом деле предложенное вами решение не работает должным образом:

y = 2;
x = @()(y);
y = 3;
x()

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

Единственный способ, которым я могу придумать, - это инкапсулировать переменную в замыкание и предоставить методы set / get (как в ООП)

IMO, MATLAB и Mathematica имеют два совершенно разных языка, поэтому я бы использовал путь MATLAB, а не пытался эмулировать свойства других языков (что обычно не лучшая вещь)

...