How to define custom functions in Maple?

Viewed 162

I'm new to Maple and I'm looking for a simple way to automate some tasks. In particular, I'm looking for a way to define custom "action" that perform some steps automatically. As as an example I would like to define a quick way to compute the determinant of the Hessian of a polynomial. Currently the way I do this is opening Maple, create a new worksheet than performing the following commands:

p := (x, y) -> x^2*y + 3*x^3 + y^3

with(VectorCalculus):
h := Hessian(p(x, y), [x, y])
Determinant(h)

What I would like to do is to compute the hessian determinant directly with something like

HessDet(p)

where HessDet would be a custom command that performs the operations above. How does one achieve something like this in Maple?

1 Answers

First things first: The value assigned to your p is a procedure which can return a polynomial expression, but not itself a polynomial. It's important not to muddle expressions and procedures. Doing so is a common cause of problems for new users.

Being able to throw around p(x,y) may be visually pleasing to your eye, but it serves little programmatic purpose here. The fact that the formal parameters of procedure p happen to be called x and y, along with the fact that you called procedure p with arguments x and y, is actually just another common source of confusion. Don't create procedures merely to call them in this way.

Also, your call p(x,y) makes it look magic that your code snippet "knows" how many arguments would be required by procedure p. So it's already a muddle to have your candidate HessDet accept p as a procedure.

So instead let's keep it straightforward, by writing HessDet to accept a polynomial rather than a procedure. We can programmatically ascertain the names in which this expression of of 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:

Now some examples of using it,

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);

You might also wonder how you could re-use this custom procedure across sessions, without having to type it in each time. Two reasonable ways are:

  1. Put the (above) defining plaintext definition of HessDet inside a personal initialization file.
  2. Create a (.mla) Maple Library Archive file, then Save your HessDet to that, and then augment the Library search path in your initialization file.

It might look like 2) is more effort, but only the Save step is needed for repeats, and you can store many custom procedures to the same archive. Your choice...

[edit] The OP has asked for clarification of the first part of the above procedure HessDet, which I suspect means the call to indets.

If P is assigned an expression then then the call indets(P,name) will return a set of all the names present in that expression. Basically, it returns the set of all indeterminate subexpressions of the expression which are of type name in Maple's technical sense.

For example,

P := x*y + sin(a*Pi)*x;

         x y + sin(a Pi) x

indets( P,
        name );

           {Pi, a, x, y}

Perhaps the name of the constant Pi is not wanted here. Ie,

indets( P,
        And( name,
             Non(constant) ) );

             {a, x, y}

Perhaps we want only the non-constant names in which the expression is a polynomial? Ie,

indets( P,
        And( name,
             Non(constant),
             satisfies(u->type(p,polynom(anything,u))) ) );

              {x, y}

That last result is an advanced way of using the following tests:

type(P, polynom(anything, x));

               true

type(P, polynom(anything, y));

               true

type(P, polynom(anything, a));

               false

A central issue here is that the OP made no mention of what kind of polynomials are to be handled by the custom procedure. So I guessed with some defensive coding, in hope of less surprises later on. The original Question states that the input could be a "polynomial", but we weren't told what kind of coefficients there might be.

Perhaps the coefficients will always be real and exact or numeric. Perhaps the custon procedure should throw an error when not supplied such. These details weren't mentioned in the Question.

Related