试图理解以两种不同方式定义的匿名函数的结果

计算科学 matlab
2021-12-20 20:05:09

我正在尝试使我的代码更高效,因此在这里探索替代方案并提供一个简化的示例。这是我想到的在 matlab 中定义匿名函数的 3 个不同版本。

% Version 1 definition in script

clc;
clear;

syms x1 x2;

b = 2;

c = 3.5;

ExampleFunc = @(x1,x2) x1^3 + b*x2 + c;

% Below from command window for version 1

示例函数

示例函数 =

 @(x1,x2)x1^3+b*x2+c

ExampleFunc(2.5,5)

答案=

29.1250



% Version 2 definition in script

clc;
clear;

syms x1 x2;

b=2;

c=3.5;

TempExpr = x1^3 + b*x2 + c;

ExampleFunc = @(x1,x2) TempExpr;

% Below results from command window  for version 2

示例函数

示例函数 =

 @(x1,x2)TempExpr

ExampleFunc(2.5,5)

答案=

x1^3 + 2*x2 + 7/2

% Version 3 definition in script

clc;

clear;

syms x1 x2 b c;

TempExpr = x1^3 + b*x2 + c;

b=2;

c=3.5;

ExampleFunc = @(x1,x2) TempExpr;

% Below results from command window  for version 3

示例函数

示例函数 =

 @(x1,x2)TempExpr

ExampleFunc(2.5,5)

答案=

x1^3 + c + b*x2

为什么当我尝试查询定义并评估 x1 和 x2 的特定值时,上述版本会提供不同的结果:-

  • 在版本 1 中,定义中没有显示 b 和 c 的值(尽管我知道根据 Matlab 文档,b 和 c 的值作为常量值存储在后端 - 顺便说一句,如何检查那些确切的值值是。在命令窗口中键入 b、c 是不正确的,因为它会在查询时而不是在定义时显示工作区中这两个变量假定的值?)。

另一方面,在第 2 版(和第 3 版)中,定义没有扩展 TempExpr(顺便说一句,如何检查 TempExpr 是什么?我可以输入它,但这是唯一的方法吗?)如果是第 2 版,输入命令窗口中的 TempExpr 将 b 和 c 替换为其定义期间使用的值。在版本 3 的情况下,在命令窗口中键入 TempExpr 以符号形式保留 b 和 c?

  • 为什么 x1=2.5 和 x2=5 的评估在版本 1 中正常工作(提供了数字答案),而在版本 2 中它只显示 ExampleFunc 的基础定义(根据定义期间使用的值替换 b 和 c)但确实不在给定点进行评估。

在版本 3 中,b 和 c 都不会被替换,函数也不会在给定值 x1、x2 处进行评估?

预期结果:我的最终目标是强制第 3 版在功能评估方面表现得像第 1 版。原因在我的应用程序中,b,c 可以被认为是参数,当以符号形式定义时,可以精确定义 TempExpr,然后对于参数 b 和 c 的特定值,我将 ExampleFunc 传递给 fmincon,然后在x, x2 的具体值。

目前,为了强制版本 3 的行为类似于版本 1,我必须使用 subs 函数来定义 ExampleFunc,这会增加执行时间(这很重要,因为我正在运行 fmincon 以获取大量参数组合)。我希望通过使用匿名函数,b、c 的值将自动替换为匿名函数定义期间使用的值,但这不是这里注意到的行为。

1个回答

预期结果:我的最终目标是强制版本 3 在功能评估方面表现得像版本 1。原因在我的应用程序中,b,c 可以被认为是参数,当以符号形式定义时,可以精确定义 TempExpr,然后对于参数 b 和 c 的特定值,我将 ExampleFunc 传递给 fmincon,然后在x, x2 的具体值。

如果那是您想要做的,为什么不使用闭包

[ExampleFunc] = function myClosure(b,c)
return @(x1,x2)(x1.^3 + b * x2 + c)

这个构造建立在你现有的匿名函数构造之上,允许你在非本地地绑定你的匿名函数的值bc到你的匿名函数。您可以将闭包用作工厂来生成一堆具有不同参数值的目标函数。

至于您的三个示例,示例1和示例2之间的差异似乎主要与范围有关;TempExpr匿名函数定义而不是实际表达式中使用时,它使用变量x1x2在全局范围而不是匿名函数范围内定义。

示例 2 和示例 3 之间的区别似乎主要在于示例 3 中,您将b和声明c为符号变量。我不明白为什么这里需要任何变量来表示符号,因为您只是在评估函数;也许我错过了一些东西。