如何在 Maple 中定义自定义函数?
How to define custom functions in Maple?
我是 Maple 的新手,我正在寻找一种简单的方法来自动执行某些任务。特别是,我正在寻找一种方法来定义自动执行某些步骤的自定义“操作”。
作为示例,我想定义一种快速方法来计算多项式的 Hessian 矩阵的行列式。目前我这样做的方法是打开 Maple,创建一个新的工作表而不是执行以下命令:
p := (x, y) -> x^2*y + 3*x^3 + y^3
with(VectorCalculus):
h := Hessian(p(x, y), [x, y])
Determinant(h)
我想做的是直接用
之类的东西计算 hessian 行列式
HessDet(p)
其中 HessDet
是执行上述操作的自定义命令。如何在 Maple 中实现这样的目标?
首先要注意的是:分配给 p
的值是一个 过程,它可以 return 一个多项式表达式,但它本身不是一个多项式。重要的是不要混淆表达式和过程。这样做是新用户出现问题的常见原因。
能够四处乱扔 p(x,y)
可能在视觉上令人赏心悦目,但它在这里没有什么编程目的。事实上,过程 p
的形式参数恰好被称为 x
和 y
,以及你使用参数 x
调用过程 p
和y
,实际上只是另一个常见的混淆来源。不要仅仅为了以这种方式调用它们而创建过程。
此外,您的调用 p(x,y)
让您的代码片段“知道”过程 p
需要多少参数看起来很神奇。所以让你的候选人 HessDet
接受 p
作为程序已经是一团糟了。
因此,让我们保持直截了当,通过编写 HessDet
来接受多项式而不是过程。我们可以通过编程确定 type
polynom
.
的表达式的名称
restart;
HessDet:=proc(p::algebraic)
local H,vars;
vars:=indets(p,
And(name,Non(constant),
satisfies(u->type(p,polynom(anything,u)))));
H:=VectorCalculus:-Hessian(p,[vars[]]);
LinearAlgebra:-Determinant(H);
end proc:
下面是一些使用示例,
P := x^2*y + 3*x^3 + y^3;
HessDet(P);
p := (x, y) -> x^2*y + 3*x^3 + y^3;
HessDet(p(x,y));
HessDet(x^3-x^2+4*x);
HessDet(s^2*t + 3*s^3 + t^3);
HessDet(s[r]^2*t[r] + 3*s[r]^3 + t[r]^3);
您可能还想知道如何跨会话重复使用此自定义过程,而不必每次都输入它。两种合理的方式是:
- 将
HessDet
的(上述)明文定义放在个人 initialization file. 中
- Create a (.mla) Maple Library Archive file, then Save your
HessDet
to that, and then augment the Library search path 在你的初始化文件中。
看起来 2) 比较费力,但是重复只需要保存步骤,并且您可以将许多自定义程序存储到同一个存档中。您的选择...
[edit] OP 要求澄清上述程序的第一部分 HessDet
,我怀疑这意味着调用 indets
.
如果为 P
分配了一个表达式,那么调用 indets(P,name)
将 return 该表达式中出现的所有名称的集合。基本上,它 return 是表达式的所有不确定子表达式的集合,在 Maple 的技术意义上属于 name
类型。
例如,
P := x*y + sin(a*Pi)*x;
x y + sin(a Pi) x
indets( P,
name );
{Pi, a, x, y}
也许这里不需要常量的名称Pi
。即,
indets( P,
And( name,
Non(constant) ) );
{a, x, y}
也许我们只需要表达式为多项式的非常量名称?即,
indets( P,
And( name,
Non(constant),
satisfies(u->type(p,polynom(anything,u))) ) );
{x, y}
最后的结果是使用以下测试的高级方法:
type(P, polynom(anything, x));
true
type(P, polynom(anything, y));
true
type(P, polynom(anything, a));
false
这里的一个核心问题是 OP 没有提到自定义过程要处理哪种多项式。所以我猜测了一些防御性编码,希望以后不会出现意外。原始问题指出输入可能是“多项式”,但我们没有被告知可能存在什么样的系数。
也许系数将永远是真实的、精确的或数字的。也许自定义过程在未提供时应该抛出错误。问题中没有提到这些细节。
我是 Maple 的新手,我正在寻找一种简单的方法来自动执行某些任务。特别是,我正在寻找一种方法来定义自动执行某些步骤的自定义“操作”。 作为示例,我想定义一种快速方法来计算多项式的 Hessian 矩阵的行列式。目前我这样做的方法是打开 Maple,创建一个新的工作表而不是执行以下命令:
p := (x, y) -> x^2*y + 3*x^3 + y^3
with(VectorCalculus):
h := Hessian(p(x, y), [x, y])
Determinant(h)
我想做的是直接用
之类的东西计算 hessian 行列式HessDet(p)
其中 HessDet
是执行上述操作的自定义命令。如何在 Maple 中实现这样的目标?
首先要注意的是:分配给 p
的值是一个 过程,它可以 return 一个多项式表达式,但它本身不是一个多项式。重要的是不要混淆表达式和过程。这样做是新用户出现问题的常见原因。
能够四处乱扔 p(x,y)
可能在视觉上令人赏心悦目,但它在这里没有什么编程目的。事实上,过程 p
的形式参数恰好被称为 x
和 y
,以及你使用参数 x
调用过程 p
和y
,实际上只是另一个常见的混淆来源。不要仅仅为了以这种方式调用它们而创建过程。
此外,您的调用 p(x,y)
让您的代码片段“知道”过程 p
需要多少参数看起来很神奇。所以让你的候选人 HessDet
接受 p
作为程序已经是一团糟了。
因此,让我们保持直截了当,通过编写 HessDet
来接受多项式而不是过程。我们可以通过编程确定 type
polynom
.
restart;
HessDet:=proc(p::algebraic)
local H,vars;
vars:=indets(p,
And(name,Non(constant),
satisfies(u->type(p,polynom(anything,u)))));
H:=VectorCalculus:-Hessian(p,[vars[]]);
LinearAlgebra:-Determinant(H);
end proc:
下面是一些使用示例,
P := x^2*y + 3*x^3 + y^3;
HessDet(P);
p := (x, y) -> x^2*y + 3*x^3 + y^3;
HessDet(p(x,y));
HessDet(x^3-x^2+4*x);
HessDet(s^2*t + 3*s^3 + t^3);
HessDet(s[r]^2*t[r] + 3*s[r]^3 + t[r]^3);
您可能还想知道如何跨会话重复使用此自定义过程,而不必每次都输入它。两种合理的方式是:
- 将
HessDet
的(上述)明文定义放在个人 initialization file. 中
- Create a (.mla) Maple Library Archive file, then Save your
HessDet
to that, and then augment the Library search path 在你的初始化文件中。
看起来 2) 比较费力,但是重复只需要保存步骤,并且您可以将许多自定义程序存储到同一个存档中。您的选择...
[edit] OP 要求澄清上述程序的第一部分 HessDet
,我怀疑这意味着调用 indets
.
如果为 P
分配了一个表达式,那么调用 indets(P,name)
将 return 该表达式中出现的所有名称的集合。基本上,它 return 是表达式的所有不确定子表达式的集合,在 Maple 的技术意义上属于 name
类型。
例如,
P := x*y + sin(a*Pi)*x;
x y + sin(a Pi) x
indets( P,
name );
{Pi, a, x, y}
也许这里不需要常量的名称Pi
。即,
indets( P,
And( name,
Non(constant) ) );
{a, x, y}
也许我们只需要表达式为多项式的非常量名称?即,
indets( P,
And( name,
Non(constant),
satisfies(u->type(p,polynom(anything,u))) ) );
{x, y}
最后的结果是使用以下测试的高级方法:
type(P, polynom(anything, x));
true
type(P, polynom(anything, y));
true
type(P, polynom(anything, a));
false
这里的一个核心问题是 OP 没有提到自定义过程要处理哪种多项式。所以我猜测了一些防御性编码,希望以后不会出现意外。原始问题指出输入可能是“多项式”,但我们没有被告知可能存在什么样的系数。
也许系数将永远是真实的、精确的或数字的。也许自定义过程在未提供时应该抛出错误。问题中没有提到这些细节。