Linear Algebra Functions with NAG Support
Many LinearAlgebra package functions use NAG routines to carry out computations. The use of the NAG routines allows computations to be carried out very quickly.
This worksheet will guide you through techniques to maximize the power and speed of these routines.
restart
withLinearAlgebra:
In order to see when NAG routines are called, set the infolevel for LinearAlgebra to 1.
infolevelLinearAlgebra:=1
Determining Whether Hardware Floats are Used
When Maple uses hardware floats, it can execute more quickly than when software floats or symbolics are used. By understanding how Maple decides which algorithm to use, you can ensure that the most efficient approach is used for your data.
Types of Algorithms and Precision Available
Hardware Floats
Advantage
- very fast: compiled (NAG) code is used with hardware floats to carry out algorithms
Drawback
- precision is predetermined
Software Floats
Advantages
- fast: compiled (NAG) code is used with Maple software floats to carry out algorithms
- arbitrary precision available (precision determined by setting of the Digits environment variable)
- not as fast as hardware floats
Symbolic
- symbolic entries handled
- exact answers often possible
- relatively slow: interpreted (Maple) code is used to carry out algorithms
How Maple Decides at What Precision to Operate
Maple first determines whether or not floats and/or symbolics are present. To do so, it first checks the datatype of the Matrix, then (if necessary) checks the individual entries. In a large Matrix, this second step can take a non-trivial amount of time. For efficient code, ensure your Matrices have an appropriate datatype.
If there are only numerics, at least one float, and the UseHardwareFloats environment variable is set to deduced (the default), hardware floats are used.
If there are only numerics, at least one float, and the UseHardwareFloats environment variable is set to false, software floats are used.
If there are any non-numeric entries in a Matrix, a symbolic routine is used. Note that non-numeric entries include values such as 2 and π.
If there are no floats, a symbolic routine is used.
Note: A "float" is any entry with a decimal in it, so "2" is not a float, but "2." is a float. In the example that follows, a symbolic (exact) algorithm is used to invert Matrix M1, while a floating point routine is used to invert Matrix M2. In this case, hardware floats are used since UseHardwareFloats=deduced.
M1:=1|2,4|5;M2:=1|2.,4|5
M1:=1245
M2:=12.45
M1−1
−532343−13
M2−1
MatrixInverse: calling external function
MatrixInverse: NAG hw_f07adf MatrixInverse: NAG hw_f07ajf
−1.666666666666666520.6666666666666666301.33333333333333326−0.333333333333333315
With UseHardwareFloats=false, software floats are used to invert M2.
UseHardwareFloats:=false
MatrixInverse: NAG sw_f07adf MatrixInverse: NAG sw_f07ajf
−1.6666666660.66666666651.333333333−0.3333333332
UseHardwareFloats:=deduced
Setting the Hardware Flag
By default, the UseHardwareFloats environment variable is set to deduced to maximize the speed of computations. To turn off hardware computations and use software floats instead, set UseHardwareFloats to false.
Execute one of the following two command groups depending on whether you want to experiment with hardware floats or software floats.
If you have infolevel[LinearAlgebra] set to at least 1, you will notice that the external routines have names prefixed with "hw_" when hardware floats are being used, and with "sw_" when software floats are being used.
Controlling What Information is Returned
Some functions return more than one piece of information, or give you a choice of formats in which to obtain the results. By using the output= option, you can specify what information you would like a routine to return.
For example, when using LUDecomposition, you can specify which components of the decomposition you want returned. The examples below demonstrate the LUDecomposition command, but this functionality is also available in others, such as BidiagonalForm, QRDecomposition, and HessenbergForm.
For this example, we also demonstrate the use of software floats.
Set up a sample Matrix:
M:=14.|−8|1,−11|−4|18,3|12|19
M:=14.−81−11−41831219
The default output is to return 'P' (permutation), 'L' (lower triangular), and 'U' (upper triangular) components:
LUDecomposition⁡M;LUDecomposition⁡M,output='P','L','U'
LUDecomposition: calling external function LUDecomposition: NAG sw_f07adf
100001010,1.00.0.0.21428571431.00.−0.7857142857−0.75000000061.0,14.−8.1.0.13.7142857118.785714290.0.32.87500002
The upper triangular component can also be automatically factored into a square upper triangular Matrix ('U1') and the row-reduced echelon form of M:
LUDecomposition⁡M,output='P','L','U1','R'
LUDecomposition: calling external function LUDecomposition: NAG sw_f07adf RowOperation: calling external function RowOperation: External sw_MulRowRR RowOperation: calling external function RowOperation: External sw_AddRowRR RowOperation: calling external function RowOperation: External sw_AddRowRR RowOperation: calling external function RowOperation: External sw_MulRowRR RowOperation: calling external function
RowOperation: External sw_AddRowRR RowOperation: calling external function RowOperation: External sw_MulRowRR
100001010,1.00.0.0.21428571431.00.−0.7857142857−0.75000000061.0,14.−8.1.013.7142857118.785714290032.87500002,1.0.0.0.1.0.0.0.1.
Usually you will want the whole decomposition, but if you only want part of it, you can ask for just the part you want:
LUDecomposition⁡M,output='U'
LUDecomposition: calling external function
LUDecomposition: NAG sw_f07adf
14.−8.1.0.13.7142857118.785714290.0.32.87500002
You can also request 'NAG' format. This special format is particularly space efficient: the permutation Matrix is compressed into a pivot vector, and the L and U Matrices are combined into a single Matrix. This format is understood by other commands, such as LinearSolve (note that the order of the vector and matrix must be preserved when passing to other routines).
ipiv,N:=LUDecomposition⁡M,output='NAG';LinearSolve⁡ipiv,N,Vector⁡29,−21,−40,datatype=float
ipiv,N:=133,14.−8.1.0.214285714313.7142857118.78571429−0.7857142857−0.750000000632.87500002
LinearSolve: using method LU LinearSolve: calling external function LinearSolve: NAG sw_f07aef
0.9999999993−2.000000001−1.000000000
Controlling the Format of the Output
Functions that return Matrices allow you to specify Matrix characteristics via the outputoptions option. This may involve making a copy of the Matrix that was originally produced by the function. (To determine if such a copy has been made, set infolevel[ LinearAlgebra ] := 2.)
The following examples create a random Matrix with a particular shape and an updatable scalar Matrix.
M1:=RandomMatrix⁡4,density=0.5,outputoptions=shape='symmetric',storage='triangularupper'
M1:=0069−40−2−93069−930−18−40−180
M2:=ScalarMatrix⁡3.2,4,outputoptions=shape='rectangular';M23,1≔173;M2
M2:=3.200003.200003.200003.2
M23,1:=173
3.200003.20017303.200003.2
Minimizing Storage Costs
There are two main ways to minimize storage costs:
- use the 'inplace' feature
- create your Matrices with the right properties so that copies do not have to be made
Note that the first of these requires you to use the named version of the function (for example, Multiply instead of the '.' operator). The second applies to both named functions and to functions called via operators.
Using the 'inplace' Feature
The inplace feature allows you to store the output of a function directly on top of one of the inputs. In order for feature to be included in a function, two requirements must be met:
(1) the output must be the same shape and size as one of the inputs, and
(2) it must be possible to code the algorithm truly in-place; it must not just copy the result into the input object when it is done.
Some examples will clarify the above points.
(1) Multiply can be done inplace when the output object is the same size as the first input object ; this is the case whenever the second Matrix is square. (Strictly speaking, the Multiply function is not quite carried out in place -- at any given time, there is a copy of one row of the Matrix in memory -- but this overhead is small compared to creating an entire new Matrix).
M1:=RandomMatrix⁡2,3;M2≔RandomMatrix3,3;Multiply⁡M1,M2,'inplace';M1
M1:=10−9−22−16−5045
M2:=314312−5025−2−809450
2520−1863−962−159622922158
Note that Multiply cannot be done in place when the output and input are not the same size:
M1:=RandomMatrix⁡3,3;M2≔RandomMatrix⁡3,2;Multiply⁡M1,M2,'inplace'
M1:=−4486−4824207765−619
M2:=60−25−9551−2076
Error, (in LinearAlgebra:-MatrixMatrixMultiply) the second factor must be square to compute the product in place
(2) CrossProduct takes two 3-element Vectors as inputs, and returns a 3-element Vector. It looks like a promising candidate for an inplace operation. However, as can be seen below, overwriting any of the input values would obliterate data needed to compute the output values for other locations.
V1≔Vectorrow'a','b','c';V2≔Vectorrow'x','y','z';CrossProduct⁡V1,V2
V1:=abc
V2:=xyz
b⁢z−c⁢yc⁢x−a⁢za⁢y−b⁢x
Avoiding Copies
By setting the infolevel for LinearAlgebra to 2, you can see when avoidable copies are made.
infolevelLinearAlgebra:=2
The NAG algorithms require data to be in a floating-point (either hardware or software) Matrix. They work fastest when data is in a hardware float Matrix. Compare the following: notice that the M1 Matrix has to be copied, while the M2 Matrix can be used directly.
M1:=−21.|−50|−79,0|30|−71,0|0|28;M2:=Matrix⁡M1,datatype='float';BackwardSubstitute⁡M1,1,2,3;BackwardSubstitute⁡M2,1,2,3
M1:=−21.−50−79030−710028
M2:=−21.−50.−79.0.30.−71.0.0.28.
BackwardSubstitute: calling external function BackwardSubstitute: copying lefthand Matrix, to obtain datatype float[8] BackwardSubstitute: NAG hw_f07tef
−1.213151927437641660.3202380952380952110.107142857142857136
BackwardSubstitute: calling external function BackwardSubstitute: NAG hw_f07tef
Choosing a Method
Many LinearAlgebra commands can be carried out in more than one way. Maple looks at the type of data it has received to determine the "best" algorithm to use.
For example, LUDecomposition has a number of techniques at its disposal, including Gaussian elimination, fraction-free Gaussian elimination, and Cholesky. If you know which algorithm is most appropriate for your Matrix, you can save the LUDecomposition function the task of having to decide which one to use. Simply specify the desired method with the method= option.
Note: When you specify a particular method, no other method will be tried, even if problems are encountered. For example, consider the following Matrix which is symmetric. It is not positive-definite, but it has mistakenly been given that attribute. When you call LinearSolve without specifying a method, it first tries the Cholesky method. When that fails, it tries LU and gets the right answer. When the Cholesky method is explicitly requested, it simply returns with an error.
M:=Matrix⁡−11.,−88,98,−88,−54,−12,98,−12,55,shape='symmetric',attributes=positive_definite
M:=−11.−8898−88−54−1298−1255
LinearSolve⁡M,1,2,3;LinearSolve⁡M,1,2,3,method='Cholesky'
LinearSolve: using method Cholesky LinearSolve: calling external function LinearSolve: NAG hw_f07gdf
Warning, Matrix is not positive-definite
LinearSolve: external call unsuccessful LUDecomposition: calling external function LUDecomposition: NAG hw_f07adf MatrixVectorMultiply: calling external function MatrixVectorMultiply: NAG hw_f06paf BackwardSubstitute: calling external function BackwardSubstitute: NAG hw_f07tef
0.0696501620067423582−0.128836927929467076−0.0976683456693519248
Error, (in LinearAlgebra:-LA_Main:-LinearSolve) Matrix is not positive-definite
LUDecomposition - Some Routine-Specific Hints
Some variants of the LUDecomposition function can be carried out inplace (reducing storage costs) when the input Matrix has a float datatype.
When you request NAG format output with the inplace option, the LU component is returned in the input Matrix. The pivot vector is returned separately.
M:=Matrix⁡14,−8,1,−11,−4,18,3,12,19,datatype=float;LUDecomposition⁡M,output='NAG',inplace;ipiv:=%1;M
M:=14.−8.1.−11.−4.18.3.12.19.
LUDecomposition: calling external function LUDecomposition: NAG hw_f07adf
133,14.−8.1.0.21428571428571427413.714285714285713618.7857142857142848−0.785714285714285698−0.75000000000000000032.8750000000000000
ipiv:=133
14.−8.1.0.21428571428571427413.714285714285713618.7857142857142848−0.785714285714285698−0.75000000000000000032.8750000000000000
When you request the Cholesky method with the inplace option, the L component is returned in the original Matrix. For efficiency, the upper triangle is not necessarily replaced with zeroes.
M:=Matrix⁡25,15,5,−5,15,10,1,−8,5,1,30,54,−5,−8,54,276,datatype=float;LUDecomposition⁡M,method='Cholesky',inplace;M
M:=25.15.5.−5.15.10.1.−8.5.1.30.54.−5.−8.54.276.
LUDecomposition: calling external function Transpose: calling external function HermitianTranspose: hw_MatTransRR MatrixAdd: calling external function MatrixAdd: NAG hw_f06ecf MatrixNorm: calling external function MatrixNorm: NAG hw_f06raf CholeskyDecomposition: NAG hw_f07fdf
5.15.5.−5.3.1.1.−8.1.−2.5.54.−1.−5.9.13.
LinearSolve - Some Routine-Specific Hints
The LinearSolve command allows you to solve a linear system with one or more right-hand sides. Each time you execute the LinearSolve command, it has to factor the input Matrix. You can save time by providing all the right-hand sides in a single command so that it only has to factor the Matrix once:
M:=Matrix⁡1.,3,4,5,datatype=float;V1≔1.,2;V2:=7,−11;V3:=−34,−67
M:=1.3.4.5.
V1:=1.2
V2:=7−11
V3:=−34−67
LinearSolve⁡M,V1|V2|V3
LinearSolve: using method LU LinearSolve: calling external function LinearSolve: NAG hw_f07adf LinearSolve: NAG hw_f07aef
0.142857142857142877−9.71428571428571352−4.428571428571428820.2857142857142856985.57142857142857118−9.85714285714285588
If you do not have all the right-hand sides in advance, use LUDecomposition to factor the input Matrix, and pass this factorization (in a list) to LinearSolve. You can use any decomposition, but for maximum speed with floating-point data, use 'NAG' format. To minimize storage costs, use the inplace option (if available), as described in the previous section.
M:=Matrix⁡1.,3,4,5,datatype=float;ipiv,M:=LUDecomposition⁡M,output='NAG',inplace;LinearSolveipiv,M,V1|V2|V3
ipiv,M:=22,4.5.0.2500000000000000001.75000000000000000
LinearSolve: using method LU LinearSolve: calling external function LinearSolve: NAG hw_f07aef
Note: Using 'NAG' format with non-numeric entries saves storage, but it has an execution time comparable to other formats.
Return to Index for Example Worksheets
Download Help Document