# G.3 Vector and Matrix Manipulation

danger

This Reference Manual output has not been verified, and may contain omissions or errors. Report any problems on the tracking issue

1/2

Types and operations for the manipulation of real vectors and matrices are provided in Generic_Real_Arrays, which is defined in G.3.1. Types and operations for the manipulation of complex vectors and matrices are provided in Generic_Complex_Arrays, which is defined in G.3.2. Both of these library units are generic children of the predefined package Numerics (see A.5). Nongeneric equivalents of these packages for each of the predefined floating point types are also provided as children of Numerics.

1.a/2
discussion
Vector and matrix manipulation is defined in the Numerics Annex, rather than in the core, because it is considered to be a specialized need of (some) numeric applications.
1.b/2
note
These packages provide facilities that are similar to and replace those found in ISO/IEC 13813:1998 Information technology — Programming languages — Generic packages of real and complex type declarations and basic operations for Ada (including vector and matrix types). (The other facilities provided by that Standard were already provided in Ada 95.) In addition to the main facilities of that Standard, these packages also include subprograms for the solution of linear equations, matrix inversion, determinants, and the determination of the eigenvalues and eigenvectors of real symmetric matrices and Hermitian matrices.

1.c/3
note
This subclause It just provides an introduction to the following subclauses.

## G.3.1 Real Vectors and Matrices​

#### Static Semantics​

1/2

The generic library package Numerics.Generic_Real_Arrays has the following declaration:

