Programming - Maple Help

Programming Facilities Changes in Maple 10

 Maple 10 includes the following changes to programming facilities.

Procedures

Parameter Processing

 • Parameter processing for procedures has been extended to use optional parameters and keyword parameters.  An optional parameter has an associated default value, which is used when no value is passed for that parameter in a call to the procedure.  Keyword parameters are also optional, but they are not positional.  A keyword argument is passed as an equation of the form $\mathrm{param}=\mathrm{value}$ where value is the value of the parameter $\mathrm{param}$.
 • The expression defining a default value can refer to other parameter names present in the procedure definition.  Similarly, the optional type expression attached to a parameter name can refer to other parameter names; and procedure return-types can also depend upon procedure parameters.

End-of-Parameters Marker

 • An end-of-parameters marker, $, has also been introduced. If this marker is present at the end of the list of parameters in the procedure definition, then the passing of any additional arguments raises an exception. For more information see procedure/$.

Name Bindings

 • Procedures now accept an optional declaration of the form uses packagename.  The uses statement allows you to specify name bindings that affect the entire body of a procedure.  In the following example, the short names can be used when calling functions within the LinearAlgebra Package.
 > proc(x)     uses LinearAlgebra;     return 2 * Determinant(x) end proc;
 ${\mathbf{proc}}\left({x}\right)\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{return}}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{2}{*}{\mathrm{LinearAlgebra}}{:-}{\mathrm{Determinant}}{}\left({x}\right)\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{end proc}}$ (1)
 • The uses declaration can also be specified for modules.
 > module()     uses LinearAlgebra;     export f;     f := proc(A) Transpose(A) end proc; end module;
 > print(%:-f);

Numeric Code Translator

 • Some numeric Maple procedures can be compiled to native code. For more information, see the Compile help page.
 > mvmul := proc( n :: posint,     p :: Vector( datatype = float[ 8 ] ),     m :: Matrix( datatype = float[ 8 ] ),     v :: Vector( datatype = float[ 8 ] ) )     local    i :: integer, j :: integer, s :: float;     for i from 1 to n do         s := 0.0;         for j from 1 to n do             s := s + m[ i, j ] * v[ j ]         end do;         p[ i ] := s     end do end proc:
 > m := Matrix( 2, 2, [ [ 1, 2 ], [ 3, 4 ] ], 'datatype' = 'float'[ 8 ] ):
 > v := Vector( 2, [ 5, 6 ], 'datatype' = 'float'[ 8 ] ):
 > m . v;
 $\left[\begin{array}{c}{17.}\\ {39.}\end{array}\right]$ (2)
 > p := Vector( 2, 'datatype' = 'float'[ 8 ] ):
 > cmvmul := Compiler[Compile]( mvmul ):
 > cmvmul( 2, p, m, v ): p;
 $\left[\begin{array}{c}{17.}\\ {39.}\end{array}\right]$ (3)
 > N := 500:
 > m := LinearAlgebra[RandomMatrix]( N, N, 'outputoptions' = [ 'datatype' = 'float'[ 8 ] ] ):
 > v := LinearAlgebra[RandomVector]( N, 'outputoptions' = [ 'datatype' = 'float'[ 8 ] ] ):
 > p := Vector( N, 'datatype' = 'float'[ 8 ] ):
 > time( mvmul( N, p, m, v ) );
 ${0.350}$ (4)
 The compiled code executes much faster.
 > time( cmvmul( N, p, m, v ) );
 ${0.003}$ (5)
 Hardware integer arithmetic is also supported.
 > p := proc( n :: integer, a :: Array( datatype = integer[ 4 ] ) ) :: integer;     local    i :: integer, s :: integer;     s := 0;     for i from 1 to n do         s := s + a[ i ]     end do;     s end proc:
 > cp := Compiler[Compile]( p ):
 > a := Array( [ 1, 2, 3, 4, 5 ], datatype = integer[ 4 ] ):
 > cp( 5, a );
 ${15}$ (6)
 > r := rand( -2^10 .. 2^10 ):
 > N := 10^6:
 > a := Array( 1..N, r, datatype = integer[ 4 ] ):
 A call to p is fully interpreted.
 > time( p( N, a ) );
 ${0.378}$ (7)
 A call to cp executes native code.
 > time( cp( N, a ) );
 ${0.010}$ (8)

Number of Results

 • A new special name, _nresults is set to the number of names on the left-hand side of an assignment.  This can be used inside a procedure to return a different number of results depending on how many values are expected to be assigned.
 Define a procedure using _nresults.
 > lu := proc(M)     if _nresults = 3 then       LinearAlgebra[LUDecomposition]( M );     elif _nresults = 2 then       LinearAlgebra[LUDecomposition]( M, output='NAG' );     elif _nresults = 1 or _nresults = undefined then       LinearAlgebra[LUDecomposition]( M, output='L' );     else       error "too many results"     end if;   end:
 Sample input:
 > A := <<0,-2,0>|<1,3,0>|<1,1,0>>;
 ${A}{≔}\left[\begin{array}{ccc}{0}& {1}& {1}\\ {-2}& {3}& {1}\\ {0}& {0}& {0}\end{array}\right]$ (9)
 A call using multiple assignment: the procedure determines three arguments must be returned.
 > P, L, U := lu(A);
 ${P}{,}{L}{,}{U}{≔}\left[\begin{array}{ccc}{0}& {1}& {0}\\ {1}& {0}& {0}\\ {0}& {0}& {1}\end{array}\right]{,}\left[\begin{array}{ccc}{1}& {0}& {0}\\ {0}& {1}& {0}\\ {0}& {0}& {1}\end{array}\right]{,}\left[\begin{array}{ccc}{-2}& {3}& {1}\\ {0}& {1}& {1}\\ {0}& {0}& {0}\end{array}\right]$ (10)
 Same procedure, same arguments, but now two (2) results instead of three (3):
 > L, U := lu(A);
 ${L}{,}{U}{≔}\left[\begin{array}{c}{2}\\ {2}\\ {3}\end{array}\right]{,}\left[\begin{array}{ccc}{-2}& {3}& {1}\\ {0}& {1}& {1}\\ {0}& {0}& {0}\end{array}\right]$ (11)
 Following the code above, one argument is returned when the call is not part of an assignment statement, or is nested inside an expression.
 > L := lu(A);
 ${L}{≔}\left[\begin{array}{ccc}{1}& {0}& {0}\\ {0}& {1}& {0}\\ {0}& {0}& {1}\end{array}\right]$ (12)
 > L := f(lu(A));
 ${L}{≔}{f}{}\left(\left[\begin{array}{ccc}{1}& {0}& {0}\\ {0}& {1}& {0}\\ {0}& {0}& {1}\end{array}\right]\right)$ (13)
 > L := 2*lu(A);
 ${L}{≔}\left[\begin{array}{ccc}{2}& {0}& {0}\\ {0}& {2}& {0}\\ {0}& {0}& {2}\end{array}\right]$ (14)

Saving External Function Definitions

 • Procedures returned by the define_external command contain runtime information about the link to their corresponding external library. In previous releases, this information could not be saved. Maple now saves the original parameter sequence passed to define_external so that it can regenerate the external procedure in the next Maple session. For more information, see define_external/save.