所以,我最近从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)。最好是我的问题的答案不会有这个限制,但如果确实如此,我仍然会接受它。
答案 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/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背景开始并坚定地在Mathematica中编写For
循环)。
答案 1 :(得分:3)
实际上,您提出的解决方案无法按预期工作:
y = 2;
x = @()(y);
y = 3;
x()
当你定义匿名函数时,它会创建一个闭包并在那一刻捕获/复制y
的值(现在它有自己的y
副本)。然后,如果更改外部的y
,则不会影响在闭包中创建的2
,因此在您的示例中,最后一个值将返回3
而不是{{1}}
我能想到的唯一方法是将变量封装在一个闭包中并公开set / get方法(就像在OOP中一样)
IMO,MATLAB和Mathematica有两种非常不同的语言,因此我会采用MATLAB方式而不是尝试模拟其他语言的功能(这通常不是最好的选择)