如何在 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 的形式参数恰好被称为 xy,以及你使用参数 x 调用过程 py,实际上只是另一个常见的混淆来源。不要仅仅为了以这种方式调用它们而创建过程。

此外,您的调用 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);

您可能还想知道如何跨会话重复使用此自定义过程,而不必每次都输入它。两种合理的方式是:

  1. HessDet 的(上述)明文定义放在​​个人 initialization file.
  2. 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 没有提到自定义过程要处理哪种多项式。所以我猜测了一些防御性编码,希望以后不会出现意外。原始问题指出输入可能是“多项式”,但我们没有被告知可能存在什么样的系数。

也许系数将永远是真实的、精确的或数字的。也许自定义过程在未提供时应该抛出错误。问题中没有提到这些细节。