G.3.1 Real Vectors and Matrices
Static Semantics
The generic library 
package Numerics.Generic_Real_Arrays has the following declaration: 
generic
   type Real 
is digits <>;
package Ada.Numerics.Generic_Real_Arrays 
is
   pragma Pure(Generic_Real_Arrays);
 
   -- Types
   type Real_Vector 
is array (Integer 
range <>) 
of Real'Base;
   
type Real_Matrix 
is array (Integer 
range <>, Integer 
range <>)
                                                   
of Real'Base;
 
   -- Subprograms for Real_Vector types
   -- Real_Vector arithmetic operations
   function "+"   (Right : Real_Vector)       return Real_Vector;
   function "-"   (Right : Real_Vector)       return Real_Vector;
   function "abs" (Right : Real_Vector)       return Real_Vector;
   function "+"   (Left, Right : Real_Vector) return Real_Vector;
   function "-"   (Left, Right : Real_Vector) return Real_Vector;
   function "*"   (Left, Right : Real_Vector) return Real'Base;
   function "abs" (Right : Real_Vector)       return Real'Base;
   -- Real_Vector scaling operations
   function "*" (Left : Real'Base;   Right : Real_Vector)
      return Real_Vector;
   function "*" (Left : Real_Vector; Right : Real'Base)
      return Real_Vector;
   function "/" (Left : Real_Vector; Right : Real'Base)
      return Real_Vector;
   -- Other Real_Vector operations
   function Unit_Vector (Index : Integer;
                         Order : Positive;
                         First : Integer := 1) 
return Real_Vector;
 
   -- Subprograms for Real_Matrix types
   -- Real_Matrix arithmetic operations
   function "+"       (Right : Real_Matrix) 
return Real_Matrix;
   
function "-"       (Right : Real_Matrix) 
return Real_Matrix;
   
function "
abs"     (Right : Real_Matrix) 
return Real_Matrix;
   
function Transpose (X     : Real_Matrix) 
return Real_Matrix;
 
   function "+" (Left, Right : Real_Matrix) return Real_Matrix;
   function "-" (Left, Right : Real_Matrix) return Real_Matrix;
   function "*" (Left, Right : Real_Matrix) return Real_Matrix;
   function "*" (Left, Right : Real_Vector) return Real_Matrix;
   function "*" (Left : Real_Vector; Right : Real_Matrix)
      return Real_Vector;
   function "*" (Left : Real_Matrix; Right : Real_Vector)
      return Real_Vector;
   -- Real_Matrix scaling operations
   function "*" (Left : Real'Base;   Right : Real_Matrix)
      return Real_Matrix;
   function "*" (Left : Real_Matrix; Right : Real'Base)
      return Real_Matrix;
   function "/" (Left : Real_Matrix; Right : Real'Base)
      return Real_Matrix;
   -- Real_Matrix inversion and related operations
   function Solve (A : Real_Matrix; X : Real_Vector) 
return Real_Vector;
   
function Solve (A, X : Real_Matrix) 
return Real_Matrix;
   
function Inverse (A : Real_Matrix) 
return Real_Matrix;
   
function Determinant (A : Real_Matrix) 
return Real'Base;
 
   -- Eigenvalues and vectors of a real symmetric matrix
   function Eigenvalues (A : Real_Matrix) 
return Real_Vector;
 
   procedure Eigensystem (A       : 
in  Real_Matrix;
                          Values  : 
out Real_Vector;
                          Vectors : 
out Real_Matrix);
 
   -- Other Real_Matrix operations
   function Unit_Matrix (Order            : Positive;
                         First_1, First_2 : Integer := 1)
                                            
return Real_Matrix;
 
end Ada.Numerics.Generic_Real_Arrays;
 The library package Numerics.Real_Arrays 
is declared pure and defines the same types and subprograms as Numerics.Generic_Real_Arrays, 
except that the predefined type Float is systematically substituted for 
Real'Base throughout. Nongeneric equivalents for each of the other predefined 
floating point types are defined similarly, with the names Numerics.Short_Real_Arrays, 
Numerics.Long_Real_Arrays, etc. 
 
 Two types are defined and exported by Numerics.Generic_Real_Arrays. 
The composite type Real_Vector is provided to represent a vector with 
components of type Real; it is defined as an unconstrained, one-dimensional 
array with an index of type Integer. The composite type Real_Matrix is 
provided to represent a matrix with components of type Real; it is defined 
as an unconstrained, two-dimensional array with indices of type Integer.
 The effect of the various subprograms is as described 
below. In most cases the subprograms are described in terms of corresponding 
scalar operations of the type Real; any exception raised by those operations 
is propagated by the array operation. Moreover, the accuracy of the result 
for each individual component is as defined for the scalar operation 
unless stated otherwise.
 In the case of those operations which are defined 
to 
involve an inner product, Constraint_Error may be raised if 
an intermediate result is outside the range of Real'Base even though 
the mathematical final result would not be.
 
function "+"   (Right : Real_Vector) return Real_Vector;
function "-"   (Right : Real_Vector) return Real_Vector;
function "abs" (Right : Real_Vector) return Real_Vector;
Each operation returns 
the result of applying the corresponding operation of the type Real to 
each component of Right. The index range of the result is Right'Range.
function "+" (Left, Right : Real_Vector) return Real_Vector;
function "-" (Left, Right : Real_Vector) return Real_Vector;
Each operation returns the result of applying 
the corresponding operation of the type Real to each component of Left 
and the matching component of Right. The index range of the result is 
Left'Range. Constraint_Error is raised if Left'Length is not equal to 
Right'Length.
function "*" (Left, Right : Real_Vector) return Real'Base;
This operation returns the inner product of Left 
and Right. Constraint_Error is raised if Left'Length is not equal to 
Right'Length. This operation involves an inner product.
function "abs" (Right : Real_Vector) return Real'Base;
This operation returns the L2-norm of Right (the 
square root of the inner product of the vector with itself).
function "*" (Left : Real'Base; Right : Real_Vector) return Real_Vector;
This operation returns the result of multiplying 
each component of Right by the scalar Left using the "*" operation 
of the type Real. The index range of the result is Right'Range.
function "*" (Left : Real_Vector; Right : Real'Base) return Real_Vector;
function "/" (Left : Real_Vector; Right : Real'Base) return Real_Vector;
Each operation returns the result of applying 
the corresponding operation of the type Real to each component of Left 
and to the scalar Right. The index range of the result is Left'Range.
function Unit_Vector (Index : Integer;
                      Order : Positive;
                      First : Integer := 1) return Real_Vector;
This function returns a 
unit vector 
with Order components and a lower bound of First. All components are 
set to 0.0 except for the Index component which is set to 1.0. Constraint_Error 
is raised if Index < First, Index > First + Order – 1 or 
if First + Order – 1 > Integer'Last.
 
function "+"   (Right : Real_Matrix) return Real_Matrix;
function "-"   (Right : Real_Matrix) return Real_Matrix;
function "abs" (Right : Real_Matrix) return Real_Matrix;
Each operation returns the result of applying 
the corresponding operation of the type Real to each component of Right. 
The index ranges of the result are those of Right.
function Transpose (X : Real_Matrix) return Real_Matrix;
This function returns the transpose of a matrix 
X. The first and second index ranges of the result are X'Range(2) and 
X'Range(1) respectively.
function "+" (Left, Right : Real_Matrix) return Real_Matrix;
function "-" (Left, Right : Real_Matrix) return Real_Matrix;
Each operation returns the result of applying 
the corresponding operation of the type Real to each component of Left 
and the matching component of Right. The index ranges of the result are 
those of Left. Constraint_Error is raised if Left'Length(1) is not equal 
to Right'Length(1) or Left'Length(2) is not equal to Right'Length(2).
function "*" (Left, Right : Real_Matrix) return Real_Matrix;
This operation provides the standard mathematical 
operation for matrix multiplication. The first and second index ranges 
of the result are Left'Range(1) and Right'Range(2) respectively. Constraint_Error 
is raised if Left'Length(2) is not equal to Right'Length(1). This operation 
involves inner products.
function "*" (Left, Right : Real_Vector) return Real_Matrix;
This operation returns the outer product of a 
(column) vector Left by a (row) vector Right using the operation "*" 
of the type Real for computing the individual components. The first and 
second index ranges of the result are Left'Range and Right'Range respectively.
function "*" (Left : Real_Vector; Right : Real_Matrix) return Real_Vector;
This operation provides the standard mathematical 
operation for multiplication of a (row) vector Left by a matrix Right. 
The index range of the (row) vector result is Right'Range(2). Constraint_Error 
is raised if Left'Length is not equal to Right'Length(1). This operation 
involves inner products.
function "*" (Left : Real_Matrix; Right : Real_Vector) return Real_Vector;
This operation provides the standard mathematical 
operation for multiplication of a matrix Left by a (column) vector Right. 
The index range of the (column) vector result is Left'Range(1). Constraint_Error 
is raised if Left'Length(2) is not equal to Right'Length. This operation 
involves inner products.
function "*" (Left : Real'Base; Right : Real_Matrix) return Real_Matrix;
This operation returns the result of multiplying 
each component of Right by the scalar Left using the "*" operation 
of the type Real. The index ranges of the result are those of Right.
function "*" (Left : Real_Matrix; Right : Real'Base) return Real_Matrix;
function "/" (Left : Real_Matrix; Right : Real'Base) return Real_Matrix;
Each operation returns the result of applying 
the corresponding operation of the type Real to each component of Left 
and to the scalar Right. The index ranges of the result are those of 
Left.
function Solve (A : Real_Matrix; X : Real_Vector) return Real_Vector;
This function returns a vector Y such that X is 
(nearly) equal to A * Y. This is the standard mathematical operation 
for solving a single set of linear equations. The index range of the 
result is A'Range(2). Constraint_Error is raised if A'Length(1), A'Length(2), 
and X'Length are not equal. Constraint_Error is raised if the matrix 
A is ill-conditioned.
function Solve (A, X : Real_Matrix) return Real_Matrix;
This function returns a matrix Y such that X is 
(nearly) equal to A * Y. This is the standard mathematical operation 
for solving several sets of linear equations. The index ranges of the 
result are A'Range(2) and X'Range(2). Constraint_Error is raised if A'Length(1), 
A'Length(2), and X'Length(1) are not equal. Constraint_Error is raised 
if the matrix A is ill-conditioned.
function Inverse (A : Real_Matrix) return Real_Matrix;
This function returns a matrix B such that A * 
B is (nearly) equal to the unit matrix. The index ranges of the result 
are A'Range(2) and A'Range(1). Constraint_Error is raised if A'Length(1) 
is not equal to A'Length(2). Constraint_Error is raised if the matrix 
A is ill-conditioned.
function Determinant (A : Real_Matrix) return Real'Base;
This function returns the determinant of the matrix 
A. Constraint_Error is raised if A'Length(1) is not equal to A'Length(2).
function Eigenvalues(A : Real_Matrix) return Real_Vector;
This function returns the eigenvalues of the symmetric 
matrix A as a vector sorted into order with the largest first. Constraint_Error 
is raised if A'Length(1) is not equal to A'Length(2). The index range 
of the result is A'Range(1). Argument_Error is raised if the matrix A 
is not symmetric.
procedure Eigensystem(A       : in  Real_Matrix;
                      Values  : out Real_Vector;
                      Vectors : out Real_Matrix);
This procedure computes both the eigenvalues and 
eigenvectors of the symmetric matrix A. The out parameter Values is the 
same as that obtained by calling the function Eigenvalues. The out parameter 
Vectors is a matrix whose columns are the eigenvectors of the matrix 
A. The order of the columns corresponds to the order of the eigenvalues. 
The eigenvectors are normalized and mutually orthogonal (they are orthonormal), 
including when there are repeated eigenvalues. Constraint_Error is raised 
if A'Length(1) is not equal to A'Length(2), or if Values'Range is not 
equal to A'Range(1), or if the index ranges of the parameter Vectors 
are not equal to those of A. Argument_Error is raised if the matrix A 
is not symmetric. Constraint_Error is also raised in implementation-defined 
circumstances if the algorithm used does not converge quickly enough.
function Unit_Matrix (Order            : Positive;
                      First_1, First_2 : Integer := 1) return Real_Matrix;
This function returns a square 
unit matrix 
with Order**2 components and lower bounds of First_1 and First_2 (for 
the first and second index ranges respectively). All components are set 
to 0.0 except for the main diagonal, whose components are set to 1.0. 
Constraint_Error is raised if First_1 + Order – 1 > Integer'Last 
or First_2 + Order – 1 > Integer'Last.
 
Implementation Requirements
 Accuracy requirements for the subprograms Solve, 
Inverse, Determinant, Eigenvalues and Eigensystem are implementation 
defined. 
 For operations not involving an inner product, the 
accuracy requirements are those of the corresponding operations of the 
type Real in both the strict mode and the relaxed mode (see 
G.2).
 
 For operations involving 
an inner product, no requirements are specified in the relaxed mode. 
In the strict mode the modulus of the absolute error of the inner product 
X*Y shall not exceed g*abs(X)*abs(Y) 
where g is defined as 
g = X'Length * Real'Machine_Radix**(1 – Real'Model_Mantissa)
 For the L2-norm, no accuracy requirements are specified 
in the relaxed mode. In the strict mode the relative error on the norm 
shall not exceed g / 2.0 + 3.0 * Real'Model_Epsilon where g 
is defined as above.
Documentation Requirements
 Implementations shall document any techniques used 
to reduce cancellation errors such as extended precision arithmetic. 
Implementation Permissions
 The nongeneric equivalent packages may, but need 
not, be actual instantiations of the generic package for the appropriate 
predefined type.
Implementation Advice
 Implementations should implement the Solve and Inverse 
functions using established techniques such as LU decomposition with 
row interchanges followed by back and forward substitution. Implementations 
are recommended to refine the result by performing an iteration on the 
residuals; if this is done, then it should be documented. 
 It is not the intention that any special provision 
should be made to determine whether a matrix is ill-conditioned or not. 
The naturally occurring overflow (including division by zero) which will 
result from executing these functions with an ill-conditioned matrix 
and thus raise Constraint_Error is sufficient. 
 The test that a matrix is symmetric should be performed 
by using the equality operator to compare the relevant components. 
 An implementation should minimize the circumstances 
under which the algorithm used for Eigenvalues and Eigensystem fails 
to converge. 
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe