MATLAB将变量与匿名函数一起存储。以下是the documentation的工作原理示例。
表达式中的变量:
函数句柄不仅可以存储表达式,还可以存储变量 该表达式需要进行评估。
例如,为匿名函数创建一个函数句柄 需要系数a,b和c。
a = 1.3; b = .2; c = 30; parabola = @(x) a*x.^2 + b*x + c;
因为a,b和c在您创建抛物线时可用,所以 函数句柄包括那些值。价值观持续存在于 即使清除变量,函数句柄:
clear a b c x = 1; y = parabola(x) y = 31.5000
据推测,即使将b和c的值保存并从mat文件重新加载,它们也会与函数一起存储。在实践中,我发现这些值不会持久存在,尤其是在编辑最初创建函数的代码时。
有没有办法根据变量的数值定义函数句柄?我想要一些形式
>> a = 1.3;
>> b = .2;
>> c = 30;
>> parabola = @(x) a*x.^2 + b*x + c
parabola = @(x) a*x.^2+b*x+c
>> parabola2 = forceEval(parabola)
parabola2 = @(x) 1.3*x.^2+.2x+30
编辑:也许我的问题在于文件关联,但是当我编辑我最初定义匿名函数的文件时,我得到一个看起来像的错误:
无法找到函数@(ydata)nr /(na * dt)* normpdf(ydata,mu(j),s(j))./ normpdf(ydata,mu_a(j),s_a(j)) C:\ mfilename.m。 (我将mfile的名称更改为mfilename)
我对这类东西的常用解决方案是使用func2str()来删除文件依赖项,但这也会删除包含参数值的工作空间信息。所以我想强制所有参数在函数定义中采用它们的数值。
答案 0 :(得分:6)
值存储在函数中。正如我之前在不同的答案中演示的那样,您可以使用functions
命令进行检查:
>> a = 1.3; b = .2; c = 30;
>> parabola = @(x) a*x.^2 + b*x + c;
>> x = 1;
>> y = parabola(x)
y =
31.5
>> clear a b c
>> y = parabola(x)
y =
31.5
>> fi = functions(parabola)
fi =
function: '@(x)a*x.^2+b*x+c'
type: 'anonymous'
file: ''
workspace: {[1x1 struct]}
>> fi.workspace{1}
ans =
a: 1.3
b: 0.2
c: 30
即使将句柄保存到磁盘:
>> save parabolaFun.mat parabola
>> clear parabola a b c
>> load parabolaFun.mat parabola
>> y = parabola(x)
y =
31.5
>> fi = functions(parabola)
fi =
function: '@(x)a*x.^2+b*x+c'
type: 'anonymous'
file: ''
workspace: {[1x1 struct]}
>> fi.workspace{1}
ans =
a: 1.3
b: 0.2
c: 30
你可以简化这样的抛物线手柄的创建:
function p = makeParabola(a,b,c)
p = @(x) a*x.^2 + b*x + c;
end
您可以使用MATLAB®保存和加载功能在MAT文件中保存和加载函数句柄。如果加载在早期MATLAB会话中保存的函数句柄,则以下条件可能会导致意外行为:
- 定义该函数的任何文件都已移动,因此句柄中存储的路径不再存在。
- 将功能句柄加载到与保存环境不同的环境中。例如,函数的源不存在,或者位于与保存句柄的系统不同的文件夹中。
在这两种情况下,函数句柄现在都无效,因为它不再与任何现有的函数代码相关联。虽然句柄无效,但MATLAB仍然可以成功执行加载而不显示警告。但是,尝试调用句柄会导致错误。
因此,如果您从文件支持的函数(不是脚本,那没关系)创建句柄,然后修改或删除该文件,句柄将变为无效。
答案 1 :(得分:3)
匿名函数capture表达式中涉及的所有变量的值。如果您想要查看捕获的环境工作区,请使用functions
作为答案中显示的@chappjc。
现在你要注意匿名函数中使用的变量类型(想想值类型与句柄类型)。
捕获所有native types(数字,逻辑,结构,单元格等)by-value not by-reference。例如:
x = magic(4);
f = @() x; % captures matrix x
x(1) = 1 % modify x
xx = f() % change not reflected here
将其与使用handle-class类型(例如containers.Map
)进行比较:
x = containers.Map('KeyType','char', 'ValueType','double');
f = @() x; % captures handle-class object x
x('1') = 1; % modify map
keys(x) % changed
keys(f()) % also changed!
f() == x % compare handle equality, evaluates to true
答案 2 :(得分:1)
a = 1.3, b = 0.2, c = 30;
parabola = eval(['@(x) ', num2str(a), '*x^2 + ', num2str(b), '*x + ', num2str(c)]);