Skip to content

Numerics#

The library package Numerics is the parent of several child units that provide facilities for mathematical computation. One child, the generic package Generic_Elementary_Functions, is defined in A.5.1, together with nongeneric equivalents; two others, the package Float_Random and the generic package Discrete_Random, are defined in A.5.2. Additional (optional) children are defined in Annex G, “Numerics”.

package Ada.Numerics
   with Pure is

   Argument_Error: exception;

   Pi: constant := 3.14159_26535_89793_23846_26433_83279_50288_41971_69399_37511;
   π : constant := Pi;
   e : constant := 2.71828_18284_59045_23536_02874_71352_66249_77572_47093_69996;
end Ada.Numerics;

Elementary Functions#

Implementation-defined approximations to the mathematical functions known as the “elementary functions” are provided by the subprograms in Numerics.Generic_Elementary_Functions. Nongeneric equivalents of this generic package for each of the predefined floating point types are also provided as children of Numerics.

generic
   type Float_Type is digits <>;
package Ada.Numerics.Generic_Elementary_Functions
   with Pure, Nonblocking is

   function Sqrt(X          : Float_Type'Base) return Float_Type'Base;
   function Log (X          : Float_Type'Base) return Float_Type'Base;
   function Log (X, Base    : Float_Type'Base) return Float_Type'Base;
   function Exp (X          : Float_Type'Base) return Float_Type'Base;
   function "**"(Left, Right: Float_Type'Base) return Float_Type'Base;

   function Sin(X       : Float_Type'Base) return Float_Type'Base;
   function Sin(X, Cycle: Float_Type'Base) return Float_Type'Base;
   function Cos(X       : Float_Type'Base) return Float_Type'Base;
   function Cos(X, Cycle: Float_Type'Base) return Float_Type'Base;
   function Tan(X       : Float_Type'Base) return Float_Type'Base;
   function Tan(X, Cycle: Float_Type'Base) return Float_Type'Base;
   function Cot(X       : Float_Type'Base) return Float_Type'Base;
   function Cot(X, Cycle: Float_Type'Base) return Float_Type'Base;

   function Arcsin(X       : Float_Type'Base) return Float_Type'Base;
   function Arcsin(X, Cycle: Float_Type'Base) return Float_Type'Base;
   function Arccos(X       : Float_Type'Base) return Float_Type'Base;
   function Arccos(X, Cycle: Float_Type'Base) return Float_Type'Base;
   function Arctan(Y: Float_Type'Base; X: Float_Type'Base := 1.0) return Float_Type'Base;
   function Arccot(X: Float_Type'Base; Y: Float_Type'Base := 1.0) return Float_Type'Base;
   function Arctan(Y: Float_Type'Base; X: Float_Type'Base := 1.0; Cycle: Float_Type'Base) return Float_Type'Base;
   function Arccot(X: Float_Type'Base; Y: Float_Type'Base := 1.0; Cycle: Float_Type'Base) return Float_Type'Base;

   function Sinh   (X: Float_Type'Base) return Float_Type'Base;
   function Cosh   (X: Float_Type'Base) return Float_Type'Base;
   function Tanh   (X: Float_Type'Base) return Float_Type'Base;
   function Coth   (X: Float_Type'Base) return Float_Type'Base;
   function Arcsinh(X: Float_Type'Base) return Float_Type'Base;
   function Arccosh(X: Float_Type'Base) return Float_Type'Base;
   function Arctanh(X: Float_Type'Base) return Float_Type'Base;
   function Arccoth(X: Float_Type'Base) return Float_Type'Base;
end Ada.Numerics.Generic_Elementary_Functions;

Generic Complex Types#

generic
   type Real is digits <>;
package Ada.Numerics.Generic_Complex_Types
   with Pure, Nonblocking is

   type Complex is record
      Re, Im: Real'Base;
   end record;

   type Imaginary is private
      with Preelaborable_Initialization;

   i: constant Imaginary;
   j: constant Imaginary;

   function Re(X: Complex)   return Real'Base;
   function Im(X: Complex)   return Real'Base;
   function Im(X: Imaginary) return Real'Base;

   procedure Set_Re(X: in out Complex; Re: Real'Base);
   procedure Set_Im(X: in out Complex; Im: Real'Base);
   procedure Set_Im(X: out Imaginary ; Im: Real'Base);

   function Compose_From_Cartesian(Re, Im: Real'Base) return Complex;
   function Compose_From_Cartesian(Re    : Real'Base) return Complex;
   function Compose_From_Cartesian(Im    : Imaginary) return Complex;

   function Modulus(X    : Complex) return Real'Base;
   function "abs"  (Right: Complex) return Real'Base renames Modulus;

   function Argument(X: Complex)                   return Real'Base;
   function Argument(X: Complex; Cycle: Real'Base) return Real'Base;

   function Compose_From_Polar(Modulus, Argument       : Real'Base) return Complex;
   function Compose_From_Polar(Modulus, Argument, Cycle: Real'Base) return Complex;

   function "+"      (Right: Complex) return Complex;
   function "-"      (Right: Complex) return Complex;
   function Conjugate(X    : Complex) return Complex;

   function "+"(Left, Right: Complex) return Complex;
   function "-"(Left, Right: Complex) return Complex;
   function "*"(Left, Right: Complex) return Complex;
   function "/"(Left, Right: Complex) return Complex;

   function "**"(Left: Complex; Right: Integer) return Complex;

   function "+"      (Right: Imaginary) return Imaginary;
   function "-"      (Right: Imaginary) return Imaginary;
   function Conjugate(X    : Imaginary) return Imaginary renames "-";
   function "abs"    (Right: Imaginary) return Real'Base;

   function "+"(Left, Right: Imaginary) return Imaginary;
   function "-"(Left, Right: Imaginary) return Imaginary;
   function "*"(Left, Right: Imaginary) return Real'Base;
   function "/"(Left, Right: Imaginary) return Real'Base;

   function "**"(Left: Imaginary; Right: Integer) return Complex;

   function "<" (Left, Right: Imaginary) return Boolean;
   function "<="(Left, Right: Imaginary) return Boolean;
   function ">" (Left, Right: Imaginary) return Boolean;
   function ">="(Left, Right: Imaginary) return Boolean;

   function "+"(Left: Complex  ; Right: Real'Base) return Complex;
   function "+"(Left: Real'Base; Right: Complex)   return Complex;
   function "-"(Left: Complex  ; Right: Real'Base) return Complex;
   function "-"(Left: Real'Base; Right: Complex)   return Complex;
   function "*"(Left: Complex  ; Right: Real'Base) return Complex;
   function "*"(Left: Real'Base; Right: Complex)   return Complex;
   function "/"(Left: Complex  ; Right: Real'Base) return Complex;
   function "/"(Left: Real'Base; Right: Complex)   return Complex;

   function "+"(Left: Complex  ; Right: Imaginary) return Complex;
   function "+"(Left: Imaginary; Right: Complex)   return Complex;
   function "-"(Left: Complex  ; Right: Imaginary) return Complex;
   function "-"(Left: Imaginary; Right: Complex)   return Complex;
   function "*"(Left: Complex  ; Right: Imaginary) return Complex;
   function "*"(Left: Imaginary; Right: Complex)   return Complex;
   function "/"(Left: Complex  ; Right: Imaginary) return Complex;
   function "/"(Left: Imaginary; Right: Complex)   return Complex;

   function "+"(Left: Imaginary; Right: Real'Base) return Complex;
   function "+"(Left: Real'Base; Right: Imaginary) return Complex;
   function "-"(Left: Imaginary; Right: Real'Base) return Complex;
   function "-"(Left: Real'Base; Right: Imaginary) return Complex;
   function "*"(Left: Imaginary; Right: Real'Base) return Imaginary;
   function "*"(Left: Real'Base; Right: Imaginary) return Imaginary;
   function "/"(Left: Imaginary; Right: Real'Base) return Imaginary;
   function "/"(Left: Real'Base; Right: Imaginary) return Imaginary;
private
   type Imaginary is new Real'Base;

   i: constant Imaginary := 1.0;
   j: constant Imaginary := 1.0;
end Ada.Numerics.Generic_Complex_Types;

Complex Elementary Functions#

with Ada.Numerics.Generic_Complex_Types;

generic
   with package Complex_Types is new Ada.Numerics.Generic_Complex_Types(<>);
   use Complex_Types;
package Ada.Numerics.Generic_Complex_Elementary_Functions
   with Pure, Nonblocking is

   function Sqrt(X: Complex)   return Complex;
   function Log (X: Complex)   return Complex;
   function Exp (X: Complex)   return Complex;
   function Exp (X: Imaginary) return Complex;

   function "**"(Left: Complex;   Right: Complex)   return Complex;
   function "**"(Left: Complex;   Right: Real'Base) return Complex;
   function "**"(Left: Real'Base; Right: Complex)   return Complex;

   function Sin(X: Complex) return Complex;
   function Cos(X: Complex) return Complex;
   function Tan(X: Complex) return Complex;
   function Cot(X: Complex) return Complex;

   function Arcsin(X: Complex) return Complex;
   function Arccos(X: Complex) return Complex;
   function Arctan(X: Complex) return Complex;
   function Arccot(X: Complex) return Complex;

   function Sinh(X: Complex) return Complex;
   function Cosh(X: Complex) return Complex;
   function Tanh(X: Complex) return Complex;
   function Coth(X: Complex) return Complex;

   function Arcsinh(X: Complex) return Complex;
   function Arccosh(X: Complex) return Complex;
   function Arctanh(X: Complex) return Complex;
   function Arccoth(X: Complex) return Complex;
end Ada.Numerics.Generic_Complex_Elementary_Functions;

Random Number Generation#

Facilities for the generation of pseudo-random floating point numbers are provided in the package Numerics.Float_Random; the generic package Numerics.Discrete_Random provides similar facilities for the generation of pseudo-random integers and pseudo-random values of enumeration types. For brevity, pseudo-random values of any of these types are called random numbers.

Some of the facilities provided are basic to all applications of random numbers. These include a limited private type each of whose objects serves as the generator of a (possibly distinct) sequence of random numbers; a function to obtain the “next” random number from a given sequence of random numbers (that is, from its generator); and subprograms to initialize or reinitialize a given generator to a time-dependent state or a state denoted by a single integer.

Other facilities are provided specifically for advanced applications. These include subprograms to save and restore the state of a given generator; a private type whose objects can be used to hold the saved state of a generator; and subprograms to obtain a string representation of a given generator state, or, given such a string representation, the corresponding state.

Float Random
package Ada.Numerics.Float_Random
   with Global => in out synchronized is

   -- Basic facilities
   type Generator is limited private;

   subtype Uniformly_Distributed is Float range 0.0 .. 1.0;

   function Random(Gen: Generator) return Uniformly_Distributed
      with Global => overriding in out Gen;

   procedure Reset(Gen: Generator; Initiator: Integer) with Global => overriding in out Gen;
   procedure Reset(Gen: Generator)                     with Global => overriding in out Gen;

   -- Advanced facilities
   type State is private;

   procedure Save (Gen: Generator; To_State  : out State);
   procedure Reset(Gen: Generator; From_State:     State)
      with Global => overriding in out Gen;

   Max_Image_Width: constant := <implementation-defined integer value>;

   function Image(Of_State   : State)  return String;
   function Value(Coded_State: String) return State;
end Ada.Numerics.Float_Random;
Discrete Random
generic
   type Result_Subtype is (<>);
package Ada.Numerics.Discrete_Random
   with Global => in out synchronized is

   -- Basic facilities
   type Generator is limited private;
   
   function Random(Gen: Generator) return Result_Subtype
      with Global => overriding in out Gen;
   function Random(Gen: Generator; First: Result_Subtype; Last: Result_Subtype) return Result_Subtype
      with Post   => Random'Result in First .. Last,
           Global => overriding in out Gen;

   procedure Reset(Gen: Generator; Initiator: Integer) with Global => overriding in out Gen;
   procedure Reset(Gen: Generator)                     with Global => overriding in out Gen;

   -- Advanced facilities
   type State is private;

   procedure Save (Gen: Generator; To_State  : out State);
   procedure Reset(Gen: Generator; From_State:     State)
      with Global => overriding in out Gen;

   Max_Image_Width: constant := <implementation-defined integer value>;

   function Image(Of_State   : State)  return String;
   function Value(Coded_State: String) return State;
end Ada.Numerics.Discrete_Random;

Bounded (Run-Time) Errors

It is a bounded error to invoke Value with a string that is not the image of any generator state. If the error is detected, Constraint_Error or Program_Error is raised. Otherwise, a call to Reset with the resulting state will produce a generator such that calls to Random with this generator will produce a sequence of values of the appropriate subtype, but which are not necessarily random in character. That is, the sequence of values do not necessarily fulfill the implementation requirements of this subclause.

Examples Using Numerics.Discrete_Random and Numerics.Float_Random

Example of a program that plays a simulated dice game
with Ada.Numerics.Discrete_Random;

procedure Dice_Game is
   subtype Die  is Integer range 1 .. 6;
   subtype Dice is Integer range 2*Die'First .. 2*Die'Last;
   package Random_Die is new Ada.Numerics.Discrete_Random(Die);
   use Random_Die;

   G: Generator;
   D: Dice;
begin
   Reset(G);  -- Start the generator in a unique state in each run
   loop
      -- Roll a pair of dice; sum and process the results
      D := Random(G) + Random(G);
      ...
   end loop;
end Dice_Game;
Example of a program that simulates coin tosses
with Ada.Numerics.Discrete_Random;

procedure Flip_A_Coin is
   type Coin is (Heads, Tails);
   package Random_Coin is new Ada.Numerics.Discrete_Random(Coin);
   use Random_Coin;

   G: Generator;
begin
   Reset(G);  -- Start the generator in a unique state in each run
   loop
      -- Toss a coin and process the result
      case Random(G) is
      when Heads => ...
      when Tails => ...
      end case;
   ...
   end loop;
Example of a parallel simulation of a physical system, with a separate generator of event probabilities in each task
with Ada.Numerics.Float_Random;

procedure Parallel_Simulation is
   use Ada.Numerics.Float_Random;
   task type Worker is
      entry Initialize_Generator(Initiator: Integer);
      ...
   end Worker;

   W: array (1 .. 10) of Worker;
   task body Worker is
      G                   : Generator;
      Probability_Of_Event: Uniformly_Distributed;
   begin
      accept Initialize_Generator(Initiator: Integer) do
         Reset(G, Initiator);
      end Initialize_Generator;
      loop
         ...
         Probability_Of_Event := Random(G);
         ...
      end loop;
   end Worker;
begin
   -- Initialize the generators in the Worker tasks to different states
   for I in W'Range loop
      W(I).Initialize_Generator(I);
   end loop;
   ... -- Wait for the Worker tasks to terminate
end Parallel_Simulation;

Although each Worker task initializes its generator to a different state, those states will be the same in every execution of the program. The generator states can be initialized uniquely in each program execution by instantiating Ada.Numerics.Discrete_Random for the type Integer in the main procedure, resetting the generator obtained from that instance to a time-dependent state, and then using random integers obtained from that generator to initialize the generators in each Worker task.

Big Numbers#

Support is provided for integer arithmetic involving values larger than those supported by the target machine, and for arbitrary-precision real numbers.

package Ada.Numerics.Big_Numbers
   with Pure, Nonblocking, Global => null is

   subtype Field       is Integer range 0 .. <implementation-defined>;
   subtype Number_Base is Integer range 2 .. 16;
end Ada.Numerics.Big_Numbers;

Big Integers#

with Ada.Strings.Text_Buffers;

package Ada.Numerics.Big_Numbers.Big_Integers
   with Preelaborate, Nonblocking, Global => in out synchronized is

   type Big_Integer is private
     with Integer_Literal => From_Universal_Image,
          Put_Image       => Put_Image;

   function Is_Valid(Arg: Big_Integer) return Boolean
      with Convention => Intrinsic;

   subtype Valid_Big_Integer is Big_Integer
      with Dynamic_Predicate => Is_Valid(Valid_Big_Integer),
           Predicate_Failure => (raise Program_Error);

   function "=" (L, R: Valid_Big_Integer) return Boolean;
   function "<" (L, R: Valid_Big_Integer) return Boolean;
   function "<="(L, R: Valid_Big_Integer) return Boolean;
   function ">" (L, R: Valid_Big_Integer) return Boolean;
   function ">="(L, R: Valid_Big_Integer) return Boolean;

   function To_Big_Integer(Arg: Integer) return Valid_Big_Integer;

   subtype Big_Positive is Big_Integer
      with Dynamic_Predicate => (if Is_Valid(Big_Positive) then Big_Positive > 0),
           Predicate_Failure => (raise Constraint_Error);
   subtype Big_Natural is Big_Integer
      with Dynamic_Predicate => (if Is_Valid(Big_Natural) then Big_Natural >= 0),
           Predicate_Failure => (raise Constraint_Error);

   function In_Range(Arg, Low, High: Valid_Big_Integer) return Boolean is
      (Low <= Arg and Arg <= High);

   function To_Integer(Arg: Valid_Big_Integer) return Integer
      with Pre => In_Range(Arg, Low  => To_Big_Integer(Integer'First),
                                High => To_Big_Integer(Integer'Last))
                  or else raise Constraint_Error;

   generic
      type Int is range <>;
   package Signed_Conversions is
      function To_Big_Integer(Arg: Int) return Valid_Big_Integer;
      function From_Big_Integer(Arg: Valid_Big_Integer) return Int
         with Pre => In_Range(Arg, Low  => To_Big_Integer(Int'First),
                                   High => To_Big_Integer(Int'Last))
                     or else raise Constraint_Error;
   end Signed_Conversions;

   generic
      type Int is mod <>;
   package Unsigned_Conversions is
      function To_Big_Integer(Arg: Int) return Valid_Big_Integer;
      function From_Big_Integer(Arg: Valid_Big_Integer) return Int
         with Pre => In_Range(Arg, Low  => To_Big_Integer(Int'First),
                                   High => To_Big_Integer(Int'Last))
                     or else raise Constraint_Error;
   end Unsigned_Conversions;

   function To_String(Arg: Valid_Big_Integer; Width: Field := 0; Base: Number_Base := 10) return String
      with Post => To_String'Result'First = 1;
   function From_String         (Arg: String) return Valid_Big_Integer;
   function From_Universal_Image(Arg: String) return Valid_Big_Integer renames From_String;

   procedure Put_Image(Buffer: in out Ada.Strings.Text_Buffers.Root_Buffer_Type'Class; Arg: Valid_Big_Integer);

   function "+"  (L   : Valid_Big_Integer) return Valid_Big_Integer;
   function "-"  (L   : Valid_Big_Integer) return Valid_Big_Integer;
   function "abs"(L   : Valid_Big_Integer) return Valid_Big_Integer;
   function "+"  (L, R: Valid_Big_Integer) return Valid_Big_Integer;
   function "-"  (L, R: Valid_Big_Integer) return Valid_Big_Integer;
   function "*"  (L, R: Valid_Big_Integer) return Valid_Big_Integer;
   function "/"  (L, R: Valid_Big_Integer) return Valid_Big_Integer;
   function "mod"(L, R: Valid_Big_Integer) return Valid_Big_Integer;
   function "rem"(L, R: Valid_Big_Integer) return Valid_Big_Integer;
   function Min  (L, R: Valid_Big_Integer) return Valid_Big_Integer;
   function Max  (L, R: Valid_Big_Integer) return Valid_Big_Integer;
   function "**" (L: Valid_Big_Integer; R: Natural) return Valid_Big_Integer;

   function Greatest_Common_Divisor(L, R: Valid_Big_Integer) return Big_Positive
      with Pre => (L /= 0 and R /= 0) or else raise Constraint_Error;
end Ada.Numerics.Big_Numbers.Big_Integers;

Big Reals#

with Ada.Numerics.Big_Numbers.Big_Integers; use all type Big_Integers.Big_Integer;
with Ada.Strings.Text_Buffers;

package Ada.Numerics.Big_Numbers.Big_Reals
   with Preelaborate, Nonblocking, Global => in out synchronized is

   type Big_Real is private
      with Real_Literal => From_Universal_Image,
           Put_Image    => Put_Image;

   function Is_Valid(Arg: Big_Real) return Boolean
      with Convention => Intrinsic;

   subtype Valid_Big_Real is Big_Real
      with Dynamic_Predicate => Is_Valid(Valid_Big_Real),
           Predicate_Failure => raise Program_Error;

   function "/"(Num, Den: Big_Integers.Valid_Big_Integer) return Valid_Big_Real
      with Pre => Den /= 0 or else raise Constraint_Error;

   function Numerator(Arg: Valid_Big_Real) return Big_Integers.Valid_Big_Integer
     with Post => (if Arg = 0.0 then Numerator'Result = 0);
   function Denominator(Arg: Valid_Big_Real) return Big_Integers.Big_Positive
      with Post => (if Arg = 0.0
                    then Denominator'Result = 1
                    else Big_Integers.Greatest_Common_Divisor(Numerator(Arg), Denominator'Result) = 1);

   function To_Big_Real(Arg: Big_Integers.Valid_Big_Integer) return Valid_Big_Real is
      (Arg / 1);
   function To_Real(Arg: Integer) return Valid_Big_Real is
      (Big_Integers.To_Big_Integer(Arg) / 1);

   function "=" (L, R: Valid_Big_Real) return Boolean;
   function "<" (L, R: Valid_Big_Real) return Boolean;
   function "<="(L, R: Valid_Big_Real) return Boolean;
   function ">" (L, R: Valid_Big_Real) return Boolean;
   function ">="(L, R: Valid_Big_Real) return Boolean;

   function In_Range(Arg, Low, High: Valid_Big_Real) return Boolean is
      (Low <= Arg and Arg <= High);

   generic
      type Num is digits <>;
   package Float_Conversions is
      function To_Big_Real  (Arg: Num)            return Valid_Big_Real;
      function From_Big_Real(Arg: Valid_Big_Real) return Num
         with Pre => In_Range(Arg, Low  => To_Big_Real(Num'First),
                                   High => To_Big_Real(Num'Last))
                     or else (raise Constraint_Error);
   end Float_Conversions;

   generic
      type Num is delta <>;
   package Fixed_Conversions is
      function To_Big_Real  (Arg: Num)            return Valid_Big_Real;
      function From_Big_Real(Arg: Valid_Big_Real) return Num
         with Pre => In_Range(Arg, Low  => To_Big_Real(Num'First),
                                   High => To_Big_Real(Num'Last))
                     or else (raise Constraint_Error);
   end Fixed_Conversions;

   function To_String(Arg : Valid_Big_Real;
                      Fore: Field := 2;
                      Aft : Field := 3;
                      Exp : Field := 0) return String
      with Post => To_String'Result'First = 1;

   function From_String         (Arg: String) return Valid_Big_Real;
   function From_Universal_Image(Arg: String) return Valid_Big_Real renames From_String;
   function From_Universal_Image(Num, Den: String) return Valid_Big_Real is
      (Big_Integers.From_Universal_Image(Num) / Big_Integers.From_Universal_Image(Den));

   function To_Quotient_String(Arg: Valid_Big_Real) return String is
      (To_String(Numerator(Arg)) & " / " & To_String(Denominator(Arg)));
   function From_Quotient_String(Arg: String) return Valid_Big_Real;

   procedure Put_Image(Buffer: in out Ada.Strings.Text_Buffers.Root_Buffer_Type'Class; Arg: Valid_Big_Real);

   function "+"  (L   : Valid_Big_Real) return Valid_Big_Real;
   function "-"  (L   : Valid_Big_Real) return Valid_Big_Real;
   function "abs"(L   : Valid_Big_Real) return Valid_Big_Real;
   function "+"  (L, R: Valid_Big_Real) return Valid_Big_Real;
   function "-"  (L, R: Valid_Big_Real) return Valid_Big_Real;
   function "*"  (L, R: Valid_Big_Real) return Valid_Big_Real;
   function "/"  (L, R: Valid_Big_Real) return Valid_Big_Real;
   function Min  (L, R: Valid_Big_Real) return Valid_Big_Real;
   function Max  (L, R: Valid_Big_Real) return Valid_Big_Real;
   function "**" (L: Valid_Big_Real; R: Integer) return Valid_Big_Real;
end Ada.Numerics.Big_Numbers.Big_Reals;

Real Vectors and Matrices#

generic
   type Real is digits <>;
package Ada.Numerics.Generic_Real_Arrays
   with pragma Pure, Nonblocking is

   type Real_Vector is array(Integer range <>)                   of Real'Base;
   type Real_Matrix is array(Integer range <>, Integer range <>) of Real'Base;

   function "+"  (Right: Real_Vector) return Real_Vector;
   function "-"  (Right: Real_Vector) return Real_Vector;
   function "abs"(Right: Real_Vector) return Real_Vector;
   function "abs"(Right: Real_Vector) return Real'Base;

   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 "*"(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;

   function Unit_Vector(Index: Integer; Order: Positive; First: Integer := 1) return Real_Vector;

   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;

   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;

   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;

   function  Eigenvalues(A: Real_Matrix) return Real_Vector;
   procedure Eigensystem(A: Real_Matrix; Values: out Real_Vector; Vectors: out Real_Matrix);

   function Unit_Matrix(Order: Positive; First_1, First_2: Integer := 1) return Real_Matrix;
end Ada.Numerics.Generic_Real_Arrays;

Complex Vectors and Matrices#

with Ada.Numerics.Generic_Real_Arrays, Ada.Numerics.Generic_Complex_Types;

generic
   with package Real_Arrays is new Ada.Numerics.Generic_Real_Arrays(<>);
   use Real_Arrays;
   with package Complex_Types is new Ada.Numerics.Generic_Complex_Types(Real);
   use Complex_Types;
package Ada.Numerics.Generic_Complex_Arrays
   with Pure, Nonblocking is

   -- Types
   type Complex_Vector is array(Integer range <>)                   of Complex;
   type Complex_Matrix is array(Integer range <>, Integer range <>) of Complex;

   -- Subprograms for Complex_Vector types
   -- Complex_Vector selection, conversion and composition operations
   function Re(X: Complex_Vector) return Real_Vector;
   function Im(X: Complex_Vector) return Real_Vector;

   procedure Set_Re(X: in out Complex_Vector; Re: Real_Vector);
   procedure Set_Im(X: in out Complex_Vector; Im: Real_Vector);

   function Compose_From_Cartesian(Re    : Real_Vector) return Complex_Vector;
   function Compose_From_Cartesian(Re, Im: Real_Vector) return Complex_Vector;

   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;

   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;

   -- Complex_Vector arithmetic operations
   function "+"      (Right: Complex_Vector) return Complex_Vector;
   function "-"      (Right: Complex_Vector) return Complex_Vector;
   function Conjugate(X    : Complex_Vector) return Complex_Vector;

   function "+"(Left, Right: Complex_Vector) return Complex_Vector;
   function "-"(Left, Right: Complex_Vector) return Complex_Vector;
   function "*"(Left, Right: Complex_Vector) return Complex;

   function "abs"(Right: Complex_Vector) return Real'Base;

   -- Mixed Real_Vector and Complex_Vector arithmetic operations
   function "+"(Left: Real_Vector; Right: Complex_Vector) return Complex_Vector;
   function "-"(Left: Real_Vector; Right: Complex_Vector) return Complex_Vector;
   function "+"(Left: Complex_Vector; Right: Real_Vector) return Complex_Vector;
   function "-"(Left: Complex_Vector; Right: Real_Vector) return Complex_Vector;

   function "*"(Left: Real_Vector   ; Right: Complex_Vector) return Complex;
   function "*"(Left: Complex_Vector; Right: Real_Vector)    return Complex;

   -- Complex_Vector scaling operations
   function "*"(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;
   function "*"(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;

   -- Other Complex_Vector operations
   function Unit_Vector(Index: Integer; Order: Positive; First: Integer := 1) return Complex_Vector;

   -- Subprograms for Complex_Matrix types
   -- Complex_Matrix selection, conversion and composition operations
   function Re(X: Complex_Matrix) return Real_Matrix;
   function Im(X: Complex_Matrix) return Real_Matrix;

   procedure Set_Re(X: in out Complex_Matrix; Re: Real_Matrix);
   procedure Set_Im(X: in out Complex_Matrix; Im: Real_Matrix);

   function Compose_From_Cartesian(Re    : Real_Matrix) return Complex_Matrix;
   function Compose_From_Cartesian(Re, Im: Real_Matrix) return Complex_Matrix;

   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;

   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;

   -- Complex_Matrix arithmetic operations
   function "+"      (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;

   function "+"(Left, Right: Complex_Matrix) return Complex_Matrix;
   function "-"(Left, Right: Complex_Matrix) return Complex_Matrix;
   function "*"(Left, Right: Complex_Matrix) return Complex_Matrix;
   function "*"(Left, Right: Complex_Vector) return Complex_Matrix;

   function "*"(Left: Complex_Vector; Right: Complex_Matrix) return Complex_Vector;
   function "*"(Left: Complex_Matrix; Right: Complex_Vector) return Complex_Vector;

   -- Mixed Real_Matrix and Complex_Matrix arithmetic operations
   function "+"(Left: Real_Matrix; Right: Complex_Matrix) return Complex_Matrix;
   function "-"(Left: Real_Matrix; Right: Complex_Matrix) return Complex_Matrix;
   function "*"(Left: Real_Matrix; Right: Complex_Matrix) return Complex_Matrix;
   function "*"(Left: Real_Vector; Right: Complex_Vector) return Complex_Matrix;
   function "*"(Left: Real_Vector; Right: Complex_Matrix) return Complex_Vector;
   function "*"(Left: Real_Matrix; Right: Complex_Vector) return Complex_Vector;
   function "+"(Left: Complex_Matrix; Right: Real_Matrix) return Complex_Matrix;
   function "-"(Left: Complex_Matrix; Right: Real_Matrix) return Complex_Matrix;
   function "*"(Left: Complex_Matrix; Right: Real_Matrix) return Complex_Matrix;
   function "*"(Left: Complex_Vector; Right: Real_Vector) return Complex_Matrix;
   function "*"(Left: Complex_Vector; Right: Real_Matrix) return Complex_Vector;
   function "*"(Left: Complex_Matrix; Right: Real_Vector) return Complex_Vector;

   -- Complex_Matrix scaling operations
   function "*"(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;
   function "*"(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;

   -- Complex_Matrix inversion and related operations
   function Solve      (A, X: Complex_Matrix)                 return Complex_Matrix;
   function Solve      (A: Complex_Matrix; X: Complex_Vector) return Complex_Vector;
   function Inverse    (A: Complex_Matrix)                    return Complex_Matrix;
   function Determinant(A: Complex_Matrix)                    return Complex;

   -- Eigenvalues and vectors of a Hermitian matrix
   function  Eigenvalues(A: Complex_Matrix) return Real_Vector;
   procedure Eigensystem(A: Complex_Matrix; Values: out Real_Vector; Vectors: out Complex_Matrix);

   -- Other Complex_Matrix operations
   function Unit_Matrix(Order: Positive; First_1, First_2: Integer := 1) return Complex_Matrix;
end Ada.Numerics.Generic_Complex_Arrays;

Floating-Point Attributes#

The following representation-oriented attributes are defined for every subtype S of a floating point type T.

Attribute
Description
S'Machine_Radix Yields the radix of the hardware representation of the type T. The value of this attribute is of the type universal_integer.
The values of other representation-oriented attributes of a floating point subtype, and of the “primitive function” attributes of a floating point subtype described later, are defined in terms of a particular representation of nonzero values called the canonical form. The canonical form (for the type T) is the form \(\pm \operatorname{mantissa} \cdot \operatorname{T'Machine\_Radix}^{\operatorname{exponent}}\) where
\(\operatorname{mantissa}\) is a fraction in the number base T'Machine\_Radix, the first digit of which is nonzero.
\(\operatorname{exponent}\) is an integer.
S'Machine_Mantissa Yields the largest value of \(p\) such that every value expressible in the canonical form (for the type T), having a \(p\)-digit mantissa and an exponent between T'Machine_Emin and T'Machine_Emax, is a machine number (see 3.5.7) of the type T. This attribute yields a value of the type universal_integer.
S'Machine_Emin Yields the smallest (most negative) value of exponent such that every value expressible in the canonical form (for the type T), having a mantissa of T'Machine_Mantissa digits, is a machine number (see 3.5.7) of the type T. This attribute yields a value of the type universal_integer.
S'Machine_Emax Yields the largest (most positive) value of exponent such that every value expressible in the canonical form (for the type T), having a mantissa of T'Machine_Mantissa digits, is a machine number (see 3.5.7) of the type T. This attribute yields a value of the type universal_integer.
S'Denorm Yields the value True if every value expressible in the form \(\pm \operatorname{mantissa} \cdot \operatorname{T'Machine\_Radix}^{\operatorname{T'Machine_Emin}}\) where \(mantissa\) is a nonzero T'Machine_Mantissa-digit fraction in the number base T'Machine_Radix, the first digit of which is zero, is a machine number (see 3.5.7) of the type T; yields the value False otherwise. The value of this attribute is of the predefined type Boolean.
The values described by the formula in the definition of S'Denorm are called denormalized numbers. A nonzero machine number that is not a denormalized number is a normalized number. A normalized number \(x\) of a given type T is said to be represented in canonical form when it is expressed in the canonical form (for the type T) with a mantissa having T'Machine_Mantissa digits; the resulting form is the canonical-form representation of \(x\).
S'Machine_Rounds Yields the value True if rounding is performed on inexact results of every predefined operation that yields a result of the type T; yields the value False otherwise. The value of this attribute is of the predefined type Boolean.
S'Machine_Overflows Yields the value True if overflow and divide-by-zero are detected and reported by raising Constraint_Error for every predefined operation that yields a result of the type T; yields the value False otherwise. The value of this attribute is of the predefined type Boolean.
S'Signed_Zeros Yields the value True if the hardware representation for the type T has the capability of representing both positively and negatively signed zeros, these being generated and used by the predefined operations of the type T as specified in IEC 559:1989; yields the value False otherwise. The value of this attribute is of the predefined type Boolean.
For every value \(x\) of a floating point type T, the normalized exponent of \(x\) is defined as follows:
– The normalized exponent of zero is (by convention) zero.
For nonzero \(x\), the normalized exponent of \(x\) is the unique integer \(k\) such that \(\operatorname{T'Machine\_Radix}^{k - 1} \le \mid x \mid < \operatorname{T'Machine\_Radix}^k\).

The following primitive function attributes are defined for any subtype S of a floating point type T.

Attribute
Description
S'Exponent S'Exponent denotes a function with the following specification:
function S'Exponent(X: T) return <universal_integer>;
The function yields the normalized exponent of X.
S'Fraction S'Fraction denotes a function with the following specification:
function S'Fraction(X: T) return T;
The function yields the value \(X \cdot \operatorname{T'Machine\_Radix}^{-k}\), where \(k\) is the normalized exponent of X. A zero result[, which can only occur when X is zero,] has the sign of X.
S'Compose S'Compose denotes a function with the following specification:
function S'Compose(Fraction: T; Exponent: <universal_integer>) return T;
Let \(v\) be the value \(\operatorname{Fraction} \cdot \operatorname{T'Machine\_Radix}^{\operatorname{Exponent} - k}\), where \(k\) is the normalized exponent of Fraction. If \(v\) is a machine number of the type T, or if \(\mid v \mid \ge \operatorname{T'Model\_Small}\), the function yields \(v\); otherwise, it yields either one of the machine numbers of the type T adjacent to \(v\). Constraint_Error is optionally raised if \(v\) is outside the base range of S. A zero result has the sign of Fraction when S'Signed_Zeros is True.
S'Scaling S'Scaling denotes a function with the following specification:
function S'Scaling(X: T; Adjustment: <universal_integer>) return T;
Let \(v\) be the value \(X \cdot \operatorname{T'Machine\_Radix}^{\operatorname{Adjustment}}\). If \(v\) is a machine number of the type T, or if \(\mid v \mid \ge \operatorname{T'Model\_Small}\), the function yields \(v\); otherwise, it yields either one of the machine numbers of the type T adjacent to \(v\). Constraint_Error is optionally raised if \(v\) is outside the base range of S. A zero result has the sign of X when S'Signed_Zeros is True.
S'Floor S'Floor denotes a function with the following specification:
function S'Floor(X: T) return T;
The function yields the value Floor(X), that is i.e., the largest (most positive) integral value less than or equal to X. When X is zero, the result has the sign of X; a zero result otherwise has a positive sign.
S'Ceiling S'Ceiling denotes a function with the following specification:
function S'Ceiling(X: T) return T;
The function yields the value Ceiling(X), that is i.e., the smallest (most negative) integral value greater than or equal to X. When X is zero, the result has the sign of X; a zero result otherwise has a negative sign when S'Signed_Zeros is True.
S'Rounding S'Rounding denotes a function with the following specification:
function S'Rounding(X: T) return T;
The function yields the integral value nearest to X, rounding away from zero if X lies exactly halfway between two integers. A zero result has the sign of X when S'Signed_Zeros is True.
S'Unbiased_Rounding S'Unbiased_Rounding denotes a function with the following specification:
function S'Unbiased_Rounding(X: T) return T;
The function yields the integral value nearest to X, rounding toward the even integer if X lies exactly halfway between two integers. A zero result has the sign of X when S'Signed_Zeros is True.
S'Machine_Rounding S'Machine_Rounding denotes a function with the following specification:
function S'Machine_Rounding(X: T) return T;
The function yields the integral value nearest to X. If X lies exactly halfway between two integers, one of those integers is returned, but which of them is returned is unspecified. A zero result has the sign of X when S'Signed_Zeros is True. This function provides access to the rounding behavior which is most efficient on the target processor.
S'Truncation S'Truncation denotes a function with the following specification:
function S'Truncation(X: T) return T;
The function yields the value Ceiling(X) when X is negative, and Floor(X) otherwise. A zero result has the sign of X when S'Signed_Zeros is True.
S'Remainder S'Remainder denotes a function with the following specification:
function S'Remainder(X, Y: T) return T;
For nonzero Y, let \(v\) be the value \(X - n \cdot Y\), where \(n\) is the integer nearest to the exact value of \(\frac{X}{Y}\); if \(\mid n - \frac{X}{Y} \mid = \frac{1}{2}\), then \(n\) is chosen to be even. If \(v\) is a machine number of the type T, the function yields \(v\); otherwise, it yields zero. Constraint_Error is raised if Y is zero. A zero result has the sign of X when S'Signed_Zeros is True.
S'Adjacent S'Adjacent denotes a function with the following specification:
function S'Adjacent(X, Towards: T) return T;
If Towards = X, the function yields X; otherwise, it yields the machine number of the type T adjacent to X in the direction of Towards, if that machine number exists. If the result would be outside the base range of S, Constraint_Error is raised. When T'Signed_Zeros is True, a zero result has the sign of X. When Towards is zero, its sign has no bearing on the result.
S'Copy_Sign S'Copy_Sign denotes a function with the following specification:
function S'Copy_Sign(Value, Sign: T) return T;
If the value of Value is nonzero, the function yields a result whose magnitude is that of Value and whose sign is that of Sign; otherwise, it yields the value zero. Constraint_Error is optionally raised if the result is outside the base range of S. A zero result has the sign of Sign when S'Signed_Zeros is True.
S'Leading_Part S'Leading_Part denotes a function with the following specification:
function S'Leading_Part(X: T; Radix_Digits: <universal_integer>) return T;
Let \(v\) be the value \(\operatorname{T'Machine\_Radix}^{k - \operatorname{Radix\_Digits}}\), where \(k\) is the normalized exponent of X. The function yields the value
\(\lfloor \frac{X}{v} \rfloor \cdot v\), when X is nonnegative and Radix_Digits is positive.
\(\lceil \frac{X}{v} \rceil \cdot v\), when X is negative and Radix_Digits is positive.
Constraint_Error is raised when Radix_Digits is zero or negative. A zero result[, which can only occur when X is zero,] has the sign of X.
S'Machine S'Machine denotes a function with the following specification:
function S'Machine(X: T) return T;
If X is a machine number of the type T, the function yields X; otherwise, it yields the value obtained by rounding or truncating X to either one of the adjacent machine numbers of the type T. Constraint_Error is raised if rounding or truncating X to the precision of the machine numbers results in a value outside the base range of S. A zero result has the sign of X when S'Signed_Zeros is True.

The following model-oriented attributes are defined for any subtype S of a floating point type T.

Attribute
Description
S'Model_Mantissa If the Numerics Annex is not supported, this attribute yields an implementation defined value that is greater than or equal to \(\lceil d \cdot \frac{log(10)}{log(\operatorname{T'Machine\_Radix}) \rceil + 1\), where \(d\) is the requested decimal precision of T, and less than or equal to the value of T'Machine_Mantissa. See G.2.2 for further requirements that apply to implementations supporting the Numerics Annex. The value of this attribute is of the type universal_integer.
S'Model_Emin If the Numerics Annex is not supported, this attribute yields an implementation defined value that is greater than or equal to the value of T'Machine_Emin. See G.2.2 for further requirements that apply to implementations supporting the Numerics Annex. The value of this attribute is of the type universal_integer.
S'Model_Epsilon Yields the value \(\operatorname{T'Machine\_Radix}^{1 - \operatorname{T'Model\_Mantissa}}\). The value of this attribute is of the type universal_real.
S'Model_Small Yields the value \(\operatorname{T'Machine\_Radix}^{\operatorname{T'Model_Emin} - 1}}\). The value of this attribute is of the type universal_real.
S'Model S'Model denotes a function with the following specification:
function S'Model(X: T) return T
If the Numerics Annex is not supported, the meaning of this attribute is implementation defined; see G.2.2 for the definition that applies to implementations supporting the Numerics Annex.
S'Safe_First Yields the lower bound of the safe range (see 3.5.7) of the type T. If the Numerics Annex is not supported, the value of this attribute is implementation defined; see G.2.2 for the definition that applies to implementations supporting the Numerics Annex. The value of this attribute is of the type universal_real.
S'Safe_Last Yields the upper bound of the safe range (see 3.5.7) of the type T. If the Numerics Annex is not supported, the value of this attribute is implementation defined; see G.2.2 for the definition that applies to implementations supporting the Numerics Annex. The value of this attribute is of the type universal_real.

Fixed-Point Attributes#

The following representation-oriented attributes are defined for every subtype S of a fixed point type T.

Attribute
Description
S'Machine_Radix Yields the radix of the hardware representation of the type T. The value of this attribute is of the type universal_integer.
S'Machine_Rounds Yields the value True if rounding is performed on inexact results of every predefined operation that yields a result of the type T; yields the value False otherwise. The value of this attribute is of the predefined type Boolean.
S'Machine_Overflows Yields the value True if overflow and divide-by-zero are detected and reported by raising Constraint_Error for every predefined operation that yields a result of the type T; yields the value False otherwise. The value of this attribute is of the predefined type Boolean.