2/5
``````generic
type Real is digits <>;
with  Pure, Nonblocking is
3/2-- Types
4/2type Real_Vector is array (Integer range <>) of Real'Base;
type Real_Matrix is array (Integer range <>, Integer range <>)
of Real'Base;
5/2-- Subprograms for Real_Vector types
6/2-- Real_Vector arithmetic operations
7/2function "+"   (Right : Real_Vector)       return Real_Vector;
function "-"   (Right : Real_Vector)       return Real_Vector;
function "abs" (Right : Real_Vector)       return Real_Vector;
8/2function "+"   (Left, Right : Real_Vector) return Real_Vector;
function "-"   (Left, Right : Real_Vector) return Real_Vector;
9/2function "*"   (Left, Right : Real_Vector) return Real'Base;
10/2function "abs" (Right : Real_Vector)       return Real'Base;
11/2-- Real_Vector scaling operations
12/2function "*" (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;
13/2-- Other Real_Vector operations
14/2function Unit_Vector (Index : Integer;
Order : Positive;
First : Integer := 1) return Real_Vector;
15/2-- Subprograms for Real_Matrix types
16/2-- Real_Matrix arithmetic operations
17/2function "+"       (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;
18/2function "+" (Left, Right : Real_Matrix) return Real_Matrix;
function "-" (Left, Right : Real_Matrix) return Real_Matrix;
function "*" (Left, Right : Real_Matrix) return Real_Matrix;
19/2function "*" (Left, Right : Real_Vector) return Real_Matrix;
20/2function "*" (Left : Real_Vector; Right : Real_Matrix)
return Real_Vector;
function "*" (Left : Real_Matrix; Right : Real_Vector)
return Real_Vector;
21/2-- Real_Matrix scaling operations
22/2function "*" (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;
23/2-- Real_Matrix inversion and related operations
24/2function 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;
25/2-- Eigenvalues and vectors of a real symmetric matrix
26/2function Eigenvalues (A : Real_Matrix) return Real_Vector;
27/2procedure Eigensystem (A       : in  Real_Matrix;
Values  : out Real_Vector;
Vectors : out Real_Matrix);
28/2-- Other Real_Matrix operations
29/2function Unit_Matrix (Order            : Positive;
First_1, First_2 : Integer := 1)
return Real_Matrix;
``````
31/2

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.

31.a/2
reason
The nongeneric equivalents are provided to allow the programmer to construct simple mathematical applications without being required to understand and use generics, and to be consistent with other Numerics packages.
32/2

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.

33/2

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.

34/2

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.

35/2
``function "+"   (Right : Real_Vector) return Real_Vector;function "-"   (Right : Real_Vector) return Real_Vector;function "abs" (Right : Real_Vector) return Real_Vector;``
36/2

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.

37/2
``function "+" (Left, Right : Real_Vector) return Real_Vector;function "-" (Left, Right : Real_Vector) return Real_Vector;``
38/2

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.

39/2
``function "*" (Left, Right : Real_Vector) return Real'Base;``
40/2

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.

41/2
``function "abs" (Right : Real_Vector) return Real'Base;``
42/2

This operation returns the L2-norm of Right (the square root of the inner product of the vector with itself).

42.a/2
discussion
Normalization of vectors is a frequent enough operation that it is useful to provide the norm as a basic operation. Furthermore, implementing the norm is not entirely straightforward, because the inner product might overflow while the final norm does not. An implementation cannot merely return Sqrt (X * X), it has to cope with a possible overflow of the inner product.
42.b/2
implementation note
While the definition is given in terms of an inner product, the norm doesn't “involve an inner product” in the technical sense. The reason is that it has accuracy requirements substantially different from those applicable to inner products; and that cancellations cannot occur, because all the terms are positive, so there is no possibility of intermediate overflow.
43/2
``function "*" (Left : Real'Base; Right : Real_Vector) return Real_Vector;``
44/2

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.

45/2
``function "*" (Left : Real_Vector; Right : Real'Base) return Real_Vector;function "/" (Left : Real_Vector; Right : Real'Base) return Real_Vector;``
46/2

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.

47/2
``function Unit_Vector (Index : Integer;                      Order : Positive;                      First : Integer := 1) return Real_Vector;``
48/2

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.

49/2
``function "+"   (Right : Real_Matrix) return Real_Matrix;function "-"   (Right : Real_Matrix) return Real_Matrix;function "abs" (Right : Real_Matrix) return Real_Matrix;``
50/2

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.

51/2
``function Transpose (X : Real_Matrix) return Real_Matrix;``
52/2

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.

53/2
``function "+" (Left, Right : Real_Matrix) return Real_Matrix;function "-" (Left, Right : Real_Matrix) return Real_Matrix;``
54/2

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).

55/2
``function "*" (Left, Right : Real_Matrix) return Real_Matrix;``
56/2

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.

57/2
``function "*" (Left, Right : Real_Vector) return Real_Matrix;``
58/2

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.

59/2
``function "*" (Left : Real_Vector; Right : Real_Matrix) return Real_Vector;``
60/2

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.

61/2
``function "*" (Left : Real_Matrix; Right : Real_Vector) return Real_Vector;``
62/2

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.

63/2
``function "*" (Left : Real'Base; Right : Real_Matrix) return Real_Matrix;``
64/2

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.

65/2
``function "*" (Left : Real_Matrix; Right : Real'Base) return Real_Matrix;function "/" (Left : Real_Matrix; Right : Real'Base) return Real_Matrix;``
66/2

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.

67/2
``function Solve (A : Real_Matrix; X : Real_Vector) return Real_Vector;``
68/2

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.

68.a/2
The text says that Y is such that “X is (nearly) equal to A * Y” rather than “X is equal to A * Y” because rounding errors may mean that there is no value of Y such that X is exactly equal to A * Y. On the other hand it does not mean that any old rough value will do. The algorithm given under should be followed.
68.b/2
The requirement to raise Constraint_Error if the matrix is ill-conditioned is really a reflection of what will happen if the matrix is ill-conditioned. See . We do not make any attempt to define ill-conditioned formally.
68.c/2
note
These remarks apply to all versions of Solve and Inverse.
69/2
``function Solve (A, X : Real_Matrix) return Real_Matrix;``
70/2

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.

71/2
``function Inverse (A : Real_Matrix) return Real_Matrix;``
72/2

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.

73/2
``function Determinant (A : Real_Matrix) return Real'Base;``
74/2

This function returns the determinant of the matrix A. Constraint_Error is raised if A'Length(1) is not equal to A'Length(2).

75/2
``function Eigenvalues(A : Real_Matrix) return Real_Vector;``
76/2

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.

77/2
``procedure Eigensystem(A       : in  Real_Matrix;                      Values  : out Real_Vector;                      Vectors : out Real_Matrix);``
78/3

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.

78.a/3
ramification
There is no requirement on the absolute direction of the returned eigenvectors. Thus they might be multiplied by -1. It is only the ratios of the components that matter. This is standard practice.
79/2
``function Unit_Matrix (Order            : Positive;                      First_1, First_2 : Integer := 1) return Real_Matrix;``
80/2

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​

81/2

Accuracy requirements for the subprograms Solve, Inverse, Determinant, Eigenvalues and Eigensystem are implementation defined.

81.a/2
implementation defined
The accuracy requirements for the subprograms Solve, Inverse, Determinant, Eigenvalues and Eigensystem for type Real_Matrix.
82/2

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).

83/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

84/2

g = X'Length * Real'Machine_Radix**(1 – Real'Model_Mantissa)

85/2

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.

85.a/2
reason
This is simply the combination of the error on the inner product with the error on Sqrt. A first order computation would lead to 2.0 * Real'Model_Epsilon above, but we are adding an extra Real'Model_Epsilon to account for higher order effects.

#### Documentation Requirements​

86/2

Implementations shall document any techniques used to reduce cancellation errors such as extended precision arithmetic.

86.a/2
note
Documentation Requirement: Any techniques used to reduce cancellation errors in Numerics.Generic_Real_Arrays shall be documented.
86.b/2
implementation note
The above accuracy requirement is met by the canonical implementation of the inner product by multiplication and addition using the corresponding operations of type Real'Base and performing the cumulative addition using ascending indices. Note however, that some hardware provides special operations for the computation of the inner product and although these may be fast they may not meet the accuracy requirement specified. See Accuracy and Stability of Numerical Algorithms By N J Higham (ISBN 0-89871-355-2), Section 3.1.
86.c/3
note
Note moreover that the componentwise accuracy requirements are not met by subcubic methods for matrix multiplication such as that devised by Strassen. These methods, which are typically used for the fast multiplication of very large matrices (that is, order more than a few thousands), have normwise accuracy properties. If it is desired to use such methods, then distinct subprograms should be provided (perhaps in a child package). See Section 22.2.2 in the above reference.

#### Implementation Permissions​

87/5

The nongeneric equivalent packages can be actual instantiations of the generic package for the appropriate predefined type, though that is not required.

88/3

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.

88.a/2
Solve and Inverse for Numerics.Generic_Real_Arrays should be implemented using established techniques such as LU decomposition and the result should be refined by an iteration on the residuals.
89/2

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.

89.a/2
discussion
There isn't any advice for the implementation to document with this paragraph.
90/2

The test that a matrix is symmetric should be performed by using the equality operator to compare the relevant components.

90.a/2
The equality operator should be used to test that a matrix in Numerics.Generic_Real_Arrays is symmetric.
91/3

An implementation should minimize the circumstances under which the algorithm used for Eigenvalues and Eigensystem fails to converge.

91.a.1/3
An implementation should minimize the circumstances under which the algorithm used for Numerics.Generic_Real_Arrays.Eigenvalues and Numerics.Generic_Real_Arrays.Eigensystem fails to converge.
91.a/3
implementation note
J. H. Wilkinson is the acknowledged expert in this area. See for example Wilkinson, J. H., and Reinsch, C. , Linear Algebra , vol II of Handbook for Automatic Computation, Springer-Verlag, or Wilkinson, J. H., The Algebraic Eigenvalue Problem, Oxford University Press.

91.b/2
note
The package Numerics.Generic_Real_Arrays and its nongeneric equivalents are new.

#### Wording Changes from Ada 2005​

91.c/3
correction
Corrected various accuracy and definition issues.

## G.3.2 Complex Vectors and Matrices​

#### Static Semantics​

1/2

The generic library package Numerics.Generic_Complex_Arrays has the following declaration:

2/5
``````with Ada.Numerics.Generic_Real_Arrays, Ada.Numerics.Generic_Complex_Types;
generic
with package Real_Arrays   is new
use Real_Arrays;
with package Complex_Types is new
use Complex_Types;
with  Pure, Nonblocking is
3/2-- Types
4/2type Complex_Vector is array (Integer range <>) of Complex;
type Complex_Matrix is array (Integer range <>,
Integer range <>) of Complex;
5/2-- Subprograms for Complex_Vector types
6/2-- Complex_Vector selection, conversion and composition operations
7/2function Re (X : Complex_Vector) return Real_Vector;
function Im (X : Complex_Vector) return Real_Vector;
8/2procedure Set_Re (X  : in out Complex_Vector;
Re : in     Real_Vector);
procedure Set_Im (X  : in out Complex_Vector;
Im : in     Real_Vector);
9/2function Compose_From_Cartesian (Re     : Real_Vector)
return Complex_Vector;
function Compose_From_Cartesian (Re, Im : Real_Vector)
return Complex_Vector;
10/2function Modulus  (X     : Complex_Vector) return Real_Vector;
function "abs"    (Right : Complex_Vector) return Real_Vector
renames Modulus;
function Argument (X     : Complex_Vector) return Real_Vector;
function Argument (X     : Complex_Vector;
Cycle : Real'Base)      return Real_Vector;
11/2function Compose_From_Polar (Modulus, Argument : Real_Vector)
return Complex_Vector;
function Compose_From_Polar (Modulus, Argument : Real_Vector;
Cycle             : Real'Base)
return Complex_Vector;
12/2-- Complex_Vector arithmetic operations
13/2function "+"       (Right  : Complex_Vector) return Complex_Vector;
function "-"       (Right  : Complex_Vector) return Complex_Vector;
function Conjugate (X      : Complex_Vector) return Complex_Vector;
14/2function "+"  (Left, Right : Complex_Vector) return Complex_Vector;
function "-"  (Left, Right : Complex_Vector) return Complex_Vector;
15/2function "*"  (Left, Right : Complex_Vector) return Complex;
16/3function "abs"     (Right : Complex_Vector) return Real'Base;
17/2-- Mixed Real_Vector and Complex_Vector arithmetic operations
18/2function "+" (Left  : Real_Vector;
Right : Complex_Vector) return Complex_Vector;
function "+" (Left  : Complex_Vector;
Right : Real_Vector)    return Complex_Vector;
function "-" (Left  : Real_Vector;
Right : Complex_Vector) return Complex_Vector;
function "-" (Left  : Complex_Vector;
Right : Real_Vector)    return Complex_Vector;
19/2function "*" (Left  : Real_Vector;    Right : Complex_Vector)
return Complex;
function "*" (Left  : Complex_Vector; Right : Real_Vector)
return Complex;
20/2-- Complex_Vector scaling operations
21/2function "*" (Left  : Complex;
Right : Complex_Vector) return Complex_Vector;
function "*" (Left  : Complex_Vector;
Right : Complex)        return Complex_Vector;
function "/" (Left  : Complex_Vector;
Right : Complex)        return Complex_Vector;
22/2function "*" (Left  : Real'Base;
Right : Complex_Vector) return Complex_Vector;
function "*" (Left  : Complex_Vector;
Right : Real'Base)      return Complex_Vector;
function "/" (Left  : Complex_Vector;
Right : Real'Base)      return Complex_Vector;
23/2-- Other Complex_Vector operations
24/2function Unit_Vector (Index : Integer;
Order : Positive;
First : Integer := 1) return Complex_Vector;
25/2-- Subprograms for Complex_Matrix types
26/2-- Complex_Matrix selection, conversion and composition operations
27/2function Re (X : Complex_Matrix) return Real_Matrix;
function Im (X : Complex_Matrix) return Real_Matrix;
28/2procedure Set_Re (X  : in out Complex_Matrix;
Re : in     Real_Matrix);
procedure Set_Im (X  : in out Complex_Matrix;
Im : in     Real_Matrix);
29/2function Compose_From_Cartesian (Re     : Real_Matrix)
return Complex_Matrix;
function Compose_From_Cartesian (Re, Im : Real_Matrix)
return Complex_Matrix;
30/2function Modulus  (X     : Complex_Matrix) return Real_Matrix;
function "abs"    (Right : Complex_Matrix) return Real_Matrix
renames Modulus;
31/2function Argument (X     : Complex_Matrix) return Real_Matrix;
function Argument (X     : Complex_Matrix;
Cycle : Real'Base)      return Real_Matrix;
32/2function Compose_From_Polar (Modulus, Argument : Real_Matrix)
return Complex_Matrix;
function Compose_From_Polar (Modulus, Argument : Real_Matrix;
Cycle             : Real'Base)
return Complex_Matrix;
33/2-- Complex_Matrix arithmetic operations
34/2function "+"       (Right : Complex_Matrix) return Complex_Matrix;
function "-"       (Right : Complex_Matrix) return Complex_Matrix;
function Conjugate (X     : Complex_Matrix) return Complex_Matrix;
function Transpose (X     : Complex_Matrix) return Complex_Matrix;
35/2function "+" (Left, Right : Complex_Matrix) return Complex_Matrix;
function "-" (Left, Right : Complex_Matrix) return Complex_Matrix;
function "*" (Left, Right : Complex_Matrix) return Complex_Matrix;
36/2function "*" (Left, Right : Complex_Vector) return Complex_Matrix;
37/2function "*" (Left  : Complex_Vector;
Right : Complex_Matrix) return Complex_Vector;
function "*" (Left  : Complex_Matrix;
Right : Complex_Vector) return Complex_Vector;
38/2-- Mixed Real_Matrix and Complex_Matrix arithmetic operations
39/2function "+" (Left  : Real_Matrix;
Right : Complex_Matrix) return Complex_Matrix;
function "+" (Left  : Complex_Matrix;
Right : Real_Matrix)    return Complex_Matrix;
function "-" (Left  : Real_Matrix;
Right : Complex_Matrix) return Complex_Matrix;
function "-" (Left  : Complex_Matrix;
Right : Real_Matrix)    return Complex_Matrix;
function "*" (Left  : Real_Matrix;
Right : Complex_Matrix) return Complex_Matrix;
function "*" (Left  : Complex_Matrix;
Right : Real_Matrix)    return Complex_Matrix;
40/2function "*" (Left  : Real_Vector;
Right : Complex_Vector) return Complex_Matrix;
function "*" (Left  : Complex_Vector;
Right : Real_Vector)    return Complex_Matrix;
41/2function "*" (Left  : Real_Vector;
Right : Complex_Matrix) return Complex_Vector;
function "*" (Left  : Complex_Vector;
Right : Real_Matrix)    return Complex_Vector;
function "*" (Left  : Real_Matrix;
Right : Complex_Vector) return Complex_Vector;
function "*" (Left  : Complex_Matrix;
Right : Real_Vector)    return Complex_Vector;
42/2-- Complex_Matrix scaling operations
43/2function "*" (Left  : Complex;
Right : Complex_Matrix) return Complex_Matrix;
function "*" (Left  : Complex_Matrix;
Right : Complex)        return Complex_Matrix;
function "/" (Left  : Complex_Matrix;
Right : Complex)        return Complex_Matrix;
44/2function "*" (Left  : Real'Base;
Right : Complex_Matrix) return Complex_Matrix;
function "*" (Left  : Complex_Matrix;
Right : Real'Base)      return Complex_Matrix;
function "/" (Left  : Complex_Matrix;
Right : Real'Base)      return Complex_Matrix;
45/2-- Complex_Matrix inversion and related operations
46/2function Solve (A : Complex_Matrix; X : Complex_Vector)
return Complex_Vector;
function Solve (A, X : Complex_Matrix) return Complex_Matrix;
function Inverse (A : Complex_Matrix) return Complex_Matrix;
function Determinant (A : Complex_Matrix) return Complex;
47/2-- Eigenvalues and vectors of a Hermitian matrix
48/2function Eigenvalues(A : Complex_Matrix) return Real_Vector;
49/2procedure Eigensystem(A       : in  Complex_Matrix;
Values  : out Real_Vector;
Vectors : out Complex_Matrix);
50/2-- Other Complex_Matrix operations
51/2function Unit_Matrix (Order            : Positive;
First_1, First_2 : Integer := 1)
return Complex_Matrix;
``````
53/2

The library package Numerics.Complex_Arrays is declared pure and defines the same types and subprograms as Numerics.Generic_Complex_Arrays, except that the predefined type Float is systematically substituted for Real'Base, and the Real_Vector and Real_Matrix types exported by Numerics.Real_Arrays are systematically substituted for Real_Vector and Real_Matrix, and the Complex type exported by Numerics.Complex_Types is systematically substituted for Complex, throughout. Nongeneric equivalents for each of the other predefined floating point types are defined similarly, with the names Numerics.Short_Complex_Arrays, Numerics.Long_Complex_Arrays, etc.

54/2

Two types are defined and exported by Numerics.Generic_Complex_Arrays. The composite type Complex_Vector is provided to represent a vector with components of type Complex; it is defined as an unconstrained one-dimensional array with an index of type Integer. The composite type Complex_Matrix is provided to represent a matrix with components of type Complex; it is defined as an unconstrained, two-dimensional array with indices of type Integer.

55/2

The effect of the various subprograms is as described below. In many cases they are described in terms of corresponding scalar operations in Numerics.Generic_Complex_Types. Any exception raised by those operations is propagated by the array subprogram. Moreover, any constraints on the parameters and the accuracy of the result for each individual component are as defined for the scalar operation.

56/2

In the case of those operations which are defined to involve an inner product, Constraint_Error may be raised if an intermediate result has a component outside the range of Real'Base even though the final mathematical result would not.

56.a/3
discussion
An inner product never involves implicit complex conjugation. If the product of a vector with the conjugate of another (or the same) vector is required, then this has to be stated explicitly by writing for example X * Conjugate(Y). This mimics the usual mathematical notation.
57/2
``function Re (X : Complex_Vector) return Real_Vector;function Im (X : Complex_Vector) return Real_Vector;``
58/2

Each function returns a vector of the specified Cartesian components of X. The index range of the result is X'Range.

59/2
``procedure Set_Re (X  : in out Complex_Vector; Re : in Real_Vector);procedure Set_Im (X  : in out Complex_Vector; Im : in Real_Vector);``
60/2

Each procedure replaces the specified (Cartesian) component of each of the components of X by the value of the matching component of Re or Im; the other (Cartesian) component of each of the components is unchanged. Constraint_Error is raised if X'Length is not equal to Re'Length or Im'Length.

61/2
``function Compose_From_Cartesian (Re     : Real_Vector)   return Complex_Vector;function Compose_From_Cartesian (Re, Im : Real_Vector)   return Complex_Vector;``
62/2

Each function constructs a vector of Complex results (in Cartesian representation) formed from given vectors of Cartesian components; when only the real components are given, imaginary components of zero are assumed. The index range of the result is Re'Range. Constraint_Error is raised if Re'Length is not equal to Im'Length.

63/2
``function Modulus  (X     : Complex_Vector) return Real_Vector;function "abs"    (Right : Complex_Vector) return Real_Vector                                              renames Modulus;function Argument (X     : Complex_Vector) return Real_Vector;function Argument (X     : Complex_Vector;                   Cycle : Real'Base)      return Real_Vector;``
64/2

Each function calculates and returns a vector of the specified polar components of X or Right using the corresponding function in numerics.generic_complex_types. The index range of the result is X'Range or Right'Range.

65/2
``function Compose_From_Polar (Modulus, Argument : Real_Vector)   return Complex_Vector;function Compose_From_Polar (Modulus, Argument : Real_Vector;                             Cycle             : Real'Base)   return Complex_Vector;``
66/2

Each function constructs a vector of Complex results (in Cartesian representation) formed from given vectors of polar components using the corresponding function in numerics.generic_complex_types on matching components of Modulus and Argument. The index range of the result is Modulus'Range. Constraint_Error is raised if Modulus'Length is not equal to Argument'Length.

67/2
``function "+" (Right : Complex_Vector) return Complex_Vector;function "-" (Right : Complex_Vector) return Complex_Vector;``
68/2

Each operation returns the result of applying the corresponding operation in numerics.generic_complex_types to each component of Right. The index range of the result is Right'Range.

69/2
``function Conjugate (X : Complex_Vector) return Complex_Vector;``
70/2

This function returns the result of applying the appropriate function Conjugate in numerics.generic_complex_types to each component of X. The index range of the result is X'Range.

71/2
``function "+" (Left, Right : Complex_Vector) return Complex_Vector;function "-" (Left, Right : Complex_Vector) return Complex_Vector;``
72/2

Each operation returns the result of applying the corresponding operation in numerics.generic_complex_types 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.

73/2
``function "*" (Left, Right : Complex_Vector) return Complex;``
74/2

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.

75/3
``function "abs" (Right : Complex_Vector) return Real'Base;``
76/2

This operation returns the Hermitian L2-norm of Right (the square root of the inner product of the vector with its conjugate).

76.a/2
implementation note
While the definition is given in terms of an inner product, the norm doesn't “involve an inner product” in the technical sense. The reason is that it has accuracy requirements substantially different from those applicable to inner products; and that cancellations cannot occur, because all the terms are positive, so there is no possibility of intermediate overflow.
77/2
``function "+" (Left  : Real_Vector;              Right : Complex_Vector) return Complex_Vector;function "+" (Left  : Complex_Vector;              Right : Real_Vector)    return Complex_Vector;function "-" (Left  : Real_Vector;              Right : Complex_Vector) return Complex_Vector;function "-" (Left  : Complex_Vector;              Right : Real_Vector)    return Complex_Vector;``
78/2

Each operation returns the result of applying the corresponding operation in numerics.generic_complex_types 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.

79/2
``function "*" (Left : Real_Vector;    Right : Complex_Vector) return Complex;function "*" (Left : Complex_Vector; Right : Real_Vector)    return Complex;``
80/2

Each operation returns the inner product of Left and Right. Constraint_Error is raised if Left'Length is not equal to Right'Length. These operations involve an inner product.

81/2
``function "*" (Left : Complex; Right : Complex_Vector) return Complex_Vector;``
82/2

This operation returns the result of multiplying each component of Right by the complex number Left using the appropriate operation "*" in numerics.generic_complex_types. The index range of the result is Right'Range.

83/2
``function "*" (Left : Complex_Vector; Right : Complex) return Complex_Vector;function "/" (Left : Complex_Vector; Right : Complex) return Complex_Vector;``
84/2

Each operation returns the result of applying the corresponding operation in numerics.generic_complex_types to each component of the vector Left and the complex number Right. The index range of the result is Left'Range.

85/2
``function "*" (Left : Real'Base;              Right : Complex_Vector) return Complex_Vector;``
86/2

This operation returns the result of multiplying each component of Right by the real number Left using the appropriate operation "*" in numerics.generic_complex_types. The index range of the result is Right'Range.

87/2
``function "*" (Left : Complex_Vector;              Right : Real'Base) return Complex_Vector;function "/" (Left : Complex_Vector;              Right : Real'Base) return Complex_Vector;``
88/2

Each operation returns the result of applying the corresponding operation in numerics.generic_complex_types to each component of the vector Left and the real number Right. The index range of the result is Left'Range.

89/2
``function Unit_Vector (Index : Integer;                      Order : Positive;                      First : Integer := 1) return Complex_Vector;``
90/2

This function returns a unit vector with Order components and a lower bound of First. All components are set to (0.0, 0.0) except for the Index component which is set to (1.0, 0.0). Constraint_Error is raised if Index < First, Index > First + Order – 1, or if First + Order – 1 > Integer'Last.

91/2
``function Re (X : Complex_Matrix) return Real_Matrix;function Im (X : Complex_Matrix) return Real_Matrix;``
92/2

Each function returns a matrix of the specified Cartesian components of X. The index ranges of the result are those of X.

93/2
``procedure Set_Re (X : in out Complex_Matrix; Re : in Real_Matrix);procedure Set_Im (X : in out Complex_Matrix; Im : in Real_Matrix);``
94/2

Each procedure replaces the specified (Cartesian) component of each of the components of X by the value of the matching component of Re or Im; the other (Cartesian) component of each of the components is unchanged. Constraint_Error is raised if X'Length(1) is not equal to Re'Length(1) or Im'Length(1) or if X'Length(2) is not equal to Re'Length(2) or Im'Length(2).

95/2
``function Compose_From_Cartesian (Re     : Real_Matrix)   return Complex_Matrix;function Compose_From_Cartesian (Re, Im : Real_Matrix)   return Complex_Matrix;``
96/2

Each function constructs a matrix of Complex results (in Cartesian representation) formed from given matrices of Cartesian components; when only the real components are given, imaginary components of zero are assumed. The index ranges of the result are those of Re. Constraint_Error is raised if Re'Length(1) is not equal to Im'Length(1) or Re'Length(2) is not equal to Im'Length(2).

97/2
``function Modulus  (X     : Complex_Matrix) return Real_Matrix;function "abs"    (Right : Complex_Matrix) return Real_Matrix                                              renames Modulus;function Argument (X     : Complex_Matrix) return Real_Matrix;function Argument (X     : Complex_Matrix;                   Cycle : Real'Base)      return Real_Matrix;``
98/2

Each function calculates and returns a matrix of the specified polar components of X or Right using the corresponding function in numerics.generic_complex_types. The index ranges of the result are those of X or Right.

99/2
``function Compose_From_Polar (Modulus, Argument : Real_Matrix)   return Complex_Matrix;function Compose_From_Polar (Modulus, Argument : Real_Matrix;                             Cycle             : Real'Base)   return Complex_Matrix;``
100/2

Each function constructs a matrix of Complex results (in Cartesian representation) formed from given matrices of polar components using the corresponding function in numerics.generic_complex_types on matching components of Modulus and Argument. The index ranges of the result are those of Modulus. Constraint_Error is raised if Modulus'Length(1) is not equal to Argument'Length(1) or Modulus'Length(2) is not equal to Argument'Length(2).

101/2
``function "+" (Right : Complex_Matrix) return Complex_Matrix;function "-" (Right : Complex_Matrix) return Complex_Matrix;``
102/2

Each operation returns the result of applying the corresponding operation in numerics.generic_complex_types to each component of Right. The index ranges of the result are those of Right.

103/2
``function Conjugate (X : Complex_Matrix) return Complex_Matrix;``
104/2

This function returns the result of applying the appropriate function Conjugate in numerics.generic_complex_types to each component of X. The index ranges of the result are those of X.

105/2
``function Transpose (X : Complex_Matrix) return Complex_Matrix;``
106/2

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.

107/2
``function "+" (Left, Right : Complex_Matrix) return Complex_Matrix;function "-" (Left, Right : Complex_Matrix) return Complex_Matrix;``
108/2

Each operation returns the result of applying the corresponding operation in numerics.generic_complex_types 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).

109/2
``function "*" (Left, Right : Complex_Matrix) return Complex_Matrix;``
110/2

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.

111/2
``function "*" (Left, Right : Complex_Vector) return Complex_Matrix;``
112/2

This operation returns the outer product of a (column) vector Left by a (row) vector Right using the appropriate operation "*" in numerics.generic_complex_types for computing the individual components. The first and second index ranges of the result are Left'Range and Right'Range respectively.

113/2
``function "*" (Left  : Complex_Vector;              Right : Complex_Matrix) return Complex_Vector;``
114/2

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.

115/2
``function "*" (Left  : Complex_Matrix;              Right : Complex_Vector) return Complex_Vector;``
116/2

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.

117/2
``function "+" (Left  : Real_Matrix;              Right : Complex_Matrix) return Complex_Matrix;function "+" (Left  : Complex_Matrix;              Right : Real_Matrix)    return Complex_Matrix;function "-" (Left  : Real_Matrix;              Right : Complex_Matrix) return Complex_Matrix;function "-" (Left  : Complex_Matrix;              Right : Real_Matrix)    return Complex_Matrix;``
118/2

Each operation returns the result of applying the corresponding operation in numerics.generic_complex_types 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).

119/2
``function "*" (Left  : Real_Matrix;              Right : Complex_Matrix) return Complex_Matrix;function "*" (Left  : Complex_Matrix;              Right : Real_Matrix)    return Complex_Matrix;``
120/2

Each 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). These operations involve inner products.

121/2
``function "*" (Left  : Real_Vector;              Right : Complex_Vector) return Complex_Matrix;function "*" (Left  : Complex_Vector;              Right : Real_Vector)    return Complex_Matrix;``
122/2

Each operation returns the outer product of a (column) vector Left by a (row) vector Right using the appropriate operation "*" in numerics.generic_complex_types for computing the individual components. The first and second index ranges of the result are Left'Range and Right'Range respectively.

123/2
``function "*" (Left  : Real_Vector;              Right : Complex_Matrix) return Complex_Vector;function "*" (Left  : Complex_Vector;              Right : Real_Matrix)    return Complex_Vector;``
124/2

Each 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). These operations involve inner products.

125/2
``function "*" (Left  : Real_Matrix;              Right : Complex_Vector) return Complex_Vector;function "*" (Left  : Complex_Matrix;              Right : Real_Vector)    return Complex_Vector;``
126/2

Each 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. These operations involve inner products.

127/2
``function "*" (Left : Complex; Right : Complex_Matrix) return Complex_Matrix;``
128/2

This operation returns the result of multiplying each component of Right by the complex number Left using the appropriate operation "*" in numerics.generic_complex_types. The index ranges of the result are those of Right.

129/2
``function "*" (Left : Complex_Matrix; Right : Complex) return Complex_Matrix;function "/" (Left : Complex_Matrix; Right : Complex) return Complex_Matrix;``
130/2

Each operation returns the result of applying the corresponding operation in numerics.generic_complex_types to each component of the matrix Left and the complex number Right. The index ranges of the result are those of Left.

131/2
``function "*" (Left : Real'Base;              Right : Complex_Matrix) return Complex_Matrix;``
132/2

This operation returns the result of multiplying each component of Right by the real number Left using the appropriate operation "*" in numerics.generic_complex_types. The index ranges of the result are those of Right.

133/2
``function "*" (Left : Complex_Matrix;              Right : Real'Base) return Complex_Matrix;function "/" (Left : Complex_Matrix;              Right : Real'Base) return Complex_Matrix;``
134/2

Each operation returns the result of applying the corresponding operation in numerics.generic_complex_types to each component of the matrix Left and the real number Right. The index ranges of the result are those of Left.

135/2
``function Solve (A : Complex_Matrix; X : Complex_Vector) return Complex_Vector;``
136/2

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.

136.a/2
The text says that Y is such that “X is (nearly) equal to A * Y” rather than “X is equal to A * Y” because rounding errors may mean that there is no value of Y such that X is exactly equal to A * Y. On the other hand it does not mean that any old rough value will do. The algorithm given under should be followed.
136.b/2
The requirement to raise Constraint_Error if the matrix is ill-conditioned is really a reflection of what will happen if the matrix is ill-conditioned. See . We do not make any attempt to define ill-conditioned formally.
136.c/2
note
These remarks apply to all versions of Solve and Inverse.
137/2
``function Solve (A, X : Complex_Matrix) return Complex_Matrix;``
138/2

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.

139/2
``function Inverse (A : Complex_Matrix) return Complex_Matrix;``
140/2

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.

141/2
``function Determinant (A : Complex_Matrix) return Complex;``
142/2

This function returns the determinant of the matrix A. Constraint_Error is raised if A'Length(1) is not equal to A'Length(2).

143/2
``function Eigenvalues(A : Complex_Matrix) return Real_Vector;``
144/2

This function returns the eigenvalues of the Hermitian 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 Hermitian.

144.a/2
discussion
A Hermitian matrix is one whose transpose is equal to its complex conjugate. The eigenvalues of a Hermitian matrix are always real. We only support this case because algorithms for solving the general case are inherently unstable.
145/2
``procedure Eigensystem(A       : in  Complex_Matrix;                      Values  :  out Real_Vector;                      Vectors :  out Complex_Matrix);``
146/3

This procedure computes both the eigenvalues and eigenvectors of the Hermitian 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 mutually 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 Hermitian. Constraint_Error is also raised in implementation-defined circumstances if the algorithm used does not converge quickly enough.

146.a/3
ramification
There is no requirement on the absolute direction of the returned eigenvectors. Thus they might be multiplied by any complex number whose modulus is 1. It is only the ratios of the components that matter. This is standard practice.
147/2
``function Unit_Matrix (Order            : Positive;                      First_1, First_2 : Integer := 1)                                         return Complex_Matrix;``
148/2

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, 0.0) except for the main diagonal, whose components are set to (1.0, 0.0). Constraint_Error is raised if First_1 + Order – 1 > Integer'Last or First_2 + Order – 1 > Integer'Last.

#### Implementation Requirements​

149/2

Accuracy requirements for the subprograms Solve, Inverse, Determinant, Eigenvalues and Eigensystem are implementation defined.

149.a/2
implementation defined
The accuracy requirements for the subprograms Solve, Inverse, Determinant, Eigenvalues and Eigensystem for type Complex_Matrix.
150/2

For operations not involving an inner product, the accuracy requirements are those of the corresponding operations of the type Real'Base and Complex in both the strict mode and the relaxed mode (see G.2).

151/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

152/2

g = X'Length * Real'Machine_Radix**(1 – Real'Model_Mantissa)
for mixed complex and real operands

153/2

g = sqrt(2.0) * X'Length * Real'Machine_Radix**(1 – Real'Model_Mantissa)
for two complex operands

154/2

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 has the definition appropriate for two complex operands.

#### Documentation Requirements​

155/2

Implementations shall document any techniques used to reduce cancellation errors such as extended precision arithmetic.

155.a/2
note
Documentation Requirement: Any techniques used to reduce cancellation errors in Numerics.Generic_Complex_Arrays shall be documented.
155.b/2
implementation note
The above accuracy requirement is met by the canonical implementation of the inner product by multiplication and addition using the corresponding operations of type Complex and performing the cumulative addition using ascending indices. Note however, that some hardware provides special operations for the computation of the inner product and although these may be fast they may not meet the accuracy requirement specified. See Accuracy and Stability of Numerical Algorithms by N J Higham (ISBN 0-89871-355-2), Sections 3.1 and 3.6.

#### Implementation Permissions​

156/5

The nongeneric equivalent packages can be actual instantiations of the generic package for the appropriate predefined type, though that is not required.

157/5

Although many operations are defined in terms of operations from Numerics.Generic_Complex_Types , they can be implemented by other operations that have the same effect.

158/3

Implementations should implement the Solve and Inverse functions using established techniques. Implementations are recommended to refine the result by performing an iteration on the residuals; if this is done, then it should be documented.

158.a/2
Solve and Inverse for Numerics.Generic_Complex_Arrays should be implemented using established techniques and the result should be refined by an iteration on the residuals.
159/2

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.

159.a/2
discussion
There isn't any advice for the implementation to document with this paragraph.
160/2

The test that a matrix is Hermitian should use the equality operator to compare the real components and negation followed by equality to compare the imaginary components (see G.2.1).

160.a/2
The equality and negation operators should be used to test that a matrix is Hermitian.
160.1/3

An implementation should minimize the circumstances under which the algorithm used for Eigenvalues and Eigensystem fails to converge.

160.a.1/3
An implementation should minimize the circumstances under which the algorithm used for Numerics.Generic_Complex_Arrays.Eigenvalues and Numerics.Generic_Complex_Arrays.Eigensystem fails to converge.
160.b/3
implementation note
J. H. Wilkinson is the acknowledged expert in this area. See for example Wilkinson, J. H., and Reinsch, C. , Linear Algebra , vol II of Handbook for Automatic Computation, Springer-Verlag, or Wilkinson, J. H., The Algebraic Eigenvalue Problem, Oxford University Press.
161/2

Implementations should not perform operations on mixed complex and real operands by first converting the real operand to complex. See G.1.1.

161.a/2