从符号差异的结果创建函数句柄的问题

问题描述

假设我有一个定义为的简单函数句柄

Eq.1    F = @(t,A) A(1) + A(2)*t + A(3)*t^2;

我想根据F的不同来定义另一个函数句柄,例如

Eq.2:  dF = @(t,A) diff( F(t,A),t );

但是,似乎禁止在某个特定的dF(例如t)上评估dF(0,A),并且出现错误,因为

“第二个参数必须是变量或变量”

然后我尝试使用如下所示的表达式:

Eq.3   dF(t,A) = diff( F(t,t );

这样,它可以直接评估t = 0

但是,必须使用dF( 0,A(1),A(2),A(3) )的形式来评估等式3,而不是dF(0,A)

我的问题是:

是否有一种更简单的方法使用直接形式dF(0,A)而不是dF(0,... )来进行直接评估

要节省在A(...)中一次dF( 0,...,A(100) )一次键入的麻烦,假设有100个参数

PS: 不使用matlabFunction


测试代码如下:

syms t A a0 a1 a2

A = [a0,a1,a2];

F = @(t,A) A(1) + A(2)*t + A(3)*t^2;

dF1      =          @(t,t );

dF2(t,A) =                 diff( F(t,t );                   % Same as using symfun

dF3      = matlabFunction( diff( F(t,t ),'Vars',{t,A} );

现在,在命令窗口中键入

>> dF1(t,A)
>> ans = a1 + 2*a2*t

>> dF1(0,A)
>> ans = a0               % This is wrong

>> dF3(t,A)
>> ans = a1 + 2*a2*t

>> dF3(0,A)
>> ans = a1               % This is correct

>> dF2(t,A)
   Error using symfun/subsref (line 141)
   Symbolic function expected 4 inputs and received 2.

>> dF2(t,a0,a2)
>> ans = a1 + 2*a2*t

>> dF2(0,a2)
>> ans = a1               % This is correct

很明显,只有dF2是符号函数。 但是,输入形式似乎不太友好。

matlabFunction的运行速度比symfun慢得多,并且@(x,A) diff(...)无法接受数值结果。这就是为什么我要使用symfun来定义具有太多参数的函数的原因。但是,符号功能的输入形式似乎并不那么直接也不友好。

解决方法

您的问题得到解答over at MATLAB Answers。简而言之:这是无法做到的。 您不能创建使用数组作为输入的符号函数:

这一切都反映了符号引擎的基本内部限制:符号引擎的内部没有提供描述或操作“数组”的内容,该数组的内容将在以后填充。

链接的帖子详细介绍了MATLAB中符号引擎的工作原理以及工作原理。我建议您阅读它。


您的代码显示了一些关于符号函数和匿名函数的误解。当你做

F = @(t,A) A(1) + A(2)*t + A(3)*t^2;

您正在创建匿名函数的函数句柄。它与符号变量tA完全无关,它不是符号函数。在这里,tA只是输入参数,可以用任何东西填充。

下一步

dF1 = @(t,A) diff( F(t,A),t );

为匿名函数创建另一个函数句柄,这一次该函数将求值x=F(t,A),然后调用diff(x,t),其中diffthe normal function,而不是其中的那个。符号工具箱。它计算t次后续数组元素之间的差。

要创建符号函数,您可以执行以下操作:

clear
syms t
A = sym('a',[1,3]);        % A = [a1,a2,a3]
F = symfun(A(1) + A(2)*t + A(3)*t^2,[t,A]);
dF = diff(F,t);
dF(0,A(1),A(2),A(3))     % returns a2

但是,这会创建一个符号函数,其中A的每个元素都是一个单独的输入参数,这不是您想要的。除了我在顶部链接的帖子的答案中所建议的那样,没有其他方法可以创建一个匿名函数来评估您的符号表达式:

clear
syms t
A = sym('a',3]);
F = symfun(A(1) + A(2)*t + A(3)*t^2,A]);
dF_sym = diff(F,t);
dF = @(t,A)dF_sym(t,A(3));
dF(0,A)                    % returns a2

PS:请注意,上面的symfun调用与:

clear
syms t F(t,a1,a3)
F(t,a3) = a1 + a2*t + a3*t^2;

,这就是通常创建符号函数的方式。我使用上面的symfun可以使用A而不是a1a2a3

,

似乎您刚刚混合了一些东西。 您anonymous function的定义很好,但我认为它们不代表您的预期用途。

函数diff计算向量中的差异或执行n次。第二个参数指定后者:

Y = diff(X,n)通过应用diff(X)计算第n个差 运算符递归n次。实际上,这意味着diff(X,2)是 与diff(diff(X))相同。

因此,很明显#Merge this table with the summary table df2 = pd.merge(df2,df_intermediate2,how='left',on='Sport') 会引发错误(“计算某物的第0个差”)。 我不禁想到这不是您想要的(因为在原始函数diff(...,0)中使用t毫无意义...)。我假设F是一个时间(向量)

也许这更适合您的问题:

t

所以你可以做

F = @(t,A) A(:,1) + A(:,2).*t + A(:,3).*t.^2; % vector-wise
dF = @(t,A) diff(F(t,[],1)./diff(t,1); % row-wise difference

PS:这些不是 symbolic 函数,而只是匿名函数句柄,即指向函数的指针(有一个单独的 Symmbolic Math Toolbox 和要将符号数学函数添加到函数句柄,可以使用matlabFunction函数)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...