Programming Facilities Changes in Maple 10
Maple 10 includes the following changes to programming facilities.
Procedures
Name Bindings
Numeric Code Translator
Number of Results
Saving External Function Definitions
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 param=value where value is the value of the parameter 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.
For more information, see paramprocessing.
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/$.
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;
procxreturn2*LinearAlgebra:-Determinant⁡xend proc
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);
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;
17.39.
p := Vector( 2, 'datatype' = 'float'[ 8 ] ):
cmvmul := Compiler[Compile]( mvmul ):
cmvmul( 2, p, m, v ): p;
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.205
The compiled code executes much faster.
time( cmvmul( N, p, m, v ) );
0.002
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
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.283
A call to cp executes native code.
time( cp( N, a ) );
0.003
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≔011−231000
A call using multiple assignment: the procedure determines three arguments must be returned.
P, L, U := lu(A);
P,L,U≔010100001,100010001,−231011000
Same procedure, same arguments, but now two (2) results instead of three (3):
L, U := lu(A);
L,U≔223,−231011000
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≔100010001
L := f(lu(A));
L≔f⁡100010001
L := 2*lu(A);
L≔200020002
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.
See Also
Index of New Maple 10 Features
Language and System Updates in Maple 10
Download Help Document