你能在Matlab中执行延迟集(:= Mathematica)吗?

时间:2011-07-29 20:56:30

标签: matlab wolfram-mathematica lazy-evaluation delayed-execution

所以,我最近从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吗?

编辑:

我的ad-hoc解决方案仅在y是句柄类的字段时才起作用,为了清楚起见,我将其从代码中删除(它应该是someclass.y)。最好是我的问题的答案不会有这个限制,但如果确实如此,我仍然会接受它。

2 个答案:

答案 0 :(得分:5)

Lazy evaluation主要用于函数式编程语言,MATLAB是基于过程/ OOP的。因此,不存在等价的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/yf(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背景开始并坚定地在Mathematica中编写For循环)。

答案 1 :(得分:3)

实际上,您提出的解决方案无法按预期工作:

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

当你定义匿名函数时,它会创建一个闭包并在那一刻捕获/复制y的值(现在它有自己的y副本)。然后,如果更改外部的y,则不会影响在闭包中创建的2,因此在您的示例中,最后一个值将返回3而不是{{1}}

我能想到的唯一方法是将变量封装在一个闭包中并公开set / get方法(就像在OOP中一样)

IMO,MATLAB和Mathematica有两种非常不同的语言,因此我会采用MATLAB方式而不是尝试模拟其他语言的功能(这通常不是最好的选择)