Maple users often want to write a derivative evaluated at a point using Leibniz notation, as a matter of presentation, with appropriate variables and coordinates. For instance:

Now, Maple uses the D operator for evaluating derivatives at a point, but this can be a little clunky:

p := D[1,2,2,3](f)(a,b,c);
q := convert( p, Diff );

u := D[1,2,2,3](f)(5,10,15);
v := convert( u, Diff );

How can we tell Maple, programmatically, to print this in a nicer way? We amended the print command (see below) to do this. For example:

print( D[1,2,2,3](f)(a,b,c), [x,y,z] );
print( D[1,2,2,3](f)(5,10,15), [x,y,z] );

print( 'D(sin)(Pi/6)', theta );

Here's the definition of the custom version of print:

# Type to check if an expression is a derivative using 'D', e.g. D(f)(a) and D[1,2](f)(a,b).
TypeTools:-AddType(
'Dexpr',
proc( f )
if op( [0,0], f ) <> D and op( [0,0,0], f ) <> D then
return false;
end if;
if not type( op( [0,1], f ), 'name' ) or not type( { op( f ) }, 'set(algebraic)' ) then
return false;
end if;
if op( [0,0,0], f ) = D and not type( { op( [0,0,..], f ) }, 'set(posint)' ) then
return false;
end if;
return true;
end proc
):
# Create a local version of 'print', which will print expressions like D[1,2](f)(a,b) in a custom way,
# but otherwise print in the usual fashion.
local print := proc()
local A, B, f, g, L, X, Y, Z;
# Check that a valid expression involving 'D' is passed, along with a variable name or list of variable names.
if ( _npassed < 2 ) or ( not _passed[1] :: 'Dexpr' ) or ( not passed[2] :: 'Or'('name','list'('name')) ) then
return :-print( _passed );
end if;
# Extract important variables from the input.
g := _passed[1]; # expression
X := _passed[2]; # variable name(s)
f := op( [0,1], g ); # function name in expression
A := op( g ); # point(s) of evaluation
# Check that the number of variables is the same as the number of evaluation points.
if nops( X ) <> nops( [A] ) then
return :-print( _passed );
end if;
# The differential operator.
L := op( [0,0], g );
# Find the variable (univariate) or indices (multivariate) for the derivative(s).
B := `if`( L = D, X, [ op( L ) ] );
# Variable name(s) as expression sequence.
Y := op( X );
# Check that the point(s) of evaluation is/are distinct from the variable name(s).
if numelems( {Y} intersect {A} ) > 0 then
return :-print( _passed );
end if;
# Find the expression sequence of the variable names.
Z := `if`( L = D, X, X[B] );
return print( Eval( Diff( f(Y), Z ), (Y) = (A) ) );
end proc:

Do you use Leibniz Notation often? Or do you have an alternate method? We’d love to hear from you!