home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / math / kalman.src < prev    next >
Encoding:
Text File  |  1988-05-03  |  430.9 KB  |  14,737 lines

  1. --::::::::::::::::::::::::::::
  2. --CPU-TIME-CLOCK-SPEC.ADA
  3. --::::::::::::::::::::::::::::
  4.  
  5. -- This is a function to get CPU time in seconds of type DURATION
  6.  
  7. function Cpu_Time_Clock return Duration;
  8. --::::::::::::::::::::::::::::
  9. --CPU-TIME-CLOCK-BODY.TXT
  10. --::::::::::::::::::::::::::::
  11.  
  12. function Cpu_Time_Clock return Duration is
  13.  
  14.    -- This is a TeleSoft-Ada function to get CPU time in seconds 
  15.  
  16. begin
  17.  
  18.    return Duration (0.0);
  19.  
  20. end Cpu_Time_Clock;
  21. --::::::::::::::::::::::::::::
  22. --CPU-TIME-CLOCK-SPEC.ADA
  23. --::::::::::::::::::::::::::::
  24.  
  25. -- This is a function to get CPU time in seconds of type DURATION
  26.  
  27. function Cpu_Time_Clock return Duration;
  28. --::::::::::::::::::::::::::::
  29. --CPU-TIME-CLOCK-BODY.ADA
  30. --::::::::::::::::::::::::::::
  31.  
  32. with System;
  33. use System;
  34. with Condition_Handling;
  35. use Condition_Handling;
  36. with Starlet;
  37. use Starlet;
  38.  
  39. function Cpu_Time_Clock return Duration is
  40.  
  41.    -- This is a VAX Ada function to get CPU time in seconds 
  42.  
  43.    Time: Integer;
  44.    Status: Cond_Value_Type;
  45.    Item_List: constant Item_List_Type
  46.               := ((4, Jpi_Cputim, Time'Address, Address_Zero),
  47.                   (0, 0, Address_Zero, Address_Zero));
  48.  
  49. begin
  50.  
  51.    -- Call GETJPI to set CPUTIM to total accumulated CPU time 
  52.    -- (in 10-millisecond tics)
  53.  
  54.    Getjpiw (Status => Status, Itmlst => Item_List);
  55.    return Duration (Float (Time) / 100.0);
  56.  
  57. end Cpu_Time_Clock;
  58. --::::::::::::::::::::::::::::
  59. --CPU-TIME-CLOCK-BODY.ADA
  60. --::::::::::::::::::::::::::::
  61.  
  62. with System;
  63. use System;
  64. with Condition_Handling;
  65. use Condition_Handling;
  66. with Starlet;
  67. use Starlet;
  68.  
  69. function Cpu_Time_Clock return Duration is
  70.  
  71.    -- This is a VAX Ada function to get CPU time in seconds 
  72.  
  73.    Time: Integer;
  74.    Status: Cond_Value_Type;
  75.    Item_List: constant Item_List_Type
  76.               := ((4, Jpi_Cputim, Time'Address, Address_Zero),
  77.                   (0, 0, Address_Zero, Address_Zero));
  78.  
  79. begin
  80.  
  81.    -- Call GETJPI to set CPUTIM to total accumulated CPU time 
  82.    -- (in 10-millisecond tics)
  83.  
  84.    Getjpiw (Status => Status, Itmlst => Item_List);
  85.    return Duration (Float (Time) / 100.0);
  86.  
  87. end Cpu_Time_Clock;
  88. --::::::::::::::::::::::::::::
  89. --KALMAN-OPTIONS-SPEC.ADA
  90. --::::::::::::::::::::::::::::
  91.  
  92. package Kalman_Options is
  93.  
  94.    --!----------------------------------------------------------------
  95.    --!
  96.    --! Name:
  97.    --!    Kalman_Options
  98.    --!
  99.    --! Purpose:
  100.    --!    This package contains values which might be changed during 
  101.    --!    the installation of the Ada Kalman Filter. It is expected
  102.    --!    that a mature compiler would be able to recognize the
  103.    --!    values as constants and optimize away any unecessary code
  104.    --!    resulting from using the constants. In this way, a kind
  105.    --!    of macro facility can be created within the bounds of Ada.
  106.    --!
  107.    --! Globals:
  108.    --!    Execute_Debug_Code
  109.    --!       if True will execute the built-in debug code, otherwise
  110.    --!       the debug code will not be executed.
  111.    --!       
  112.    --!    Prompt_For_Math_Library
  113.    --!       if True will execute the run-time prompt for the actual
  114.    --!       math library to use, otherwise the Whitaker math library
  115.    --!       will be used.
  116.    --!
  117.    --!    Use_Fast_Matrix_Operations
  118.    --!       if True will execute the fast matrix operations instead 
  119.    --!       of the full matrix calculations, otherwise the matrix
  120.    --!       library will be used. By using the fast matrix operations
  121.    --!       an estimated 4500 floating-point multiplies will be 
  122.    --!       reduced to approximately 900.
  123.    --!       
  124.    --! Exceptions:
  125.    --!    Not applicable.
  126.    --!
  127.    --! Notes:
  128.    --!    Not applicable.
  129.    --!
  130.    --! Contract:
  131.    --!    Ada Tracking Package Using Kalman Filter Methods
  132.    --!    Contract No. N66001-85-C-0044 (31 December 1984)
  133.    --!
  134.    --! Prepared for:
  135.    --!    Naval Ocean Systems Center (WIS JPMO)
  136.    --!    271 Catalina Blvd., Building A-33
  137.    --!    San Diego, CA 92152
  138.    --!
  139.    --! Prepared by:
  140.    --!    Software Systems Engineering
  141.    --!    Federal Systems Group
  142.    --!
  143.    --!    Sanders Associates, Inc.
  144.    --!    95 Canal Street
  145.    --!    Nashua, NH 03061
  146.    --!
  147.    --! Author:
  148.    --!    Daryl R. Winters
  149.    --!
  150.    --! Changes:
  151.    --!    13-MAY-1985
  152.    --!       Changed constants to final delivery values.
  153.    --!
  154.    --!----------------------------------------------------------------
  155.  
  156.    Execute_Debug_Code         : constant Boolean := False;
  157.    Prompt_For_Math_Library    : constant Boolean := False;
  158.    Use_Fast_Matrix_Operations : constant Boolean := True;
  159.  
  160. end Kalman_Options;
  161. --::::::::::::::::::::::::::::
  162. --NUMERIC-IO-SPEC.ADA
  163. --::::::::::::::::::::::::::::
  164.  
  165.  
  166. with Text_Io; use Text_Io;
  167. package Numeric_Io is
  168.  
  169.    procedure Get (File : in File_Type; Item : out Integer);
  170.    procedure Get (Item : out Integer);
  171.    procedure Get (File : in File_Type; Item : out Float);
  172.    procedure Get (Item : out Float);
  173.    procedure Put (File : in File_Type;
  174.                   Item : in Integer; Width : in Field := Integer'Width);
  175.    procedure Put (Item : in Integer; Width : in Field := Integer'Width);
  176.    procedure Put (File : in File_Type;
  177.                   Item : in Float; Width : in Field := 2);
  178.    procedure Put (Item : in Float; Width : in Field := 2);
  179.  
  180. end Numeric_Io;
  181. --::::::::::::::::::::::::::::
  182. --NUMERIC-IO-BODY.ADA
  183. --::::::::::::::::::::::::::::
  184.  
  185.  
  186. with Text_Io;
  187. use Text_Io;
  188. package body Numeric_Io is
  189.    -- This ought to be done by instantiating the FLOAT_IO and INTEGER_IO
  190.    --  But if you dont yet have the generic TEXT_IO implemented yet
  191.    --  then something like this does the job on the DEC-10 IAPC
  192.    --  But it is a kludge
  193.    --  No effort has been put into making it pretty or portable
  194.  
  195.    package Integer_Io is new Text_Io.Integer_Io (Integer); use Integer_Io;
  196.    package Float_Io is new Text_Io.Float_Io (Float); use Float_Io;
  197.  
  198.    procedure Get (File : in File_Type; Item : out Integer) is
  199.    begin
  200.       Integer_Io.Get (File, Item);
  201.    end Get;
  202.  
  203.    procedure Get (Item : out Integer) is
  204.    begin
  205.       Integer_Io.Get (Item);
  206.    end Get;
  207.  
  208.    procedure Get (File : in File_Type; Item : out Float) is
  209.    begin
  210.       Float_Io.Get (File, Item);
  211.    end Get;
  212.  
  213.    procedure Get (Item : out Float) is
  214.    begin
  215.       Float_Io.Get (Item);
  216.    end Get;
  217.  
  218.    procedure Put (File : in File_Type;
  219.                   Item : in Integer; Width : in Field := Integer'Width) is
  220.    begin
  221.       Integer_Io.Put (File, Item, Width);
  222.    end Put;
  223.  
  224.    procedure Put (Item : in Integer; Width : in Field := Integer'Width) is
  225.    begin
  226.       Integer_Io.Put (Item, Width);
  227.    end Put;
  228.  
  229.    procedure Put (File : in File_Type;
  230.                   Item : in Float; Width : in Field := 2) is
  231.    begin
  232.       Float_Io.Put (File, Item, Width);
  233.    end Put;
  234.  
  235.    procedure Put (Item : in Float; Width : in Field := 2) is
  236.    begin
  237.       Float_Io.Put (Item, Width);
  238.    end Put;
  239.  
  240. end Numeric_Io;
  241. --::::::::::::::::::::::::::::
  242. --FLOATING-CHARACTERISTICS-SPEC.ADA
  243. --::::::::::::::::::::::::::::
  244.  
  245.  
  246. package Floating_Characteristics is
  247.    --  This package is a floating mantissa definition of a binary FLOAT 
  248.    --  It was first used on the DEC-10 and the VAX but should work for any
  249.    --  since the parameters are obtained by initializing on the actual hardware
  250.    --  Otherwise the parameters could be set in the spec if known
  251.    --  This is a preliminary package that defines the properties 
  252.    --  of the particular floating point type for which we are going to
  253.    --  generate the math routines
  254.    --  The constants are those required by the routines described in
  255.    --  "Software Manual for the Elementary Functions" W. Cody & W. Waite
  256.    --  Prentice-Hall 1980
  257.    --  Actually most are needed only for the test programs
  258.    --  rather than the functions themselves, but might as well be here
  259.    --  Most of these could be in the form of attributes if 
  260.    --  all the floating types to be considered were those built into the
  261.    --  compiler, but we also want to be able to support user defined types
  262.    --  such as software floating types of greater precision than
  263.    --  the hardware affords, or types defined on one machine to
  264.    --  simulate another
  265.    --  So we use the Cody-Waite names and derive them from an adaptation of the
  266.    --  MACHAR routine as given by Cody-Waite in Appendix B
  267.  
  268.     Ibeta : Integer;
  269.     --  The radix of the floating-point representation
  270.  
  271.     It : Integer;
  272.     --  The number of base IBETA digits in the DIS_FLOAT significand
  273.  
  274.     Irnd : Integer;
  275.     --  TRUE (1) if floating addition rounds, FALSE (0) if truncates
  276.  
  277.     Ngrd : Integer;
  278.     --  Number of guard digits for multiplication
  279.  
  280.     Machep : Integer;
  281.     --  The largest negative integer such that
  282.     --    1.0 + FLOAT (IBETA) ** MACHEP /= 1.0
  283.     --  except that MACHEP is bounded below by - (IT + 3)
  284.  
  285.     Negep : Integer;
  286.     --  The largest negative integer such that
  287.     --    1.0 -0 FLOAT (IBETA) ** NEGEP /= 1.0
  288.     --  except that NEGEP is bounded below by - (IT + 3)
  289.  
  290.     Iexp : Integer;
  291.     --  The number of bits (decimal places if IBETA = 10)
  292.     --  reserved for the representation of the exponent (including
  293.     --  the bias or sign) of a floating-point number
  294.  
  295.     Minexp : Integer;
  296.     --  The largest in magnitude negative integer such that
  297.     --  FLOAT (IBETA) ** MINEXP is a positive floating-point number
  298.  
  299.  
  300.     Maxexp : Integer;
  301.     --  The largest positive exponent for a finite floating-point number
  302.  
  303.     Eps : Float;
  304.     --  The smallest positive floating-point number such that
  305.     --                              1.0 + EPS /= 1.0
  306.     --  In particular, if IBETA = 2 or IRND = 0,
  307.     --  EPS = FLOAT (IBETA) ** MACHEP
  308.     --  Otherwise, EPS = (FLOAT (IBETA) ** MACHEP) / 2
  309.  
  310.  
  311.     Epsneg : Float;
  312.     --  A small positive floating-point number such that 1.0-EPSNEG /= 1.0
  313.  
  314.     Xmin : Float;
  315.     --  The smallest non-vanishing floating-point power of the radix
  316.     --  In particular, XMIN = FLOAT (IBETA) ** MINEXP
  317.  
  318.     Xmax : Float;
  319.     --  The largest finite floating-point number
  320.  
  321.    --  Here the structure of the floating type is defined
  322.    --  I have assumed that the exponent is always some integer form
  323.    --  The mantissa can vary
  324.    --  Most often it will be a fixed type or the same floating type
  325.    --  depending on the most efficient machine implementation
  326.    --  Most efficient implementation may require details of the machine hardware
  327.    --  In this version the simplest representation is used
  328.    --  The mantissa is extracted into a FLOAT and uses the predefined operations
  329.    subtype Exponent_Type is Integer;    --  should be derived  ##########
  330.    subtype Mantissa_Type is Float;     --   range -1.0..1.0;
  331.    --  A consequence of the rigorous constraints on MANTISSA_TYPE is that 
  332.    --  operations must be very carefully examined to make sure that no number
  333.    --  greater than one results
  334.    --  Actually this limitation is important in constructing algorithms
  335.    --  which will also run when MANTISSA_TYPE is a fixed point type
  336.  
  337.    --  If we are not using the STANDARD type, we have to define all the 
  338.    --  operations at this point
  339.    --  We also need PUT for the type if it is not otherwise available
  340.  
  341.    --  Now we do something strange
  342.    --  Since we do not know in the following routines whether the mantissa
  343.    --  will be carried as a fixed or floating type, we have to make some
  344.    --  provision for dividing by two
  345.    --  We cannot use the literals, since FIXED/2.0 and FLOAT/2 will fail
  346.    --  We define a type-dependent factor that will work
  347.    Mantissa_Divisor_2 : constant Float := 2.0;
  348.    Mantissa_Divisor_3 : constant Float := 3.0;
  349.    --  This will work for the MANTISSA_TYPE defined above
  350.    --  The alternative of defining an operation "/" to take care of it
  351.    --  is too sweeping and would allow unAda-like errors
  352.  
  353.    Mantissa_Half : constant Mantissa_Type := 0.5;
  354.  
  355.  
  356.    procedure Defloat (X : in Float;
  357.                       N : in out Exponent_Type; F : in out Mantissa_Type);
  358.    procedure Refloat (N : in Exponent_Type; F : in Mantissa_Type;
  359.                                                    X : in out Float);
  360.    --  Since the user may wish to define a floating type by some other name
  361.    --  CONVERT_TO_FLOAT is used rather than just FLOAT for explicit coersion
  362.    function Convert_To_Float (K : Integer) return Float;
  363.    --  function Convert_To_Float (N : Exponent_Type) return Float;
  364.    function Convert_To_Float (F : Mantissa_Type) return Float;
  365.  
  366. end Floating_Characteristics;
  367. --::::::::::::::::::::::::::::
  368. --FLOATING-CHARACTERISTICS-BODY.ADA
  369. --::::::::::::::::::::::::::::
  370.  
  371.  
  372. with Text_Io; use Text_Io;
  373. package body Floating_Characteristics is
  374.    --  This package is a floating mantissa definition of a binary FLOAT
  375.  
  376.     A, B, Y, Z : Float;
  377.     I, K, Mx, Iz : Integer;
  378.     Beta, Betam1, Betain : Float;
  379.     One : Float := 1.0;
  380.     Zero : Float := 0.0;
  381.  
  382.    procedure Defloat (X : in Float;
  383.                       N : in out Exponent_Type; F : in out Mantissa_Type) is
  384.       --  This is admittedly a slow method - but portable - for breaking down
  385.       --  a floating point number into its exponent and mantissa
  386.       --  Obviously with knowledge of the machine representation
  387.       --  it could be replaced with a couple of simple extractions
  388.       Exponent_Length : Integer := Iexp;
  389.       M : Exponent_Type;
  390.       W, Y, Z : Float;
  391.    begin
  392.       N := 0;
  393.       F := 0.0;
  394.       Y := abs (X);
  395.       if Y = 0.0  then
  396.          return;
  397.       elsif Y < 0.5  then
  398.          for J in reverse 0.. (Exponent_Length - 2)  loop
  399.             --  Dont want to go all the way to 2.0** (EXPONENT_LENGTH - 1)
  400.             --  Since that (or its reciprocal) will overflow if exponent biased
  401.             --  Ought to use talbular values rather than compute each time
  402.             M := Exponent_Type (2 ** J);
  403.             Z := 1.0 / (2.0**M);
  404.             W := Y / Z;
  405.             if W < 1.0  then
  406.                Y := W;
  407.                N := N - M;
  408.             end if;
  409.          end loop;
  410.       else
  411.          for J in reverse 0.. (Exponent_Length - 2)  loop
  412.             M := Exponent_Type (2 ** J);
  413.             Z := 2.0**M;
  414.             W := Y / Z;
  415.             if W >= 0.5  then
  416.                Y := W;
  417.                N := N + M;
  418.             end if;
  419.          end loop;
  420.          --  And just to clear up any loose ends from biased exponents
  421.       end if;
  422.       while Y < 0.5  loop
  423.          Y := Y * 2.0;
  424.          N := N - 1;
  425.       end loop;
  426.       while Y >= 1.0  loop
  427.          Y := Y / 2.0;
  428.          N := N + 1;
  429.       end loop;
  430.       F := Mantissa_Type (Y);
  431.       if X < 0.0  then
  432.          F := -F;
  433.       end if;
  434.       return;
  435.    exception
  436.       when others =>
  437.          N := 0;
  438.          F := 0.0;
  439.          return;
  440.    end Defloat;
  441.  
  442.  
  443.    procedure Refloat (N : in Exponent_Type; F : in Mantissa_Type;
  444.                                                    X : in out Float) is
  445.       --  Again a brute force method - but portable
  446.       --  Watch out near MAXEXP
  447.       M : Integer;
  448.       Y : Float;
  449.    begin
  450.       if F = 0.0  then
  451.          X := Zero;
  452.          return;
  453.       end if;
  454.       M := Integer (N);
  455.       Y := abs (Float (F));
  456.       while Y < 0.5  loop
  457.          M := M - 1;
  458.          if M < Minexp  then
  459.             X := Zero;
  460.          end if;
  461.          Y := Y + Y;
  462.          exit when M <= Minexp;
  463.       end loop;
  464.       if M = Maxexp  then
  465.          M := M - 1;
  466.          X := Y * 2.0**M;
  467.          X := X * 2.0;
  468.       elsif M <= Minexp + 2  then
  469.          M := M + 3;
  470.          X := Y * 2.0**M;
  471.          X := ((X / 2.0) / 2.0) / 2.0;
  472.       else
  473.          X := Y * 2.0**M;
  474.       end if;
  475.       if F < 0.0  then
  476.          X := -X;
  477.       end if;
  478.       return;
  479.    end Refloat;
  480.  
  481.    function Convert_To_Float (K : Integer) return Float is
  482.    begin
  483.       return Float (K);
  484.    end Convert_To_Float;
  485.  
  486.    -- function Convert_To_Float (N : Exponent_Type) return Float is
  487.    -- begin
  488.    --    return Float (N);
  489.    -- end Convert_To_Float;
  490.  
  491.    function Convert_To_Float (F : Mantissa_Type) return Float is
  492.    begin
  493.       return Float (F);
  494.    end Convert_To_Float;
  495.  
  496.  
  497. begin
  498.    --  Initialization for the VAX with values derived by MACHAR
  499.    --  In place of running MACHAR as the actual initialization
  500.  
  501.     Ibeta :=    2;
  502.     It :=    24;
  503.     Irnd :=    1;
  504.     Negep :=    -24;
  505.     Epsneg :=    5.9604644E-008;
  506.     Machep :=    -24;
  507.     Eps :=    5.9604644E-008;
  508.     Ngrd :=    0;
  509.     Xmin := 5.9E-39;
  510.     Minexp :=    -126;
  511.     Iexp :=    8;
  512.     Maxexp :=    127;
  513.     Xmax :=    8.5E37 * 2.0;
  514.  
  515.  
  516.    ----  This initialization is the MACHAR routine of Cody and Waite Appendix B.
  517.    --PUT ("INITIALIZATING WITH MACHAR     -     ");
  518.    --    A := ONE;
  519.    --    while (((A + ONE) - A) - ONE) = ZERO  loop
  520.    --      A := A + A;
  521.    --    end loop;
  522.    --    B := ONE;
  523.    --    while ((A + B) - A) = ZERO  loop
  524.    --      B := B + B;
  525.    --    end loop;
  526.    --    IBETA := INTEGER ((A + B) - A);
  527.    --    BETA := CONVERT_TO_FLOAT (IBETA);
  528.    --
  529.    --
  530.    --    IT := 0;
  531.    --    B := ONE;
  532.    --    while (((B + ONE) - B) - ONE) = ZERO  loop
  533.    --      IT := IT + 1;
  534.    --      B := B * BETA;
  535.    --    end loop;
  536.    --
  537.    --
  538.    --    IRND := 0;
  539.    --    BETAM1 := BETA - ONE;
  540.    --    if ((A + BETAM1) - A) /= ZERO  then
  541.    --      IRND := 1;
  542.    --    end if;
  543.    --
  544.    --
  545.    --    NEGEP := IT + 3;
  546.    --    BETAIN := ONE / BETA;
  547.    --    A := ONE;
  548.    --  --  for I in 1..NEGEP  loop
  549.    --  for I in 1..50  loop
  550.    --  exit when I > NEGEP;
  551.    --      A := A * BETAIN;
  552.    --    end loop;
  553.    --    B := A;
  554.    --    while ((ONE - A) - ONE) = ZERO  loop
  555.    --      A := A * BETA;
  556.    --      NEGEP := NEGEP - 1;
  557.    --    end loop;
  558.    --    NEGEP := -NEGEP;
  559.    --
  560.    --
  561.    --    EPSNEG := A;
  562.    --    if (IBETA /= 2) and (IRND /= 0)  then
  563.    --      A := (A * (ONE + A)) / (ONE + ONE);
  564.    --      if ((ONE - A) - ONE) /= ZERO  then
  565.    --        EPSNEG := A;
  566.    --      end if;
  567.    --    end if;
  568.    --
  569.    --
  570.    --    MACHEP := -IT - 3;
  571.    --    A := B;
  572.    --    while ((ONE + A) - ONE) = ZERO  loop
  573.    --      A := A * BETA;
  574.    --      MACHEP := MACHEP + 1;
  575.    --    end loop;
  576.    --
  577.    --
  578.    --    EPS := A;
  579.    --    if (IBETA /= 2) and (IRND /= 0)  then
  580.    --      A := (A * (ONE + A)) / (ONE + ONE);
  581.    --      if ((ONE + A) - ONE) /= ZERO  then
  582.    --        EPS := A;
  583.    --      end if;
  584.    --    end if;
  585.    --
  586.    --
  587.    --    NGRD := 0;
  588.    --    if ((IRND = 0) and ((ONE + EPS) * ONE - ONE) /= ZERO)  then
  589.    --      NGRD := 1;
  590.    --    end if;
  591.    --
  592.    --
  593.    --    I := 0;
  594.    --    K := 1;
  595.    --    Z := BETAIN;
  596.    --    loop
  597.    --      Y := Z;
  598.    --      Z := Y * Y;
  599.    --      A := Z * ONE;
  600.    --      exit when ((A + A) = ZERO) or (ABS (Z) >= Y);
  601.    --      I := I + 1;
  602.    --      K := K + K;
  603.    --    end loop;
  604.    --    if (IBETA /= 10)  then
  605.    --      IEXP := I + 1;
  606.    --      MX := K + K;
  607.    --    else
  608.    --      IEXP := 2;
  609.    --      IZ := IBETA;
  610.    --      while (K >= IZ)  loop
  611.    --        IZ := IZ * IBETA;
  612.    --        IEXP := IEXP + 1;
  613.    --      end loop;
  614.    --      MX := IZ + IZ - 1;
  615.    --    end if;
  616.    --
  617.    --    loop
  618.    --      XMIN := Y;
  619.    --      Y := Y * BETAIN;
  620.    --      A := Y * ONE;
  621.    --      exit when ((A + A) = ZERO) or (ABS (Y) >= XMIN);
  622.    --      K := K + 1;
  623.    --    end loop;
  624.    --
  625.    --
  626.    --    MINEXP := -K;
  627.    --
  628.    --
  629.    --    if ((MX <= (K + K - 3)) and (IBETA /= 10))  then
  630.    --      MX := MX + MX;
  631.    --      IEXP := IEXP + 1;
  632.    --    end if;
  633.    --
  634.    --
  635.    --    MAXEXP := MX + MINEXP;
  636.    --    I := MAXEXP + MINEXP;
  637.    --    if ((IBETA = 2) and (I = 0))  then
  638.    --      MAXEXP := MAXEXP - 1;
  639.    --    end if;
  640.    --    if (I > 20)  then
  641.    --      MAXEXP := MAXEXP - 1;
  642.    --    end if;
  643.    --    if (A /= Y)  then
  644.    --      MAXEXP := MAXEXP - 2;
  645.    --    end if;
  646.    --
  647.    --
  648.    --    XMAX := ONE - EPSNEG;
  649.    --    if ((XMAX * ONE) /= XMAX)  then
  650.    --      XMAX := ONE - BETA * EPSNEG;
  651.    --    end if;
  652.    --    XMAX := XMAX / (BETA * BETA * BETA * XMIN);
  653.    --    I := MAXEXP + MINEXP + 3;
  654.    --    if I > 0  then
  655.    --      for J in 1..50  loop
  656.    --  exit when J > I;
  657.    --        if IBETA = 2  then
  658.    --          XMAX := XMAX + XMAX;
  659.    --        else
  660.    --          XMAX := XMAX * BETA;
  661.    --        end if;
  662.    --      end loop;
  663.    --    end if;
  664.    --
  665.    --PUT ("INITIALIZED"); NEW_LINE;
  666.  
  667. end Floating_Characteristics;
  668. --::::::::::::::::::::::::::::
  669. --NUMERIC-PRIMITIVES-SPEC.ADA
  670. --::::::::::::::::::::::::::::
  671.  
  672.  
  673. with Floating_Characteristics; use Floating_Characteristics;
  674. package Numeric_Primitives is
  675.  
  676.    --  This may seem a little much but is put in this form to allow the
  677.    --  same form to be used for a generic package
  678.    --  If that is not needed, simple litterals could be substituted
  679.    Zero  : Float := Convert_To_Float (Integer (0));
  680.    One   : Float := Convert_To_Float (Integer (1));
  681.    Two   : Float := One + One;
  682.    Three : Float := One + One + One;
  683.    Half  : Float := One / Two;
  684.  
  685.    --  The following "constants" are effectively deferred to
  686.    --  the initialization part of the package body
  687.    --  This is in order to make it possible to generalize the floating type
  688.    --  If that capability is not desired, constants may be included here
  689.    Pi            : Float;
  690.    One_Over_Pi   : Float;
  691.    Two_Over_Pi   : Float;
  692.    Pi_Over_Two   : Float;
  693.    Pi_Over_Three : Float;
  694.    Pi_Over_Four  : Float;
  695.    Pi_Over_Six   : Float;
  696.  
  697.  
  698.    function Sign (X, Y : Float) return Float;
  699.     --  Returns the value of X with the sign of Y
  700.    function Max (X, Y :  Float) return Float;
  701.     --  Returns the algebraicly larger of X and Y
  702.    function Truncate (X : Float) return Float;
  703.     --  Returns the floating value of the integer no larger than X
  704.     --  AINT (X)
  705.    function Round (X : Float) return Float;
  706.     --  Returns the floating value nearest X
  707.     --  AINTRND (X)
  708.    function Ran return Float;
  709.     --  This uses a portable algorithm and is included at this point
  710.     --  Algorithms that presume unique machine hardware information
  711.     --  should be initiated in FLOATING_CHARACTERISTICS
  712.  
  713. end Numeric_Primitives;
  714. --::::::::::::::::::::::::::::
  715. --NUMERIC-PRIMITIVES-BODY.ADA
  716. --::::::::::::::::::::::::::::
  717.  
  718.  
  719. with Floating_Characteristics; use Floating_Characteristics;
  720. package body Numeric_Primitives is
  721.  
  722.    function Sign (X, Y : Float) return Float is
  723.       --  Returns the value of X with the sign of Y
  724.    begin
  725.       if Y >= 0.0  then
  726.          return X;
  727.       else
  728.          return -X;
  729.       end if;
  730.    end Sign;
  731.  
  732.    function Max (X, Y : Float) return Float is
  733.    begin
  734.       if X >= Y  then
  735.          return X;
  736.       else
  737.          return Y;
  738.       end if;
  739.    end Max;
  740.  
  741.    function Truncate (X : Float) return Float is
  742.       --  Optimum code depends on how the system rounds at exact halves
  743.    begin
  744.       if Float (Integer (X)) = X  then
  745.          return X;
  746.       end if;
  747.       if X > Zero  then
  748.          return Float (Integer (X - Half));
  749.       elsif X = Zero  then
  750.          return Zero;
  751.       else
  752.          return Float (Integer (X + Half));
  753.       end if;
  754.    end Truncate;
  755.  
  756.    function Round (X : Float) return Float is
  757.    begin
  758.       return Float (Integer (X));
  759.    end Round;
  760.  
  761.  
  762.    package Key is
  763.       X : Integer := 10_001;
  764.       Y : Integer := 20_001;
  765.       Z : Integer := 30_001;
  766.    end Key;
  767.  
  768.    function Ran return Float is
  769.       --  This rectangular random number routine is adapted from a report
  770.       --  "A Pseudo-Random Number Generator" by B. A. Wichmann and I. D. Hill
  771.       --  NPL Report DNACS XX (to be published)
  772.       --  In this stripped version, it is suitable for machines supporting 
  773.       --  INTEGER at only 16 bits and is portable in Ada
  774.       W : Float;
  775.    begin
  776.  
  777.       Key.X := 171 * (Key.X mod 177 - 177) -  2 * (Key.X / 177);
  778.       if Key.X < 0  then
  779.          Key.X := Key.X + 30269;
  780.       end if;
  781.  
  782.       Key.Y := 172 * (Key.Y mod 176 - 176) - 35 * (Key.Y / 176);
  783.       if Key.Y < 0  then
  784.          Key.Y := Key.Y + 30307;
  785.       end if;
  786.  
  787.       Key.Z := 170 * (Key.Z mod 178 - 178) - 63 * (Key.Z / 178);
  788.       if Key.Z < 0  then
  789.          Key.Z := Key.Z + 30323;
  790.       end if;
  791.  
  792.       --  CONVERT_TO_FLOAT is used instead of FLOAT since the floating
  793.       --  type may be software defined
  794.  
  795.       W :=     Convert_To_Float (Key.X)/30269.0
  796.            + Convert_To_Float (Key.Y)/30307.0
  797.            + Convert_To_Float (Key.Z)/30323.0;
  798.  
  799.       return  W - Convert_To_Float (Integer (W - 0.5));
  800.  
  801.    end Ran;
  802.  
  803. begin
  804.    Pi            := Convert_To_Float (Integer (3)) +
  805.                     Convert_To_Float (Mantissa_Type (0.14159_26535_89793_23846));
  806.    One_Over_Pi   := Convert_To_Float (Mantissa_Type (0.31830_98861_83790_67154));
  807.    Two_Over_Pi   := Convert_To_Float (Mantissa_Type (0.63661_97723_67581_34308));
  808.    Pi_Over_Two   := Convert_To_Float (Integer (1)) +
  809.                     Convert_To_Float (Mantissa_Type (0.57079_63267_94896_61923));
  810.    Pi_Over_Three := Convert_To_Float (Integer (1)) +
  811.                     Convert_To_Float (Mantissa_Type (0.04719_75511_96597_74615));
  812.    Pi_Over_Four  := Convert_To_Float (Mantissa_Type (0.78539_81633_97448_30962));
  813.    Pi_Over_Six   := Convert_To_Float (Mantissa_Type (0.52359_87755_98298_87308));
  814.  
  815. end Numeric_Primitives;
  816.  
  817. with Floating_Characteristics; use Floating_Characteristics;
  818. package Core_Functions is
  819.  
  820.    Exp_Large : Float;
  821.    Exp_Small : Float;
  822.  
  823.    function Sqrt (X : Float) return Float;
  824.    function Cbrt (X : Float) return Float;
  825.    function Log (X : Float) return Float;
  826.    function Log10 (X : Float) return Float;
  827.    function Exp (X : Float) return Float;
  828.    function "**" (X, Y : Float) return Float;
  829.  
  830. end Core_Functions;
  831.  
  832. --::::::::::::::::::::::::::::
  833. --CORE-FUNCTIONS-BODY.ADA
  834. --::::::::::::::::::::::::::::
  835.  
  836.  
  837. with Text_Io; use Text_Io;
  838. with Floating_Characteristics; use Floating_Characteristics;
  839. with Numeric_Io; use Numeric_Io;
  840. with Numeric_Primitives; use Numeric_Primitives;
  841. package body Core_Functions is
  842.  
  843.    --  The following routines are coded directly from the algorithms and
  844.    --  coeficients given in "Software Manual for the Elementry Functions"
  845.    --  by William J. Cody, Jr. and William Waite, Prentice_Hall, 1980
  846.    --  CBRT by analogy
  847.    --  A more general formulation uses MANTISSA_TYPE, etc.
  848.    --  The coeficients are appropriate for 25 to 32 bits floating significance
  849.    --  They will work for less but slightly shorter versions are possible
  850.    --  The routines are coded to stand alone so they need not be compiled together
  851.  
  852.    --  These routines have been coded to accept a general MANTISSA_TYPE
  853.    --  That is, they are designed to work with a manitssa either fixed of float
  854.    --  There are some explicit conversions which are required but these will
  855.    --  not cause any extra code to be generated
  856.  
  857.    --      16 JULY 1982       W A WHITAKER  AFATL EGLIN AFB FL 32542
  858.    --                         T C EICHOLTZ  USAFA
  859.  
  860.  
  861.    function Sqrt (X : Float) return Float is
  862.       M, N : Exponent_Type;
  863.       F, Y : Mantissa_Type;
  864.       Result : Float;
  865.  
  866.       subtype Index is Integer range 0..100;    --  #########################
  867.       Sqrt_L1 : Index := 3;
  868.       --  Could get away with SQRT_L1 := 2 for 28 bits
  869.       --  Using the better Cody-Waite coeficients overflows MANTISSA_TYPE
  870.       Sqrt_C1 : Mantissa_Type := 8#0.3317777777#;
  871.       Sqrt_C2 : Mantissa_Type := 8#0.4460000000#;
  872.       Sqrt_C3 : Mantissa_Type := 8#0.55202_36314_77747_36311_0#;
  873.  
  874.    begin
  875.       if X = Zero  then
  876.          Result := Zero;
  877.          return Result;
  878.       elsif X = One  then            --  To get exact SQRT (1.0)
  879.          Result := One;
  880.          return Result;
  881.       elsif X < Zero  then
  882.          New_Line;
  883.          Put ("*** ERROR: CALLED SQRT FOR NEGATIVE ARGUMENT ");
  884.          Put (X);
  885.          Put ("  USED ABSOLUTE VALUE ***");
  886.          New_Line;
  887.          Result := Sqrt (abs (X));
  888.          return Result;
  889.       else
  890.          Defloat (X, N, F);
  891.          Y := Sqrt_C1 + Mantissa_Type (Sqrt_C2 * F);
  892.          for J in 1..Sqrt_L1  loop
  893.             Y := Y/Mantissa_Divisor_2 + Mantissa_Type ((F/Mantissa_Divisor_2)/Y);
  894.          end loop;
  895.          if (N mod 2) /= 0  then
  896.             Y := Mantissa_Type (Sqrt_C3 * Y);
  897.             N := N + 1;
  898.          end if;
  899.          M := N/2;
  900.          Refloat (M,Y,Result);
  901.          return Result;
  902.       end if;
  903.    exception
  904.       when others =>
  905.          New_Line;
  906.          Put ("*** ERROR: EXCEPTION IN SQRT, X = ");
  907.          Put (X);
  908.          Put ("  RETURNED 1.0 ***");
  909.          New_Line;
  910.          return One;
  911.    end Sqrt;
  912.  
  913.  
  914.    function Cbrt (X : Float) return Float is
  915.       M, N : Exponent_Type;
  916.       F, Y : Mantissa_Type;
  917.       Result : Float;
  918.  
  919.       subtype Index is Integer range 0..100;    --  #########################
  920.       Cbrt_L1 : Index := 3;
  921.       Cbrt_C1 : Mantissa_Type := 0.5874009;
  922.       Cbrt_C2 : Mantissa_Type := 0.4125990;
  923.       Cbrt_C3 : Mantissa_Type := 0.62996_05249;
  924.       Cbrt_C4 : Mantissa_Type := 0.79370_05260;
  925.  
  926.    begin
  927.       if X = Zero then
  928.          Result := Zero;
  929.          return Result;
  930.       else
  931.          Defloat (X, N, F);
  932.          F := abs (F);
  933.          Y := Cbrt_C1 + Mantissa_Type (Cbrt_C2 * F);
  934.          for J in 1 .. Cbrt_L1 loop
  935.             Y :=     Y
  936.                  - (  Y/Mantissa_Divisor_3
  937.                     - Mantissa_Type ((F/Mantissa_Divisor_3) / Mantissa_Type (Y*Y)) );
  938.          end loop;
  939.          case (N mod 3) is
  940.             when 0 =>
  941.                null;
  942.             when 1 =>
  943.                Y := Mantissa_Type (Cbrt_C3 * Y);
  944.                N := N + 2;
  945.             when 2 =>
  946.                Y := Mantissa_Type (Cbrt_C4 * Y);
  947.                N := N + 1;
  948.             when others =>
  949.                null;
  950.          end case;
  951.          M := N/3;
  952.          if X < Zero  then
  953.             Y := -Y;
  954.          end if;
  955.          Refloat (M, Y, Result);
  956.          return Result;
  957.       end if;
  958.    exception
  959.       when others =>
  960.          Result := One;
  961.          if X < Zero then
  962.             Result := - One;
  963.          end if;
  964.          New_Line;
  965.          Put ("*** ERROR: EXCEPTION IN CBRT, X = ");
  966.          Put (X);
  967.          Put ("  RETURNED  ");
  968.          Put (Result);
  969.          Put (" ***");
  970.          New_Line;
  971.          return Result;
  972.    end Cbrt;
  973.  
  974.    function Log (X : Float) return Float is
  975.       --  Uses fixed formulation for generality
  976.  
  977.       Result : Float;
  978.       N : Exponent_Type;
  979.       Xn : Float;
  980.       Y : Float;
  981.       F : Mantissa_Type;
  982.       Z, Zden, Znum : Mantissa_Type;
  983.  
  984.       C0 : constant Mantissa_Type := 0.20710_67811_86547_52440;
  985.       --  SQRT (0.5) - 0.5
  986.       C1 : constant Float := 8#0.543#;
  987.       C2 : constant Float :=-2.12194_44005_46905_82767_9E-4;
  988.  
  989.       function R (Z : Mantissa_Type) return Mantissa_Type is
  990.          --  Use fixed formulation here because the float coeficents are > 1.0
  991.          --  and would exceed the limits on a MANTISSA_TYPE
  992.          A0 : constant Mantissa_Type := 0.04862_85276_587;
  993.          B0 : constant Mantissa_Type := 0.69735_92187_803;
  994.          B1 : constant Mantissa_Type :=-0.125;
  995.          C  : constant Mantissa_Type := 0.01360_09546_862;
  996.       begin
  997.          return Z + Mantissa_Type (Z *
  998.                                    Mantissa_Type (Mantissa_Type (Z * Z) * (C +
  999.                                                                            Mantissa_Type (A0/ (B0 + Mantissa_Type (B1 *
  1000.  
  1001.  
  1002.                                                                                                            Mantissa_Type
  1003.                                                                                                                    (Z *
  1004.                                                                                                                     Z)))
  1005.                                                                            ))
  1006.                                    ));
  1007.       end R;
  1008.  
  1009.    begin
  1010.  
  1011.       if X < Zero          then
  1012.          New_Line;
  1013.          Put ("*** ERROR: CALLED LOG FOR NEGATIVE ");
  1014.          Put (X);
  1015.          Put (" USED ABS => ");
  1016.          Result := Log (abs (X));
  1017.          Put (Result);
  1018.          Put (" ***");
  1019.          New_Line;
  1020.       elsif X = Zero  then
  1021.          New_Line;
  1022.          Put ("*** ERROR: CALLED LOG FOR ZERO ARGUMENT, RETURNED ");
  1023.          Result := -Xmax;      --  SUPPOSED TO BE -LARGE
  1024.          Put (Result);
  1025.          Put (" ***");
  1026.          New_Line;
  1027.       else
  1028.          Defloat (X,N,F);
  1029.          Znum := F - Mantissa_Half;
  1030.          Y := Convert_To_Float (Znum);
  1031.          Zden := Znum / Mantissa_Divisor_2 + Mantissa_Half;
  1032.          if Znum > C0  then
  1033.             Y := Y - Mantissa_Half;
  1034.             Znum := Znum - Mantissa_Half;
  1035.             Zden := Zden + Mantissa_Half/Mantissa_Divisor_2;
  1036.          else
  1037.             N := N -1;
  1038.          end if;
  1039.          Z    := Mantissa_Type (Znum / Zden);
  1040.          Result := Convert_To_Float (R (Z));
  1041.          if N /= 0  then
  1042.             Xn := Convert_To_Float (N);
  1043.             Result := (Xn * C2 + Result) + Xn * C1;
  1044.          end if;
  1045.       end if;
  1046.       return Result;
  1047.  
  1048.    exception
  1049.       when others =>
  1050.          New_Line;
  1051.          Put ("*** ERROR: EXCEPTION IN LOG, X = ");
  1052.          Put (X);
  1053.          Put ("  RETURNED 0.0 ***");
  1054.          New_Line;
  1055.          return Zero;
  1056.    end Log;
  1057.  
  1058.  
  1059.    function Log10 (X : Float) return Float is
  1060.       Log_10_Of_2 : constant Float :=
  1061.                     Convert_To_Float (Mantissa_Type (8#0.33626_75425_11562_41615#));
  1062.    begin
  1063.       return Log (X) * Log_10_Of_2;
  1064.    end Log10;
  1065.  
  1066.    function Exp (X : Float) return Float is
  1067.  
  1068.       Result : Float;
  1069.       N : Exponent_Type;
  1070.       Xg, Xn, X1, X2 : Float;
  1071.       F, G : Mantissa_Type;
  1072.  
  1073.       Bigx : Float := Exp_Large;
  1074.       Smallx : Float := Exp_Small;
  1075.  
  1076.       One_Over_Log_2 : constant Float :=  1.4426_95040_88896_34074;
  1077.       C1 : constant Float :=  0.69335_9375;
  1078.       C2 : constant Float := -2.1219_44400_54690_58277E-4;
  1079.  
  1080.       function R (G : Mantissa_Type) return Mantissa_Type is
  1081.          Z , Gp, Q : Mantissa_Type;
  1082.  
  1083.          P0 : constant Mantissa_Type :=  0.24999_99999_9992;
  1084.          P1 : constant Mantissa_Type :=  0.00595_04254_9776;
  1085.          Q0 : constant Mantissa_Type :=  0.5;
  1086.          Q1 : constant Mantissa_Type :=  0.05356_75176_4522;
  1087.          Q2 : constant Mantissa_Type :=  0.00029_72936_3682;
  1088.       begin
  1089.          Z  := Mantissa_Type (G * G);
  1090.          Gp := Mantissa_Type ((Mantissa_Type (P1 * Z) + P0) * G );
  1091.          Q  := Mantissa_Type ((Mantissa_Type (Q2 * Z) + Q1) * Z ) + Q0;
  1092.          return Mantissa_Half + Mantissa_Type ( Gp / (Q - Gp) );
  1093.       end R;
  1094.  
  1095.  
  1096.    begin
  1097.  
  1098.       if X > Bigx  then
  1099.          New_Line;
  1100.          Put ("*** ERROR: EXP CALLED WITH TOO BIG A POSITIVE ARGUMENT, ");
  1101.          Put (X);
  1102.          Put ("   RETURNED XMAX ***");
  1103.          New_Line;
  1104.          Result := Xmax;
  1105.       elsif X < Smallx  then
  1106.          New_Line;
  1107.          Put ("*** ERROR: EXP CALLED WITH TOO BIG A NEGATIVE ARGUMENT, ");
  1108.          Put (X);
  1109.          Put ("  RETURNED ZERO ***");
  1110.          New_Line;
  1111.          Result := Zero;
  1112.       elsif abs (X) < Eps  then
  1113.          Result := One;
  1114.       else
  1115.          N  := Exponent_Type (X * One_Over_Log_2);
  1116.          Xn := Convert_To_Float (N);
  1117.          X1 := Round (X);
  1118.          X2 := X - X1;
  1119.          Xg := ((X1 - Xn * C1) + X2 ) - Xn * C2;
  1120.          G  := Mantissa_Type (Xg);
  1121.          N  := N + 1;
  1122.          F := R (G);
  1123.          Refloat (N, F, Result);
  1124.       end if;
  1125.       return Result;
  1126.  
  1127.    exception
  1128.       when others =>
  1129.          New_Line;
  1130.          Put ("*** ERROR: EXCEPTION IN EXP, X = ");
  1131.          Put (X);
  1132.          Put ("  RETURNED 1.0 ***");
  1133.          New_Line;
  1134.          return One;
  1135.    end Exp;
  1136.  
  1137.    function "**" (X, Y : Float) return Float is
  1138.       --  This is the last function to be coded since it appeared that it really
  1139.       --  was un-Ada-like and ought not be in the regular package
  1140.       --  Nevertheless it was included in this version
  1141.       --  It is specific for FLOAT and does not have the MANTISSA_TYPE generality
  1142.       M, N : Exponent_Type;
  1143.       G : Mantissa_Type;
  1144.       P, Temp, Iw1, I : Integer;
  1145.       Result, Z, V, R, U1, U2, W, W1, W2, W3, Y1, Y2 : Float;
  1146.  
  1147.       K : constant Float := 0.44269_50408_88963_40736;
  1148.       Ibigx : constant Integer := Integer (Truncate (16.0 * Log (Xmax) - 1.0));
  1149.       Ismallx : constant Integer := Integer (Truncate (16.0 * Log (Xmin) + 1.0));
  1150.  
  1151.       P1 : constant Float := 0.83333_32862_45E-1;
  1152.       P2 : constant Float := 0.12506_48500_52E-1;
  1153.  
  1154.       Q1 : constant Float := 0.69314_71805_56341;
  1155.       Q2 : constant Float := 0.24022_65061_44710;
  1156.       Q3 : constant Float := 0.55504_04881_30765E-1;
  1157.       Q4 : constant Float := 0.96162_06595_83789E-2;
  1158.       Q5 : constant Float := 0.13052_55159_42810E-2;
  1159.  
  1160.       A1 : array (1 .. 17) of Float:=
  1161.                  (  8#1.00000_0000#,
  1162.                   8#0.75222_5750#,
  1163.                   8#0.72540_3067#,
  1164.                   8#0.70146_3367#,
  1165.                   8#0.65642_3746#,
  1166.                   8#0.63422_2140#,
  1167.                   8#0.61263_4520#,
  1168.                   8#0.57204_2434#,
  1169.                   8#0.55202_3631#,
  1170.                   8#0.53254_0767#,
  1171.                   8#0.51377_3265#,
  1172.                   8#0.47572_4623#,
  1173.                   8#0.46033_7602#,
  1174.                   8#0.44341_7233#,
  1175.                   8#0.42712_7017#,
  1176.                   8#0.41325_3033#,
  1177.                   8#0.40000_0000#  );
  1178.  
  1179.       A2 : array (1 .. 8) of Float :=
  1180.                  (  8#0.00000_00005_22220_66302_61734_72062#,
  1181.                   8#0.00000_00003_02522_47021_04062_61124#,
  1182.                   8#0.00000_00005_21760_44016_17421_53016#,
  1183.                   8#0.00000_00007_65401_41553_72504_02177#,
  1184.                   8#0.00000_00002_44124_12254_31114_01243#,
  1185.                   8#0.00000_00000_11064_10432_66404_42174#,
  1186.                   8#0.00000_00004_72542_16063_30176_55544#,
  1187.                   8#0.00000_00001_74611_03661_23056_22556#  );
  1188.  
  1189.  
  1190.       function Reduce (V : Float) return Float is
  1191.       begin
  1192.          return Float (Integer (16.0 * V)) * 0.0625;
  1193.       end Reduce;
  1194.  
  1195.    begin
  1196.       if X <= Zero then
  1197.          if X < Zero then
  1198.             Result := (abs (X))**Y;
  1199.             New_Line;
  1200.             Put ("*** ERROR: X ** Y CALLED WITH X = ");
  1201.             Put (X);
  1202.             Put ("  USED ABS, RETURNED ");
  1203.             Put (Result);
  1204.             Put (" ***");
  1205.             New_Line;
  1206.          else
  1207.             if Y <= Zero then
  1208.                if Y = Zero then
  1209.                   Result := Zero;
  1210.                else
  1211.                   Result := Xmax;
  1212.                end if;
  1213.                New_Line;
  1214.                Put ("*** ERROR: X ** Y CALLED WITH X = 0, Y = ");
  1215.                Put (Y);
  1216.                Put ("  RETURNED ");
  1217.                Put (Result);
  1218.                Put (" ***");
  1219.                New_Line;
  1220.             else
  1221.                Result := Zero;
  1222.             end if;
  1223.          end if;
  1224.       else
  1225.          Defloat (X, M, G);
  1226.          P := 1;
  1227.          if G <= A1 (9) then
  1228.             P := 9;
  1229.          end if;
  1230.          if G <= A1 (P+4) then
  1231.             P := P + 4;
  1232.          end if;
  1233.          if G <= A1 (P+2) then
  1234.             P := P + 2;
  1235.          end if;
  1236.          Z := ((G - A1 (P+1)) - A2 ((P+1)/2))/ (G + A1 (P+1));
  1237.          Z := Z + Z;
  1238.          V := Z * Z;
  1239.          R := (P2 * V + P1) * V * Z;
  1240.          R := R + K * R;
  1241.          U2 := (R + Z * K) + Z;
  1242.          U1 := Float (Integer (M) * 16 - P) * 0.0625;
  1243.          Y1 := Reduce (Y);
  1244.          Y2 := Y - Y1;
  1245.          W := U2 * Y + U1 * Y2;
  1246.          W1 := Reduce (W);
  1247.          W2 := W - W1;
  1248.          W := W1 + U1 * Y1;
  1249.          W1 := Reduce (W);
  1250.          W2 := W2 + (W - W1);
  1251.          W3 := Reduce (W2);
  1252.          Iw1 := Integer (Truncate (16.0 * (W1 + W3)));
  1253.          W2 := W2 - W3;
  1254.          if W > Float (Ibigx) then
  1255.             Result := Xmax;
  1256.             Put ("*** ERROR: X ** Y CALLED  X =");
  1257.             Put (X);
  1258.             Put ("   Y =");
  1259.             Put (Y);
  1260.             Put ("   TOO LARGE,  RETURNED ");
  1261.             Put (Result);
  1262.             Put (" ***");
  1263.             New_Line;
  1264.          elsif W < Float (Ismallx) then
  1265.             Result := Zero;
  1266.             Put ("*** ERROR: X ** Y CALLED  X =");
  1267.             Put (X);
  1268.             Put ("   Y =");
  1269.             Put (Y);
  1270.             Put ("   TOO SMALL,  RETURNED ");
  1271.             Put (Result);
  1272.             Put (" ***");
  1273.             New_Line;
  1274.          else
  1275.             if W2 > Zero then
  1276.                W2 := W2 - 0.0625;
  1277.                Iw1 := Iw1 + 1;
  1278.             end if;
  1279.             if Iw1 < Integer (Zero) then
  1280.                I := 0;
  1281.             else
  1282.                I := 1;
  1283.             end if;
  1284.             M := Exponent_Type (I + Iw1/16);
  1285.             P := 16 * Integer (M) - Iw1;
  1286.             Z := ((((Q5 * W2 + Q4) * W2 + Q3) * W2 + Q2) * W2 + Q1) * W2;
  1287.             Z := A1 (P+1) + (A1 (P+1) * Z);
  1288.  
  1289.             Refloat (M, Z, Result);
  1290.          end if;
  1291.       end if;
  1292.       return Result;
  1293.    end "**";
  1294.  
  1295. begin
  1296.    Exp_Large := Log (Xmax) * (One - Eps);
  1297.    Exp_Small := Log (Xmin) * (One - Eps);
  1298. end Core_Functions;
  1299. --::::::::::::::::::::::::::::
  1300. --TRIG-FUNCTIONS-SPEC.ADA
  1301. --::::::::::::::::::::::::::::
  1302.  
  1303.  
  1304. --  The following is a series of complete and machine-independent,
  1305. --  but not necessarily efficient, packages which, if compiled in order,
  1306. --  will provide the elementary functions required by some benchmarks
  1307.  
  1308. --  This specific file was prepared for the VAX/VMS Telesoft 1.3d Oct84 release
  1309. --  This is an unvalidated system 
  1310.  
  1311. package Trig_Functions is
  1312.    function Sin (X : Float) return Float;
  1313.    function Cos (X : Float) return Float;
  1314.    function Tan (X : Float) return Float;
  1315.    function Cot (X : Float) return Float;
  1316.    function Asin (X : Float) return Float;
  1317.    function Acos (X : Float) return Float;
  1318.    function Atan (X : Float) return Float;
  1319.    function Atan2 (V, U : Float) return Float;
  1320.    function Sinh (X : Float) return Float;
  1321.    function Cosh (X : Float) return Float;
  1322.    function Tanh (X : Float) return Float;
  1323. end Trig_Functions;
  1324. --::::::::::::::::::::::::::::
  1325. --TRIG-FUNCTIONS-BODY.ADA
  1326. --::::::::::::::::::::::::::::
  1327.  
  1328.  
  1329. with Text_Io; use Text_Io;
  1330. with Floating_Characteristics; use Floating_Characteristics;
  1331. with Numeric_Io; use Numeric_Io;
  1332. with Numeric_Primitives; use Numeric_Primitives;
  1333. with Core_Functions; use Core_Functions;
  1334. package body Trig_Functions is
  1335.  
  1336.    --  PRELIMINARY VERSION *********************************
  1337.  
  1338.    --  The following routines are coded directly from the algorithms and
  1339.    --  coeficients given in "Software Manual for the Elementry Functions"
  1340.    --  by William J. Cody, Jr. and William Waite, Prentice_Hall, 1980
  1341.    --  This particular version is stripped to work with FLOAT and INTEGER
  1342.    --  and uses a mantissa represented as a FLOAT
  1343.    --  A more general formulation uses MANTISSA_TYPE, etc.
  1344.    --  The coeficients are appropriate for 25 to 32 bits floating significance
  1345.    --  They will work for less but slightly shorter versions are possible
  1346.    --  The routines are coded to stand alone so they need not be compiled together
  1347.  
  1348.    --      16 JULY 1982       W A WHITAKER  AFATL EGLIN AFB FL 32542
  1349.    --                         T C EICHOLTZ  USAFA
  1350.  
  1351.  
  1352.    function Sin (X : Float) return Float is
  1353.       Sgn, Y : Float;
  1354.       N : Integer;
  1355.       Xn : Float;
  1356.       F, G, X1, X2 : Float;
  1357.       Result : Float;
  1358.  
  1359.       Ymax : Float := Float (Integer (Pi * Two** (It/2)));
  1360.       Beta : Float := Convert_To_Float (Ibeta);
  1361.       Epsilon : Float := Beta ** (-It/2);
  1362.  
  1363.       C1 : constant Float :=  3.140625;
  1364.       C2 : constant Float :=  9.6765_35897_93E-4;
  1365.  
  1366.       function R (G : Float) return Float is
  1367.          R1 : constant Float := -0.16666_66660_883;
  1368.          R2 : constant Float :=  0.83333_30720_556E-2;
  1369.          R3 : constant Float := -0.19840_83282_313E-3;
  1370.          R4 : constant Float :=  0.27523_97106_775E-5;
  1371.          R5 : constant Float := -0.23868_34640_601E-7;
  1372.       begin
  1373.          return ((((R5*G + R4)*G + R3)*G + R2)*G + R1)*G;
  1374.       end R;
  1375.  
  1376.    begin
  1377.       if X < Zero  then
  1378.          Sgn := -One;
  1379.          Y := -X;
  1380.       else
  1381.          Sgn := One;
  1382.          Y := X;
  1383.       end if;
  1384.  
  1385.       if Y > Ymax  then
  1386.          New_Line;
  1387.          Put ("*** ERROR: SIN CALLED WITH ARGUMENT TOO LARGE FOR ACCURACY ");
  1388.          Put (X);
  1389.          Put (" ***");
  1390.          New_Line;
  1391.       end if;
  1392.  
  1393.       N := Integer (Y * One_Over_Pi);
  1394.       Xn := Convert_To_Float (N);
  1395.       if N mod 2 /= 0  then
  1396.          Sgn := -Sgn;
  1397.       end if;
  1398.       X1 := Truncate (abs (X));
  1399.       X2 := abs (X) - X1;
  1400.       F := ((X1 - Xn*C1) + X2) - Xn*C2;
  1401.       if abs (F) < Epsilon  then
  1402.          Result := F;
  1403.       else
  1404.          G := F * F;
  1405.          Result := F + F*R (G);
  1406.       end if;
  1407.       return (Sgn * Result);
  1408.    end Sin;
  1409.  
  1410.  
  1411.    function Cos (X : Float) return Float is
  1412.       Sgn, Y : Float;
  1413.       N : Integer;
  1414.       Xn : Float;
  1415.       F, G, X1, X2 : Float;
  1416.       Result : Float;
  1417.  
  1418.       Ymax : Float := Float (Integer (Pi * Two** (It/2)));
  1419.       Beta : Float := Convert_To_Float (Ibeta);
  1420.       Epsilon : Float := Beta ** (-It/2);
  1421.  
  1422.       C1 : constant Float :=  3.140625;
  1423.       C2 : constant Float :=  9.6765_35897_93E-4;
  1424.  
  1425.       function R (G : Float) return Float is
  1426.          R1 : constant Float := -0.16666_66660_883;
  1427.          R2 : constant Float :=  0.83333_30720_556E-2;
  1428.          R3 : constant Float := -0.19840_83282_313E-3;
  1429.          R4 : constant Float :=  0.27523_97106_775E-5;
  1430.          R5 : constant Float := -0.23868_34640_601E-7;
  1431.       begin
  1432.          return ((((R5*G + R4)*G + R3)*G + R2)*G + R1)*G;
  1433.       end R;
  1434.  
  1435.    begin
  1436.       Sgn := 1.0;
  1437.       Y := abs (X) + Pi_Over_Two;
  1438.  
  1439.       if Y > Ymax  then
  1440.          New_Line;
  1441.          Put ("*** ERROR: COS CALLED WITH ARGUMENT TOO LARGE FOR ACCURACY ");
  1442.          Put (X);
  1443.          Put (" ***");
  1444.          New_Line;
  1445.       end if;
  1446.  
  1447.       N := Integer (Y * One_Over_Pi);
  1448.       Xn := Convert_To_Float (N);
  1449.       if N mod 2 /= 0  then
  1450.          Sgn := -Sgn;
  1451.       end if;
  1452.       Xn := Xn - 0.5;          -- TO FORM COS INSTEAD OF SIN
  1453.       X1 := Truncate (abs (X));
  1454.       X2 := abs (X) - X1;
  1455.       F := ((X1 - Xn*C1) + X2) - Xn*C2;
  1456.       if abs (F) < Epsilon  then
  1457.          Result := F;
  1458.       else
  1459.          G := F * F;
  1460.          Result := F + F*R (G);
  1461.       end if;
  1462.       return (Sgn * Result);
  1463.    end Cos;
  1464.  
  1465.  
  1466.    function Tan (X : Float) return Float is
  1467.       Sgn, Y : Float;
  1468.       N : Integer;
  1469.       Xn : Float;
  1470.       F, G, X1, X2 : Float;
  1471.       Result : Float;
  1472.  
  1473.       Ymax : Float := Float (Integer (Pi * Two** (It/2))) /2.0;
  1474.       Beta : Float := Convert_To_Float (Ibeta);
  1475.       Epsilon : Float := Beta ** (-It/2);
  1476.  
  1477.       C1 : constant Float :=  8#1.444#;
  1478.       C2 : constant Float :=  4.8382_67948_97E-4;
  1479.  
  1480.       function R (G : Float) return Float is
  1481.          P0 : constant Float :=  1.0;
  1482.          P1 : constant Float := -0.11136_14403_566;
  1483.          P2 : constant Float :=  0.10751_54738_488E-2;
  1484.          Q0 : constant Float :=  1.0;
  1485.          Q1 : constant Float := -0.44469_47720_281;
  1486.          Q2 : constant Float :=  0.15973_39213_300E-1;
  1487.       begin
  1488.          return ((P2*G + P1)*G*F + F) / (((Q2*G + Q1)*G +0.5) + 0.5);
  1489.       end R;
  1490.  
  1491.    begin
  1492.       Y := abs (X);
  1493.       if Y > Ymax  then
  1494.          New_Line;
  1495.          Put ("*** ERROR: TAN CALLED WITH ARGUMENT TOO LARGE FOR ACCURACY ");
  1496.          Put (X);
  1497.          Put (" ***");
  1498.          New_Line;
  1499.       end if;
  1500.  
  1501.       N := Integer (X * Two_Over_Pi);
  1502.       Xn := Convert_To_Float (N);
  1503.       X1 := Truncate (X);
  1504.       X2 := X - X1;
  1505.       F := ((X1 - Xn*C1) + X2) - Xn*C2;
  1506.       if abs (F) < Epsilon  then
  1507.          Result := F;
  1508.       else
  1509.          G := F * F;
  1510.          Result := R (G);
  1511.       end if;
  1512.       if N mod 2 = 0  then
  1513.          return Result;
  1514.       else
  1515.          return -1.0/Result;
  1516.       end if;
  1517.    end Tan;
  1518.  
  1519.    function Cot (X : Float) return Float is
  1520.       Sgn, Y : Float;
  1521.       N : Integer;
  1522.       Xn : Float;
  1523.       F, G, X1, X2 : Float;
  1524.       Result : Float;
  1525.  
  1526.  
  1527.       Ymax : Float := Float (Integer (Pi * Two** (It/2))) /2.0;
  1528.       Beta : Float := Convert_To_Float (Ibeta);
  1529.       Epsilon : Float := Beta ** (-It/2);
  1530.       Epsilon1 : Float :=  1.0/Xmax;
  1531.  
  1532.       C1 : constant Float :=  8#1.444#;
  1533.       C2 : constant Float :=  4.8382_67948_97E-4;
  1534.  
  1535.       function R (G : Float) return Float is
  1536.          P0 : constant Float :=  1.0;
  1537.          P1 : constant Float := -0.11136_14403_566;
  1538.          P2 : constant Float :=  0.10751_54738_488E-2;
  1539.          Q0 : constant Float :=  1.0;
  1540.          Q1 : constant Float := -0.44469_47720_281;
  1541.          Q2 : constant Float :=  0.15973_39213_300E-1;
  1542.       begin
  1543.          return ((P2*G + P1)*G*F + F) / (((Q2*G + Q1)*G +0.5) + 0.5);
  1544.       end R;
  1545.  
  1546.    begin
  1547.       Y := abs (X);
  1548.       if Y < Epsilon1  then
  1549.          New_Line;
  1550.          Put ("*** ERROR: COT CALLED WITH ARGUMENT TOO NEAR ZERO ");
  1551.          Put (X);
  1552.          Put (" ***");
  1553.          New_Line;
  1554.          if X < 0.0  then
  1555.             return -Xmax;
  1556.          else
  1557.             return Xmax;
  1558.          end if;
  1559.       end if;
  1560.       if Y > Ymax  then
  1561.          New_Line;
  1562.          Put ("*** ERROR: COT CALLED WITH ARGUMENT TOO LARGE FOR ACCURACY ");
  1563.          Put (X);
  1564.          Put (" ***");
  1565.          New_Line;
  1566.       end if;
  1567.  
  1568.       N := Integer (X * Two_Over_Pi);
  1569.       Xn := Convert_To_Float (N);
  1570.       X1 := Truncate (X);
  1571.       X2 := X - X1;
  1572.       F := ((X1 - Xn*C1) + X2) - Xn*C2;
  1573.       if abs (F) < Epsilon  then
  1574.          Result := F;
  1575.       else
  1576.          G := F * F;
  1577.          Result := R (G);
  1578.       end if;
  1579.       if N mod 2 /= 0  then
  1580.          return -Result;
  1581.       else
  1582.          return 1.0/Result;
  1583.       end if;
  1584.    end Cot;
  1585.  
  1586.  
  1587.    function Asin (X : Float) return Float is
  1588.       G, Y : Float;
  1589.       Result : Float;
  1590.       Beta : Float := Convert_To_Float (Ibeta);
  1591.       Epsilon : Float := Beta ** (-It/2);
  1592.  
  1593.       function R (G : Float) return Float is
  1594.          P1 : constant Float := -0.27516_55529_0596E1;
  1595.          P2 : constant Float :=  0.29058_76237_4859E1;
  1596.          P3 : constant Float := -0.59450_14419_3246;
  1597.          Q0 : constant Float := -0.16509_93320_2424E2;
  1598.          Q1 : constant Float :=  0.24864_72896_9164E2;
  1599.          Q2 : constant Float := -0.10333_86707_2113E2;
  1600.          Q3 : constant Float :=  1.0;
  1601.       begin
  1602.          return (((P3*G + P2)*G + P1)*G) / (((G + Q2)*G + Q1)*G + Q0);
  1603.       end R;
  1604.  
  1605.    begin
  1606.       Y := abs (X);
  1607.  
  1608.       if Y > Half  then
  1609.          if Y > 1.0  then
  1610.             New_Line;
  1611.             Put ("*** ERROR: ASIN CALLED FOR ");
  1612.             Put (X);
  1613.             Put (" (>1)  TRUNCATED TO 1, CONTINUED ***");
  1614.             New_Line;
  1615.             Y := 1.0;
  1616.          end if;
  1617.          G := ((0.5 - Y) + 0.5) / 2.0;
  1618.          Y := -2.0 * Sqrt (G);
  1619.          Result := Y + Y * R (G);
  1620.          Result := (Pi_Over_Four + Result) + Pi_Over_Four;
  1621.       else
  1622.          if Y < Epsilon  then
  1623.             Result := Y;
  1624.          else
  1625.             G := Y * Y;
  1626.             Result := Y + Y * R (G);
  1627.          end if;
  1628.       end if;
  1629.       if X < 0.0  then
  1630.          Result := -Result;
  1631.       end if;
  1632.  
  1633.       return Result;
  1634.    end Asin;
  1635.  
  1636.    function Acos (X : Float) return Float is
  1637.       G, Y : Float;
  1638.       Result : Float;
  1639.       Beta : Float := Convert_To_Float (Ibeta);
  1640.       Epsilon : Float := Beta ** (-It/2);
  1641.  
  1642.       function R (G : Float) return Float is
  1643.          P1 : constant Float := -0.27516_55529_0596E1;
  1644.          P2 : constant Float :=  0.29058_76237_4859E1;
  1645.          P3 : constant Float := -0.59450_14419_3246;
  1646.          Q0 : constant Float := -0.16509_93320_2424E2;
  1647.          Q1 : constant Float :=  0.24864_72896_9164E2;
  1648.          Q2 : constant Float := -0.10333_86707_2113E2;
  1649.          Q3 : constant Float :=  1.0;
  1650.       begin
  1651.          return (((P3*G + P2)*G + P1)*G) / (((G + Q2)*G + Q1)*G + Q0);
  1652.       end R;
  1653.  
  1654.    begin
  1655.       Y := abs (X);
  1656.  
  1657.       if Y > Half  then
  1658.          if Y > 1.0  then
  1659.             New_Line;
  1660.             Put ("*** ERROR: ACOS CALLED FOR ");
  1661.             Put (X);
  1662.             Put (" (> 1)  TRUNCATED TO 1, CONTINUED ***");
  1663.             New_Line;
  1664.             Y := 1.0;
  1665.          end if;
  1666.          G := ((0.5 - Y) + 0.5) / 2.0;
  1667.          Y := -2.0 * Sqrt (G);
  1668.          Result := Y + Y * R (G);
  1669.          if X < 0.0  then
  1670.             Result := (Pi_Over_Two + Result) + Pi_Over_Two;
  1671.          else
  1672.             Result := -Result;
  1673.          end if;
  1674.  
  1675.       else
  1676.          if Y < Epsilon  then
  1677.             Result := Y;
  1678.          else
  1679.             G := Y * Y;
  1680.             Result := Y + Y * R (G);
  1681.          end if;
  1682.          if X < 0.0  then
  1683.             Result := (Pi_Over_Four + Result) + Pi_Over_Four;
  1684.          else
  1685.             Result := (Pi_Over_Four - Result) + Pi_Over_Four;
  1686.          end if;
  1687.       end if;
  1688.  
  1689.       return Result;
  1690.    end Acos;
  1691.  
  1692.  
  1693.    function Atan (X : Float) return Float is
  1694.       F, G : Float;
  1695.       subtype Region is Integer range 0..3;    --  ##########
  1696.       N : Region;
  1697.       Result : Float;
  1698.  
  1699.       Beta : Float := Convert_To_Float (Ibeta);
  1700.  
  1701.       Epsilon : Float := Beta ** (-It/2);
  1702.  
  1703.       Sqrt_3           : constant Float :=  1.73205_08075_68877_29353;
  1704.       Sqrt_3_Minus_1   : constant Float :=  0.73205_08075_68877_29353;
  1705.       Two_Minus_Sqrt_3 : constant Float :=  0.26794_91924_31122_70647;
  1706.  
  1707.       function R (G : Float) return Float is
  1708.          P0 : constant Float := -0.14400_83448_74E1;
  1709.          P1 : constant Float := -0.72002_68488_98;
  1710.          Q0 : constant Float :=  0.43202_50389_19E1;
  1711.          Q1 : constant Float :=  0.47522_25845_99E1;
  1712.          Q2 : constant Float :=  1.0;
  1713.       begin
  1714.          return ((P1*G + P0)*G) / ((G + Q1)*G + Q0);
  1715.       end R;
  1716.  
  1717.    begin
  1718.       F := abs (X);
  1719.  
  1720.       if F > 1.0  then
  1721.          F := 1.0 / F;
  1722.          N := 2;
  1723.       else
  1724.          N := 0;
  1725.       end if;
  1726.  
  1727.       if F > Two_Minus_Sqrt_3  then
  1728.          F := (((Sqrt_3_Minus_1 * F - 0.5) - 0.5) + F) / (Sqrt_3 + F);
  1729.          N := N + 1;
  1730.       end if;
  1731.  
  1732.       if abs (F) < Epsilon  then
  1733.          Result := F;
  1734.       else
  1735.          G := F * F;
  1736.          Result := F + F * R (G);
  1737.       end if;
  1738.  
  1739.       if N > 1  then
  1740.          Result := - Result;
  1741.       end if;
  1742.  
  1743.       case N is
  1744.          when 0  =>
  1745.             Result := Result;
  1746.          when 1  =>
  1747.             Result := Pi_Over_Six + Result;
  1748.          when 2  =>
  1749.             Result := Pi_Over_Two + Result;
  1750.          when 3  =>
  1751.             Result := Pi_Over_Three + Result;
  1752.       end case;
  1753.  
  1754.       if X < 0.0  then
  1755.          Result := - Result;
  1756.       end if;
  1757.  
  1758.       return Result;
  1759.  
  1760.    end Atan;
  1761.  
  1762.  
  1763.  
  1764.    function Atan2 (V, U : Float) return Float is
  1765.       X, Result : Float;
  1766.  
  1767.    begin
  1768.  
  1769.       if U = 0.0  then
  1770.          if V = 0.0  then
  1771.             Result := 0.0;
  1772.             New_Line;
  1773.             Put ("*** ERROR: ATAN2 CALLED WITH 0.0 / 0.0   RETURNED ");
  1774.             Put (Result);
  1775.             Put (" ***");
  1776.             New_Line;
  1777.          elsif V > 0.0  then
  1778.             Result := Pi_Over_Two;
  1779.          else
  1780.             Result := - Pi_Over_Two;
  1781.          end if;
  1782.  
  1783.       else
  1784.          X := abs (V/U);
  1785.          --  If underflow or overflow is detected, go to the exception
  1786.          Result := Atan (X);
  1787.          if U < 0.0  then
  1788.             Result := Pi - Result;
  1789.          end if;
  1790.          if V < 0.0  then
  1791.             Result := - Result;
  1792.          end if;
  1793.       end if;
  1794.       return Result;
  1795.    exception
  1796.       when Numeric_Error  =>
  1797.          if abs (V) > abs (U)  then
  1798.             Result := Pi_Over_Two;
  1799.             if V < 0.0  then
  1800.                Result := - Result;
  1801.             end if;
  1802.          else
  1803.             Result := 0.0;
  1804.             if U < 0.0  then
  1805.                Result := Pi - Result;
  1806.             end if;
  1807.          end if;
  1808.          return Result;
  1809.    end Atan2;
  1810.  
  1811.  
  1812.    function Sinh (X : Float) return Float is
  1813.       G, W, Y, Z : Float;
  1814.       Result : Float;
  1815.       Beta : Float := Convert_To_Float (Ibeta);
  1816.       Epsilon : Float := Beta ** (-It/2);
  1817.  
  1818.       Ybar : Float := Exp_Large;
  1819.       Ln_V : Float := 8#0.542714#;
  1820.       V_Over_2_Minus_1 : Float :=  0.13830_27787_96019_02638E-4;
  1821.       Wmax : Float := Ybar - Ln_V + 0.69;
  1822.  
  1823.       function R (G : Float) return Float is
  1824.          P0 : constant Float :=  0.10622_28883_7151E4;
  1825.          P1 : constant Float :=  0.31359_75645_6058E2;
  1826.          P2 : constant Float :=  0.34364_14035_8506;
  1827.          Q0 : constant Float :=  0.63733_73302_1822E4;
  1828.          Q1 : constant Float := -0.13051_01250_9199E3;
  1829.          Q2 : constant Float :=  1.0;
  1830.       begin
  1831.          return (((P2*G + P1)*G + P0)*G) / ((G + Q1)*G + Q0);
  1832.       end R;
  1833.  
  1834.    begin
  1835.       Y := abs (X);
  1836.  
  1837.       if Y <= 1.0  then
  1838.          if Y < Epsilon  then
  1839.             Result := X;
  1840.          else
  1841.             G := X * X;
  1842.             Result := X + X * R (G);
  1843.          end if;
  1844.  
  1845.       else
  1846.          if Y <= Ybar  then
  1847.             Z := Exp (Y);
  1848.             Result := (Z - 1.0/Z) / 2.0;
  1849.          else
  1850.             W := Y - Ln_V;
  1851.             if W > Wmax  then
  1852.                New_Line;
  1853.                Put ("*** ERROR: SINH CALLED WITH TOO LARGE ARGUMENT ");
  1854.                Put (X);
  1855.                Put ("  RETURN BIG ***");
  1856.                New_Line;
  1857.                W := Wmax;
  1858.             end if;
  1859.             Z := Exp (W);
  1860.             Result := Z + V_Over_2_Minus_1 * Z;
  1861.          end if;
  1862.          if X < 0.0  then
  1863.             Result := -Result;
  1864.          end if;
  1865.  
  1866.       end if;
  1867.       return Result;
  1868.    end Sinh;
  1869.  
  1870.  
  1871.    function Cosh (X : Float) return Float is
  1872.       G, W, Y, Z : Float;
  1873.       Result : Float;
  1874.       Beta : Float := Convert_To_Float (Ibeta);
  1875.       Epsilon : Float := Beta ** (-It/2);
  1876.  
  1877.       Ybar : Float := Exp_Large;
  1878.       Ln_V : Float := 8#0.542714#;
  1879.       V_Over_2_Minus_1 : Float :=  0.13830_27787_96019_02638E-4;
  1880.       Wmax : Float := Ybar - Ln_V + 0.69;
  1881.  
  1882.       function R (G : Float) return Float is
  1883.          P0 : constant Float :=  0.10622_28883_7151E4;
  1884.          P1 : constant Float :=  0.31359_75645_6058E2;
  1885.          P2 : constant Float :=  0.34364_14035_8506;
  1886.          Q0 : constant Float :=  0.63733_73302_1822E4;
  1887.          Q1 : constant Float := -0.13051_01250_9199E3;
  1888.          Q2 : constant Float :=  1.0;
  1889.       begin
  1890.          return (((P2*G + P1)*G + P0)*G) / ((G + Q1)*G + Q0);
  1891.       end R;
  1892.  
  1893.    begin
  1894.       Y := abs (X);
  1895.  
  1896.       if Y <= Ybar  then
  1897.          Z := Exp (Y);
  1898.          Result := (Z + 1.0/Z) / 2.0;
  1899.       else
  1900.          W := Y - Ln_V;
  1901.          if W > Wmax  then
  1902.             New_Line;
  1903.             Put ("*** ERROR: COSH CALLED WITH TOO LARGE ARGUMENT ");
  1904.             Put (X);
  1905.             Put ("  RETURN BIG ***");
  1906.             New_Line;
  1907.             W := Wmax;
  1908.          end if;
  1909.          Z := Exp (W);
  1910.          Result := Z + V_Over_2_Minus_1 * Z;
  1911.       end if;
  1912.  
  1913.       return Result;
  1914.    end Cosh;
  1915.  
  1916.  
  1917.    function Tanh (X : Float) return Float is
  1918.       G, W, Y, Z : Float;
  1919.       Result : Float;
  1920.       Beta : Float := Convert_To_Float (Ibeta);
  1921.       Epsilon : Float := Beta ** (-It/2);
  1922.  
  1923.       Xbig : Float := (Log (2.0) + Convert_To_Float (It + 1) * Log (Beta))/2.0;
  1924.       Ln_3_Over_2 : Float :=  0.54930_61443_34054_84570;
  1925.  
  1926.       function R (G : Float) return Float is
  1927.          P0 : constant Float := -0.21063_95800_0245E2;
  1928.          P1 : constant Float := -0.93363_47565_2401;
  1929.          Q0 : constant Float :=  0.63191_87401_5582E2;
  1930.          Q1 : constant Float :=  0.28077_65347_0471E2;
  1931.          Q2 : constant Float :=  1.0;
  1932.       begin
  1933.          return ((P1*G + P0)*G) / ((G + Q1)*G + Q0);
  1934.       end R;
  1935.  
  1936.    begin
  1937.       Y := abs (X);
  1938.  
  1939.       if Y > Xbig  then
  1940.          Result := 1.0;
  1941.       else
  1942.          if Y > Ln_3_Over_2  then
  1943.             Result := 0.5 - 1.0 / (Exp (Y + Y) + 1.0);
  1944.             Result := Result + Result;
  1945.          else
  1946.             if Y < Epsilon  then
  1947.                Result := Y;
  1948.             else
  1949.                G := Y * Y;
  1950.                Result := Y + Y * R (G);
  1951.             end if;
  1952.          end if;
  1953.       end if;
  1954.       if X < 0.0  then
  1955.          Result := - Result;
  1956.       end if;
  1957.  
  1958.       return Result;
  1959.    end Tanh;
  1960.  
  1961.  
  1962. begin
  1963.    null;
  1964. end Trig_Functions;
  1965. --::::::::::::::::::::::::::::
  1966. --FLOAT-MATH-LIB-SPEC.ADA
  1967. --::::::::::::::::::::::::::::
  1968.  
  1969. package Float_Math_Lib is
  1970.  
  1971.    -- Stub for Digital math library
  1972.  
  1973.    function Sqrt  (A : Float) return Float;
  1974.    function Cbrt  (A : Float) return Float;
  1975.    function Log   (A : Float) return Float;
  1976.    function Log10 (A : Float) return Float;
  1977.    function Log2  (A : Float) return Float;
  1978.    function Exp   (A : Float) return Float;
  1979.  
  1980.    function "**"  (X, Y : Float) return Float;
  1981.  
  1982.    -------------------------------------------------------------------
  1983.  
  1984.    -- Sine, cosine, and tangent of an angle given in radians.
  1985.  
  1986.    function Sin (A : Float) return Float;
  1987.    function Cos (A : Float) return Float;
  1988.    function Tan (A : Float) return Float;
  1989.    function Cot (A : Float) return Float;
  1990.  
  1991.    -------------------------------------------------------------------
  1992.  
  1993.    -- Arc sine, arc cosine, and arc tangent - return an angle
  1994.    -- expressed in radians.
  1995.  
  1996.    function Asin (A : Float) return Float;
  1997.    function Acos (A : Float) return Float;
  1998.    function Atan (A : Float) return Float;
  1999.  
  2000.    -------------------------------------------------------------------
  2001.  
  2002.    -- Arc tangent with two parameters - Arc Tan (A1/A2) - returns
  2003.    -- an angle expressed in radians.
  2004.  
  2005.    function Atan2 (A1, A2 : Float) return Float;
  2006.  
  2007.    -------------------------------------------------------------------
  2008.  
  2009.    -- Hyperbolic sine, cosine, and tangent of an angle in radians.
  2010.  
  2011.    function Sinh (A : Float) return Float;
  2012.    function Cosh (A : Float) return Float;
  2013.    function Tanh (A : Float) return Float;
  2014.  
  2015.    -------------------------------------------------------------------
  2016.  
  2017.    -- Trigonometric functions for angles expressed in degrees.
  2018.  
  2019.    function Sind (A : Float) return Float;
  2020.    function Cosd (A : Float) return Float;
  2021.    function Tand (A : Float) return Float;
  2022.  
  2023.    function Asind (A : Float) return Float;
  2024.    function Acosd (A : Float) return Float;
  2025.    function Atand (A : Float) return Float;
  2026.  
  2027.    function Atan2D (A1, A2 : Float) return Float;
  2028.  
  2029.    -------------------------------------------------------------------
  2030.  
  2031.    -- pragma Inline (Sqrt, Log,  Log10, Log2,  Exp,   
  2032.    --                Sin,  Cos,  Tan,   Cot,
  2033.    --                Asin, Acos, Atan,  Atan2, Sinh,  Cosh,  Tanh,
  2034.    --                Sind, Cosd, Tand,  Asind, Acosd, Atand, Atan2D);
  2035.  
  2036. end Float_Math_Lib;
  2037. --::::::::::::::::::::::::::::
  2038. --FLOAT-MATH-LIB-BODY.ADA
  2039. --::::::::::::::::::::::::::::
  2040.  
  2041. package body Float_Math_Lib is
  2042.  
  2043.    -- Stub for Digital math library
  2044.  
  2045.    function Sqrt (A : Float) return Float is
  2046.    begin
  2047.       return 1.0;
  2048.    end Sqrt;
  2049.  
  2050.    function Cbrt (A : Float) return Float is
  2051.    begin
  2052.       return 1.0;
  2053.    end Cbrt;
  2054.  
  2055.    function Log (A : Float) return Float is
  2056.    begin
  2057.       return 1.0;
  2058.    end Log;
  2059.  
  2060.    function Log10 (A : Float) return Float is
  2061.    begin
  2062.       return 1.0;
  2063.    end Log10;
  2064.  
  2065.    function Log2 (A : Float) return Float is
  2066.    begin
  2067.       return 1.0;
  2068.    end Log2;
  2069.  
  2070.    function Exp (A : Float) return Float is
  2071.    begin
  2072.       return 1.0;
  2073.    end Exp;
  2074.  
  2075.    function "**" (X, Y : Float) return Float is
  2076.    begin
  2077.       return 1.0;
  2078.    end "**";
  2079.  
  2080.    -------------------------------------------------------------------
  2081.  
  2082.    -- Sine, cosine, and tangent of an angle given in radians.
  2083.  
  2084.    function Sin (A : Float) return Float is
  2085.    begin
  2086.       return 1.0;
  2087.    end Sin;
  2088.  
  2089.    function Cos (A : Float) return Float is
  2090.    begin
  2091.       return 1.0;
  2092.    end Cos;
  2093.  
  2094.    function Tan (A : Float) return Float is
  2095.    begin
  2096.       return 1.0;
  2097.    end Tan;
  2098.  
  2099.    function Cot (A : Float) return Float is
  2100.    begin
  2101.       return 1.0;
  2102.    end Cot;
  2103.  
  2104.    -------------------------------------------------------------------
  2105.  
  2106.    -- Arc sine, arc cosine, and arc tangent - return an angle
  2107.    -- expressed in radians.
  2108.  
  2109.    function Asin (A : Float) return Float is
  2110.    begin
  2111.       return 1.0;
  2112.    end Asin;
  2113.  
  2114.    function Acos (A : Float) return Float is
  2115.    begin
  2116.       return 1.0;
  2117.    end Acos;
  2118.  
  2119.    function Atan (A : Float) return Float is
  2120.    begin
  2121.       return 1.0;
  2122.    end Atan;
  2123.  
  2124.    -------------------------------------------------------------------
  2125.  
  2126.    -- Arc tangent with two parameters - Arc Tan (A1/A2) - returns
  2127.    -- an angle expressed in radians.
  2128.  
  2129.    function Atan2 (A1, A2 : Float) return Float is
  2130.    begin
  2131.       return 1.0;
  2132.    end Atan2;
  2133.  
  2134.    -------------------------------------------------------------------
  2135.  
  2136.    -- Hyperbolic sine, cosine, and tangent of an angle in radians.
  2137.  
  2138.    function Sinh (A : Float) return Float is
  2139.    begin
  2140.       return 1.0;
  2141.    end Sinh;
  2142.  
  2143.    function Cosh (A : Float) return Float is
  2144.    begin
  2145.       return 1.0;
  2146.    end Cosh;
  2147.  
  2148.    function Tanh (A : Float) return Float is
  2149.    begin
  2150.       return 1.0;
  2151.    end Tanh;
  2152.  
  2153.    -------------------------------------------------------------------
  2154.  
  2155.    -- Trigonometric functions for angles expressed in degrees.
  2156.  
  2157.    function Sind (A : Float) return Float is
  2158.    begin
  2159.       return 1.0;
  2160.    end Sind;
  2161.  
  2162.    function Cosd (A : Float) return Float is
  2163.    begin
  2164.       return 1.0;
  2165.    end Cosd;
  2166.  
  2167.    function Tand (A : Float) return Float is
  2168.    begin
  2169.       return 1.0;
  2170.    end Tand;
  2171.  
  2172.    function Asind (A : Float) return Float is
  2173.    begin
  2174.       return 1.0;
  2175.    end Asind;
  2176.  
  2177.    function Acosd (A : Float) return Float is
  2178.    begin
  2179.       return 1.0;
  2180.    end Acosd;
  2181.  
  2182.    function Atand (A : Float) return Float is
  2183.    begin
  2184.       return 1.0;
  2185.    end Atand;
  2186.  
  2187.    function Atan2D (A1, A2 : Float) return Float is
  2188.    begin
  2189.       return 1.0;
  2190.    end Atan2D;
  2191.  
  2192. end Float_Math_Lib;
  2193. --::::::::::::::::::::::::::::
  2194. --KALMAN-MATRIX-LIB-SPEC.ADA
  2195. --::::::::::::::::::::::::::::
  2196.  
  2197. package Kalman_Matrix_Lib is
  2198.  
  2199.    --!----------------------------------------------------------------
  2200.    --!
  2201.    --! Name:
  2202.    --!    Kalman_Matrix_Lib
  2203.    --!
  2204.    --! Purpose:
  2205.    --!    This package provides the necessary matrix manipulation
  2206.    --!    routines required for the Ada Kalman Filter.
  2207.    --!
  2208.    --! Interfaces:
  2209.    --!    "-"
  2210.    --!       returns the difference between two matrices, vectors,
  2211.    --!       or an element and a matrix or vector.
  2212.    --!
  2213.    --!    "+"
  2214.    --!       returns the sum of two matrices, vectors,
  2215.    --!       or an element and a matrix or vector.
  2216.    --!
  2217.    --!    "*"
  2218.    --!       returns the product of an element and a matrix 
  2219.    --!       or vector or the matrix multiplication of two
  2220.    --!       matrices (or vectors).
  2221.    --!
  2222.    --!    "/"
  2223.    --!       returns the division of two matrices, vectors,
  2224.    --!       or an element and a matrix or vector.
  2225.    --!
  2226.    --!    "**"
  2227.    --!       returns the general inverse of a matrix.
  2228.    --!
  2229.    --!    To_Vector
  2230.    --!       converts a matrix (with one row or column) to a matrix.
  2231.    --!
  2232.    --!    To_Matrix
  2233.    --!       converts a vector to a matrix.
  2234.    --!
  2235.    --!    Zero
  2236.    --!       returns a vector or matrix of all zeroes.
  2237.    --!
  2238.    --!    Identity
  2239.    --!       returns a square matrix with a diagonal of ones.
  2240.    --!
  2241.    --!    Transpose
  2242.    --!       returns the matrix transpose of a matrix.
  2243.    --!
  2244.    --!    Inverse
  2245.    --!       returns the single inverse of a matrix (if one
  2246.    --!       can be found).
  2247.    --!
  2248.    --! Exceptions:
  2249.    --!    Matrix_Error
  2250.    --!       is raised if the indicated operation cannot be performed.
  2251.    --!
  2252.    --!    Inverse_Error
  2253.    --!       is raised if the Inverse operation cannot be performed.
  2254.    --!
  2255.    --! Notes:
  2256.    --!    The Inverse function is currently only defined for matrices
  2257.    --!    of dimension 3x3 or smaller (maximum needed by the Kalman
  2258.    --!    Filter).
  2259.    --!
  2260.    --! Contract:
  2261.    --!    Ada Tracking Package Using Kalman Filter Methods
  2262.    --!    Contract No. N66001-85-C-0044 (31 December 1984)
  2263.    --!
  2264.    --! Prepared for:
  2265.    --!    Naval Ocean Systems Center (WIS JPMO)
  2266.    --!    271 Catalina Blvd., Building A-33
  2267.    --!    San Diego, CA 92152
  2268.    --!
  2269.    --! Prepared by:
  2270.    --!    Software Systems Engineering
  2271.    --!    Federal Systems Group
  2272.    --!
  2273.    --!    Sanders Associates, Inc.
  2274.    --!    95 Canal Street
  2275.    --!    Nashua, NH 03061
  2276.    --!
  2277.    --! Author:
  2278.    --!    Daryl R. Winters
  2279.    --!
  2280.    --!----------------------------------------------------------------
  2281.  
  2282.    subtype Index is Positive;
  2283.    subtype Element is Float;
  2284.  
  2285.    type Vector is array (Index range <>) of Element;
  2286.    type Matrix is array (Index range <>, Index range <>) of Element;
  2287.  
  2288.    -------------------------------------------------------------------
  2289.  
  2290.    -- Matrix conversions.
  2291.  
  2292.    function To_Vector (Item: Matrix) return Vector;
  2293.    function To_Matrix (Item: Vector) return Matrix;
  2294.  
  2295.    -------------------------------------------------------------------
  2296.  
  2297.    -- Zero matrix.
  2298.  
  2299.    function Zero (Size: Vector) return Vector;
  2300.    function Zero (Size: Matrix) return Matrix;
  2301.  
  2302.    -------------------------------------------------------------------
  2303.  
  2304.    -- Matrix identity.
  2305.  
  2306.    function Identity (Size: Matrix) return Matrix;
  2307.  
  2308.    -------------------------------------------------------------------
  2309.  
  2310.    -- Matrix transpose.
  2311.  
  2312.    function Transpose (Item: Vector) return Matrix;
  2313.    function Transpose (Item: Matrix) return Matrix;
  2314.  
  2315.    -------------------------------------------------------------------
  2316.  
  2317.    -- Matrix subtraction.
  2318.  
  2319.    function "-" (Right: Vector) return Vector;
  2320.    function "-" (Right: Matrix) return Matrix;
  2321.  
  2322.    function "-" (Left: Vector;  Right: Element) return Vector;
  2323.    function "-" (Left: Element; Right: Vector)  return Vector;
  2324.  
  2325.    function "-" (Left: Element; Right: Matrix)  return Matrix;
  2326.    function "-" (Left: Matrix;  Right: Element) return Matrix;
  2327.  
  2328.    function "-" (Left: Vector; Right: Vector) return Vector;
  2329.    function "-" (Left: Matrix; Right: Vector) return Matrix;
  2330.    function "-" (Left: Vector; Right: Matrix) return Matrix;
  2331.    function "-" (Left: Matrix; Right: Matrix) return Matrix;
  2332.  
  2333.    -------------------------------------------------------------------
  2334.  
  2335.    -- Matrix addition.
  2336.  
  2337.    function "+" (Right: Vector) return Vector;
  2338.    function "+" (Right: Matrix) return Matrix;
  2339.  
  2340.    function "+" (Left: Vector;  Right: Element) return Vector;
  2341.    function "+" (Left: Element; Right: Vector)  return Vector;
  2342.  
  2343.    function "+" (Left: Element; Right: Matrix)  return Matrix;
  2344.    function "+" (Left: Matrix;  Right: Element) return Matrix;
  2345.  
  2346.    function "+" (Left: Vector; Right: Vector) return Vector;
  2347.    function "+" (Left: Matrix; Right: Vector) return Matrix;
  2348.    function "+" (Left: Vector; Right: Matrix) return Matrix;
  2349.    function "+" (Left: Matrix; Right: Matrix) return Matrix;
  2350.  
  2351.    -------------------------------------------------------------------
  2352.  
  2353.    -- Matrix multiplication.
  2354.  
  2355.    function "*" (Left: Vector;  Right: Element) return Vector;
  2356.    function "*" (Left: Element; Right: Vector)  return Vector;
  2357.  
  2358.    function "*" (Left: Element; Right: Matrix)  return Matrix;
  2359.    function "*" (Left: Matrix;  Right: Element) return Matrix;
  2360.  
  2361.    function "*" (Left: Vector; Right: Vector) return Matrix;
  2362.    function "*" (Left: Vector; Right: Matrix) return Matrix;
  2363.    function "*" (Left: Matrix; Right: Vector) return Matrix;
  2364.    function "*" (Left: Matrix; Right: Matrix) return Matrix;
  2365.  
  2366.    -------------------------------------------------------------------
  2367.  
  2368.    -- Matrix division.
  2369.  
  2370.    function "/" (Left: Vector;  Right: Element) return Vector;
  2371.    function "/" (Left: Element; Right: Vector)  return Vector;
  2372.  
  2373.    function "/" (Left: Element; Right: Matrix)  return Matrix;
  2374.    function "/" (Left: Matrix;  Right: Element) return Matrix;
  2375.  
  2376.    -------------------------------------------------------------------
  2377.  
  2378.    -- Matrix inversion.
  2379.  
  2380.    function Inverse (Item: Matrix) return Matrix;
  2381.  
  2382.    function "**" (Left: Matrix; Right: Integer) return Matrix;
  2383.  
  2384.    -------------------------------------------------------------------
  2385.  
  2386.    Matrix_Error:  exception;
  2387.    Inverse_Error: exception;
  2388.  
  2389. end Kalman_Matrix_Lib;
  2390. --::::::::::::::::::::::::::::
  2391. --KALMAN-MATRIX-LIB-BODY.ADA
  2392. --::::::::::::::::::::::::::::
  2393.  
  2394. package body Kalman_Matrix_Lib is
  2395.  
  2396.    --!----------------------------------------------------------------
  2397.    --!
  2398.    --! Name:
  2399.    --!    Kalman_Matrix_Lib
  2400.    --!
  2401.    --! Purpose:
  2402.    --!    This package body contains the matrix operations needed
  2403.    --!    by the Ada Kalman Filter.
  2404.    --!
  2405.    --! Exceptions:
  2406.    --!    Not applicable.
  2407.    --!
  2408.    --! Notes:
  2409.    --!    Not applicable.
  2410.    --!
  2411.    --! Contract:
  2412.    --!    Ada Tracking Package Using Kalman Filter Methods
  2413.    --!    Contract No. N66001-85-C-0044 (31 December 1984)
  2414.    --!
  2415.    --! Prepared for:
  2416.    --!    Naval Ocean Systems Center (WIS JPMO)
  2417.    --!    271 Catalina Blvd., Building A-33
  2418.    --!    San Diego, CA 92152
  2419.    --!
  2420.    --! Prepared by:
  2421.    --!    Software Systems Engineering
  2422.    --!    Federal Systems Group
  2423.    --!
  2424.    --!    Sanders Associates, Inc.
  2425.    --!    95 Canal Street
  2426.    --!    Nashua, NH 03061
  2427.    --!
  2428.    --! Author:
  2429.    --!    Daryl R. Winters
  2430.    --!
  2431.    --! Changes:
  2432.    --!    22-APR-1985
  2433.    --!       Re-initialized the L and M indexes in "+" and "*" which
  2434.    --!       were used to index the Right array. This resulted in
  2435.    --!       a value outside the array bounds. This was not picked
  2436.    --!       up by the VAX Ada compiler as a Constraint_Error, as
  2437.    --!       required by the Ada LRM, but generated a "Digital
  2438.    --!       reserved op-code" message.
  2439.    --!
  2440.    --!    23-APR-1985
  2441.    --!       Moved the point of initialization of L to outside the
  2442.    --!       outer loop in "+" and "*". This resulted in L tracking
  2443.    --!       the J index and not the I index as required.
  2444.    --!
  2445.    --!----------------------------------------------------------------
  2446.  
  2447.    pragma Page;
  2448.    -------------------------------------------------------------------
  2449.  
  2450.    function Zero return Element is
  2451.  
  2452.       --!-------------------------------------------------------------
  2453.       --!
  2454.       --! Name:
  2455.       --!    Zero
  2456.       --!
  2457.       --! Purpose:
  2458.       --!    This local function returns a zero value.
  2459.       --!
  2460.       --! Parameters:
  2461.       --!    Not applicable.
  2462.       --!
  2463.       --! Exceptions:
  2464.       --!    Not applicable.
  2465.       --!
  2466.       --! Notes:
  2467.       --!    Not applicable.
  2468.       --!
  2469.       --!-------------------------------------------------------------
  2470.  
  2471.    begin
  2472.       return (0.0);
  2473.    end Zero;
  2474.  
  2475.    pragma Page;
  2476.    -------------------------------------------------------------------
  2477.  
  2478.    function One return Element is
  2479.  
  2480.       --!-------------------------------------------------------------
  2481.       --!
  2482.       --! Name:
  2483.       --!    One
  2484.       --!
  2485.       --! Purpose:
  2486.       --!    This local function returns a one.
  2487.       --!
  2488.       --! Parameters:
  2489.       --!    Not applicable.
  2490.       --!
  2491.       --! Exceptions:
  2492.       --!    Not applicable.
  2493.       --!
  2494.       --! Notes:
  2495.       --!    Not applicable.
  2496.       --!
  2497.       --!-------------------------------------------------------------
  2498.  
  2499.    begin
  2500.       return (1.0);
  2501.    end One;
  2502.  
  2503.    pragma Page;
  2504.    -------------------------------------------------------------------
  2505.  
  2506.    function To_Vector (Item: Matrix) return Vector is
  2507.  
  2508.       --!-------------------------------------------------------------
  2509.       --!
  2510.       --! Name:
  2511.       --!    To_Vector
  2512.       --!
  2513.       --! Purpose:
  2514.       --!    This function converts a matrix (with one row or column)
  2515.       --!    to a vector.
  2516.       --!
  2517.       --! Parameters:
  2518.       --!    Item
  2519.       --!       is a matrix with one row or column.
  2520.       --!
  2521.       --! Exceptions:
  2522.       --!    Matrix_Error
  2523.       --!       is raised if the parameter is not of the correct 
  2524.       --!       shape.
  2525.       --!
  2526.       --! Notes:
  2527.       --!    Not applicable.
  2528.       --!
  2529.       --!-------------------------------------------------------------
  2530.  
  2531.    begin
  2532.       if (Item'Length (1) = 1) then
  2533.          declare
  2534.             Result: Vector (Item'range (2));
  2535.          begin
  2536.             for I in Item'range (2) loop
  2537.                Result (I) := Item (Item'First (1), I);
  2538.             end loop;
  2539.  
  2540.             return (Result);
  2541.          end;
  2542.  
  2543.       elsif (Item'Length (2) = 1) then
  2544.          declare
  2545.             Result: Vector (Item'range (1));
  2546.          begin
  2547.             for I in Item'range (1) loop
  2548.                Result (I) := Item (I, Item'First (2));
  2549.             end loop;
  2550.  
  2551.             return (Result);
  2552.          end;
  2553.  
  2554.       else
  2555.          raise Matrix_Error;
  2556.       end if;
  2557.    end To_Vector;
  2558.  
  2559.    pragma Page;
  2560.    -------------------------------------------------------------------
  2561.  
  2562.    function To_Matrix (Item: Vector) return Matrix is
  2563.  
  2564.       --!-------------------------------------------------------------
  2565.       --!
  2566.       --! Name:
  2567.       --!    To_Matrix
  2568.       --!
  2569.       --! Purpose:
  2570.       --!    This function converts a vector to a matrix of one row.
  2571.       --!
  2572.       --! Parameters:
  2573.       --!    Item
  2574.       --!       is a vector.
  2575.       --!
  2576.       --! Exceptions:
  2577.       --!    Not applicable.
  2578.       --!
  2579.       --! Notes:
  2580.       --!    Not applicable.
  2581.       --!
  2582.       --!-------------------------------------------------------------
  2583.  
  2584.       Result: Matrix (Item'First .. Item'First, Item'range);
  2585.  
  2586.    begin
  2587.       for I in Item'range loop
  2588.          Result (Item'First, I) := Item (I);
  2589.       end loop;
  2590.  
  2591.       return (Result);
  2592.    end To_Matrix;
  2593.  
  2594.    pragma Page;
  2595.    -------------------------------------------------------------------
  2596.  
  2597.    function Zero (Size: Vector) return Vector is
  2598.  
  2599.       --!-------------------------------------------------------------
  2600.       --!
  2601.       --! Name:
  2602.       --!    Zero
  2603.       --!
  2604.       --! Purpose:
  2605.       --!    This function returns a vector of all zeroes.
  2606.       --!
  2607.       --! Parameters:
  2608.       --!    Size
  2609.       --!       is a vector of the desired size.
  2610.       --!
  2611.       --! Exceptions:
  2612.       --!    Not applicable.
  2613.       --!
  2614.       --! Notes:
  2615.       --!    Only the Size'range value is used to determine the size.
  2616.       --!
  2617.       --!-------------------------------------------------------------
  2618.  
  2619.       Result: Vector (Size'range);
  2620.  
  2621.    begin
  2622.       for I in Result'range loop
  2623.          Result (I) := Zero;
  2624.       end loop;
  2625.  
  2626.       return (Result);
  2627.    end Zero;
  2628.  
  2629.    pragma Page;
  2630.    -------------------------------------------------------------------
  2631.  
  2632.    function Zero (Size: Matrix) return Matrix is
  2633.  
  2634.       --!-------------------------------------------------------------
  2635.       --!
  2636.       --! Name:
  2637.       --!    Zero
  2638.       --!
  2639.       --! Purpose:
  2640.       --!    This function returns a matrix of all zeroes.
  2641.       --!
  2642.       --! Parameters:
  2643.       --!    Size
  2644.       --!       is a matrix of the desired size.
  2645.       --!
  2646.       --! Exceptions:
  2647.       --!    Not applicable.
  2648.       --!
  2649.       --! Notes:
  2650.       --!    Only the Size'range value is used to determine the size.
  2651.       --!
  2652.       --!-------------------------------------------------------------
  2653.  
  2654.       Result: Matrix (Size'range (1), Size'range (2));
  2655.  
  2656.    begin
  2657.       for I in Result'range (1) loop
  2658.          for J in Result'range (2) loop
  2659.             Result (I, J) := Zero;
  2660.          end loop;
  2661.       end loop;
  2662.  
  2663.       return (Result);
  2664.    end Zero;
  2665.  
  2666.    pragma Page;
  2667.    -------------------------------------------------------------------
  2668.  
  2669.    function Identity (Size: Matrix) return Matrix is
  2670.  
  2671.       --!-------------------------------------------------------------
  2672.       --!
  2673.       --! Name:
  2674.       --!    Identity
  2675.       --!
  2676.       --! Purpose:
  2677.       --!    This function returns a square matrix with the diagonal
  2678.       --!    all ones and everything else all zeroes.
  2679.       --!
  2680.       --! Parameters:
  2681.       --!    Size
  2682.       --!       is a matrix of the desired size.
  2683.       --!
  2684.       --! Exceptions:
  2685.       --!    Matrix_Error
  2686.       --!       is raised if the matrix is not square.
  2687.       --!
  2688.       --! Notes:
  2689.       --!    Only the Size'range value is used to determine the size.
  2690.       --!
  2691.       --!-------------------------------------------------------------
  2692.  
  2693.       Result: Matrix (Size'range (1), Size'range (2));
  2694.  
  2695.    begin
  2696.       if (Size'Length (1) /= Size'Length (2)) then
  2697.          raise Matrix_Error;
  2698.       end if;
  2699.  
  2700.       for I in Result'range (1) loop
  2701.          for J in Result'range (2) loop
  2702.             if (I = J) then
  2703.                Result (I, J) := One;
  2704.             else
  2705.                Result (I, J) := Zero;
  2706.             end if;
  2707.          end loop;
  2708.       end loop;
  2709.  
  2710.       return (Result);
  2711.    end Identity;
  2712.  
  2713.    pragma Page;
  2714.    -------------------------------------------------------------------
  2715.  
  2716.    function Transpose (Item: Vector) return Matrix is
  2717.  
  2718.       --!-------------------------------------------------------------
  2719.       --!
  2720.       --! Name:
  2721.       --!    Transpose
  2722.       --!
  2723.       --! Purpose:
  2724.       --!    This function returns the transpose of a vector by
  2725.       --!    first converting the vector to a matrix of one row.
  2726.       --!
  2727.       --! Parameters:
  2728.       --!    Item
  2729.       --!       is the vector to be transposed.
  2730.       --!
  2731.       --! Exceptions:
  2732.       --!    Not applicable.
  2733.       --!
  2734.       --! Notes:
  2735.       --!    Not applicable.
  2736.       --!
  2737.       --!-------------------------------------------------------------
  2738.  
  2739.       Result: Matrix (Item'range, Item'First .. Item'First);
  2740.  
  2741.    begin
  2742.       for I in Item'range loop
  2743.          Result (I, Item'First) := Item (I);
  2744.       end loop;
  2745.  
  2746.       return (Result);
  2747.    end Transpose;
  2748.  
  2749.    pragma Page;
  2750.    -------------------------------------------------------------------
  2751.  
  2752.    function Transpose (Item: Matrix) return Matrix is
  2753.  
  2754.       --!-------------------------------------------------------------
  2755.       --!
  2756.       --! Name:
  2757.       --!    Transpose
  2758.       --!
  2759.       --! Purpose:
  2760.       --!    This procedure returns the transpose of a matrix.
  2761.       --!
  2762.       --! Parameters:
  2763.       --!    Item
  2764.       --!       is the matrix to be transposed.
  2765.       --!
  2766.       --! Exceptions:
  2767.       --!    Not applicable.
  2768.       --!
  2769.       --! Notes:
  2770.       --!    Not applicable.
  2771.       --!
  2772.       --!-------------------------------------------------------------
  2773.  
  2774.       Result: Matrix (Item'range (2), Item'range (1));
  2775.  
  2776.    begin
  2777.       for I in Item'range (1) loop
  2778.          for J in Item'range (2) loop
  2779.             Result (J, I) := Item (I, J);
  2780.          end loop;
  2781.       end loop;
  2782.  
  2783.       return (Result);
  2784.    end Transpose;
  2785.  
  2786.    pragma Page;
  2787.    -------------------------------------------------------------------
  2788.  
  2789.    function "-" (Right: Vector) return Vector is
  2790.  
  2791.       --!-------------------------------------------------------------
  2792.       --!
  2793.       --! Name:
  2794.       --!    "-"
  2795.       --!
  2796.       --! Purpose:
  2797.       --!    This function returns the negative of a vector by
  2798.       --!    negating all elements.
  2799.       --!
  2800.       --! Parameters:
  2801.       --!    Right
  2802.       --!       is the vector to be negated.
  2803.       --!
  2804.       --! Exceptions:
  2805.       --!    Not applicable.
  2806.       --!
  2807.       --! Notes:
  2808.       --!    Not applicable.
  2809.       --!
  2810.       --!-------------------------------------------------------------
  2811.  
  2812.       Result: Vector (Right'range);
  2813.  
  2814.    begin
  2815.       for I in Right'range loop
  2816.          Result (I) := - Right (I);
  2817.       end loop;
  2818.  
  2819.       return (Result);
  2820.    end "-";
  2821.  
  2822.    pragma Page;
  2823.    -------------------------------------------------------------------
  2824.  
  2825.    function "-" (Right: Matrix) return Matrix is
  2826.  
  2827.       --!-------------------------------------------------------------
  2828.       --!
  2829.       --! Name:
  2830.       --!    "-"
  2831.       --!
  2832.       --! Purpose:
  2833.       --!    This function returns the negative of a matrix by
  2834.       --!    negating all elements.
  2835.       --!
  2836.       --! Parameters:
  2837.       --!    Right
  2838.       --!       is the matrix to be negated.
  2839.       --!
  2840.       --! Exceptions:
  2841.       --!    Not applicable.
  2842.       --!
  2843.       --! Notes:
  2844.       --!    Not applicable.
  2845.       --!
  2846.       --!-------------------------------------------------------------
  2847.  
  2848.       Result: Matrix (Right'range (1), Right'range (2));
  2849.  
  2850.    begin
  2851.       for I in Right'range (1) loop
  2852.          for J in Right'range (2) loop
  2853.             Result (I, J) := - Right (I, J);
  2854.          end loop;
  2855.       end loop;
  2856.  
  2857.       return (Result);
  2858.    end "-";
  2859.  
  2860.    pragma Page;
  2861.    -------------------------------------------------------------------
  2862.  
  2863.    function "-" (Left: Vector;  Right: Element) return Vector is
  2864.  
  2865.       --!-------------------------------------------------------------
  2866.       --!
  2867.       --! Name:
  2868.       --!    "-"
  2869.       --!
  2870.       --! Purpose:
  2871.       --!    This function subtracts an element from all elements
  2872.       --!    of a vector.
  2873.       --!
  2874.       --! Parameters:
  2875.       --!    Left
  2876.       --!       is the vector of values.
  2877.       --!
  2878.       --!    Right
  2879.       --!       is the value to subtract from the vector.
  2880.       --!
  2881.       --! Exceptions:
  2882.       --!    Not applicable.
  2883.       --!
  2884.       --! Notes:
  2885.       --!    Not applicable.
  2886.       --!
  2887.       --!-------------------------------------------------------------
  2888.  
  2889.       Result: Vector (Left'range);
  2890.  
  2891.    begin
  2892.       for I in Left'range loop
  2893.          Result (I) := Left (I) - Right;
  2894.       end loop;
  2895.  
  2896.       return (Result);
  2897.    end "-";
  2898.  
  2899.    pragma Page;
  2900.    -------------------------------------------------------------------
  2901.  
  2902.    function "-" (Left: Element; Right: Vector) return Vector is
  2903.  
  2904.       --!-------------------------------------------------------------
  2905.       --!
  2906.       --! Name:
  2907.       --!    "-"
  2908.       --!
  2909.       --! Purpose:
  2910.       --!    This function returns a vector produced by subtracting
  2911.       --!    a vector from a value.
  2912.       --!
  2913.       --! Parameters:
  2914.       --!    Left
  2915.       --!       is the value to be subtracted from.
  2916.       --!
  2917.       --!    Right
  2918.       --!       is the vector to subtract from the value.
  2919.       --!
  2920.       --! Exceptions:
  2921.       --!    Not applicable.
  2922.       --!
  2923.       --! Notes:
  2924.       --!    Not applicable.
  2925.       --!
  2926.       --!-------------------------------------------------------------
  2927.  
  2928.       Result: Vector (Right'range);
  2929.  
  2930.    begin
  2931.       for I in Right'range loop
  2932.          Result (I) := Left - Right (I);
  2933.       end loop;
  2934.  
  2935.       return (Result);
  2936.    end "-";
  2937.  
  2938.    pragma Page;
  2939.    -------------------------------------------------------------------
  2940.  
  2941.    function "-" (Left: Element; Right: Matrix) return Matrix is
  2942.  
  2943.       --!-------------------------------------------------------------
  2944.       --!
  2945.       --! Name:
  2946.       --!    "-"
  2947.       --!
  2948.       --! Purpose:
  2949.       --!    This function returns a matrix produced by subtracting
  2950.       --!    a matrix from a value.
  2951.       --!
  2952.       --! Parameters:
  2953.       --!    Left
  2954.       --!       is the value to be subtracted from.
  2955.       --!
  2956.       --!    Right
  2957.       --!       is the matrix to subtract from the value.
  2958.       --!
  2959.       --! Exceptions:
  2960.       --!    Not applicable.
  2961.       --!
  2962.       --! Notes:
  2963.       --!    Not applicable.
  2964.       --!
  2965.       --!-------------------------------------------------------------
  2966.  
  2967.       Result: Matrix (Right'range (1), Right'range (2));
  2968.  
  2969.    begin
  2970.       for I in Right'range (1) loop
  2971.          for J in Right'range (2) loop
  2972.             Result (I, J) := Left - Right (I, J);
  2973.          end loop;
  2974.       end loop;
  2975.  
  2976.       return (Result);
  2977.    end "-";
  2978.  
  2979.    pragma Page;
  2980.    -------------------------------------------------------------------
  2981.  
  2982.    function "-" (Left: Matrix; Right: Element) return Matrix is
  2983.  
  2984.       --!-------------------------------------------------------------
  2985.       --!
  2986.       --! Name:
  2987.       --!    "-"
  2988.       --!
  2989.       --! Purpose:
  2990.       --!    This function subtracts a value from all elements of
  2991.       --!    a matrix.
  2992.       --!
  2993.       --! Parameters:
  2994.       --!    Left
  2995.       --!       is the matrix.
  2996.       --!
  2997.       --!    Right
  2998.       --!       is the value to subtract from the matrix.
  2999.       --!
  3000.       --! Exceptions:
  3001.       --!    Not applicable.
  3002.       --!
  3003.       --! Notes:
  3004.       --!    Not applicable.
  3005.       --!
  3006.       --!-------------------------------------------------------------
  3007.  
  3008.       Result: Matrix (Left'range (1), Left'range (2));
  3009.  
  3010.    begin
  3011.       for I in Left'range (1) loop
  3012.          for J in Left'range (2) loop
  3013.             Result (I, J) := Left (I, J) - Right;
  3014.          end loop;
  3015.       end loop;
  3016.  
  3017.       return (Result);
  3018.    end "-";
  3019.  
  3020.    pragma Page;
  3021.    -------------------------------------------------------------------
  3022.  
  3023.    function "-" (Left: Vector; Right: Vector) return Vector is
  3024.  
  3025.       --!-------------------------------------------------------------
  3026.       --!
  3027.       --! Name:
  3028.       --!    "-"
  3029.       --!
  3030.       --! Purpose:
  3031.       --!    This function subtracts two vectors.
  3032.       --!
  3033.       --! Parameters:
  3034.       --!    Left
  3035.       --!       is a vector.
  3036.       --!
  3037.       --!    Right
  3038.       --!       is a vector.
  3039.       --!
  3040.       --! Exceptions:
  3041.       --!    Matrix_Error
  3042.       --!       is raised if the vectors are not the same size.
  3043.       --!
  3044.       --! Notes:
  3045.       --!    Not applicable.
  3046.       --!
  3047.       --!-------------------------------------------------------------
  3048.  
  3049.       Result: Vector (Left'range);
  3050.       J: Index := Right'First;
  3051.  
  3052.    begin
  3053.       if (Left'Length /= Right'Length) then
  3054.          raise Matrix_Error;
  3055.       end if;
  3056.  
  3057.       for I in Left'range loop
  3058.          Result (I) := Left (I) - Right (J);
  3059.          exit when (J = Right'Last);
  3060.          J := Index'Succ (J);
  3061.       end loop;
  3062.  
  3063.       return (Result);
  3064.    end "-";
  3065.  
  3066.    pragma Page;
  3067.    -------------------------------------------------------------------
  3068.  
  3069.    function "-" (Left: Matrix; Right: Vector) return Matrix is
  3070.  
  3071.       --!-------------------------------------------------------------
  3072.       --!
  3073.       --! Name:
  3074.       --!    "-"
  3075.       --!
  3076.       --! Purpose:
  3077.       --!    This function subtracts a vector from a matrix by
  3078.       --!    first converting the vector to a single column matrix.
  3079.       --!
  3080.       --! Parameters:
  3081.       --!    Left
  3082.       --!       is the matrix.
  3083.       --!
  3084.       --!    Left
  3085.       --!       is the vector.
  3086.       --!
  3087.       --! Exceptions:
  3088.       --!    Matrix_Error
  3089.       --!       is raised if the resulting matrices are not of the
  3090.       --!       the same size.
  3091.       --!
  3092.       --! Notes:
  3093.       --!    Not applicable.
  3094.       --!
  3095.       --!-------------------------------------------------------------
  3096.  
  3097.    begin
  3098.       if (Left'Length (1) = 1) then
  3099.          return (Left - To_Matrix (Right));
  3100.  
  3101.       elsif (Left'Length (2) = 1) then
  3102.          return (Left - Transpose (Right));
  3103.  
  3104.       else
  3105.          raise Matrix_Error;
  3106.       end if;
  3107.    end "-";
  3108.  
  3109.    pragma Page;
  3110.    -------------------------------------------------------------------
  3111.  
  3112.    function "-" (Left: Vector; Right: Matrix) return Matrix is
  3113.  
  3114.       --!-------------------------------------------------------------
  3115.       --!
  3116.       --! Name:
  3117.       --!    "-"
  3118.       --!
  3119.       --! Purpose:
  3120.       --!    This function subtracts a vector from a matrix by first
  3121.       --!    converting the vector to a matrix of one row.
  3122.       --!
  3123.       --! Parameters:
  3124.       --!    Left
  3125.       --!       is the vector.
  3126.       --!
  3127.       --!    Left
  3128.       --!       is the matrix.
  3129.       --!
  3130.       --! Exceptions:
  3131.       --!    Matrix_Error
  3132.       --!       is raised if the resulting matrices are not of the
  3133.       --!       the same size.
  3134.       --!
  3135.       --! Notes:
  3136.       --!    Not applicable.
  3137.       --!
  3138.       --!-------------------------------------------------------------
  3139.  
  3140.    begin
  3141.       if (Right'Length (1) = 1) then
  3142.          return (To_Matrix (Left) - Right);
  3143.  
  3144.       elsif (Right'Length (2) = 1) then
  3145.          return (Transpose (Left) - Right);
  3146.  
  3147.       else
  3148.          raise Matrix_Error;
  3149.       end if;
  3150.    end "-";
  3151.  
  3152.    pragma Page;
  3153.    -------------------------------------------------------------------
  3154.  
  3155.    function "-" (Left: Matrix; Right: Matrix) return Matrix is
  3156.  
  3157.       --!-------------------------------------------------------------
  3158.       --!
  3159.       --! Name:
  3160.       --!    "-"
  3161.       --!
  3162.       --! Purpose:
  3163.       --!    This function subtracts corresponding elements from
  3164.       --!    two matrices.
  3165.       --!
  3166.       --! Parameters:
  3167.       --!    Left
  3168.       --!       is a matrix.
  3169.       --!
  3170.       --!    Right
  3171.       --!       is a matrix.
  3172.       --!
  3173.       --! Exceptions:
  3174.       --!    Matrix_Error
  3175.       --!       is raised if the matrices are not the same size.
  3176.       --!
  3177.       --! Notes:
  3178.       --!    Not applicable.
  3179.       --!
  3180.       --!-------------------------------------------------------------
  3181.  
  3182.       Result: Matrix (Left'range (1), Left'range (2));
  3183.       L: Index;
  3184.       M: Index;
  3185.  
  3186.    begin
  3187.       if (Left'Length (1) /= Right'Length (1)) or
  3188.          (Left'Length (2) /= Right'Length (2)) then
  3189.          raise Matrix_Error;
  3190.       end if;
  3191.  
  3192.       L := Right'First (1);
  3193.       for I in Left'range (1) loop
  3194.  
  3195.          M := Right'First (2);
  3196.          for J in Left'range (2) loop
  3197.             Result (I, J) := Left (I, J) - Right (L, M);
  3198.  
  3199.             exit when (M = Right'Last (2));
  3200.             M := Index'Succ (M);
  3201.          end loop;
  3202.  
  3203.          exit when (L = Right'Last (1));
  3204.          L := Index'Succ (L);
  3205.       end loop;
  3206.  
  3207.       return (Result);
  3208.    end "-";
  3209.  
  3210.    pragma Page;
  3211.    -------------------------------------------------------------------
  3212.  
  3213.    function "+" (Right: Vector) return Vector is
  3214.  
  3215.       --!-------------------------------------------------------------
  3216.       --!
  3217.       --! Name:
  3218.       --!    "+"
  3219.       --!
  3220.       --! Purpose:
  3221.       --!    This function returns the vector.
  3222.       --!
  3223.       --! Parameters:
  3224.       --!    Right
  3225.       --!       is the vector.
  3226.       --!
  3227.       --! Exceptions:
  3228.       --!    Not applicable.
  3229.       --!
  3230.       --! Notes:
  3231.       --!    Not applicable.
  3232.       --!
  3233.       --!-------------------------------------------------------------
  3234.  
  3235.       Result: Vector (Right'range);
  3236.  
  3237.    begin
  3238.       for I in Right'range loop
  3239.          Result (I) := + Right (I);
  3240.       end loop;
  3241.  
  3242.       return (Result);
  3243.    end "+";
  3244.  
  3245.    pragma Page;
  3246.    -------------------------------------------------------------------
  3247.  
  3248.    function "+" (Right: Matrix) return Matrix is
  3249.  
  3250.       --!-------------------------------------------------------------
  3251.       --!
  3252.       --! Name:
  3253.       --!    "+"
  3254.       --!
  3255.       --! Purpose:
  3256.       --!    This function returns the matrix.
  3257.       --!
  3258.       --! Parameters:
  3259.       --!    Right
  3260.       --!       is the matrix.
  3261.       --!
  3262.       --! Exceptions:
  3263.       --!    Not applicable.
  3264.       --!
  3265.       --! Notes:
  3266.       --!    Not applicable.
  3267.       --!
  3268.       --!-------------------------------------------------------------
  3269.  
  3270.       Result: Matrix (Right'range (1), Right'range (2));
  3271.  
  3272.    begin
  3273.       for I in Right'range (1) loop
  3274.          for J in Right'range (2) loop
  3275.             Result (I, J) := + Right (I, J);
  3276.          end loop;
  3277.       end loop;
  3278.  
  3279.       return (Result);
  3280.    end "+";
  3281.  
  3282.    pragma Page;
  3283.    -------------------------------------------------------------------
  3284.  
  3285.    function "+" (Left: Vector;  Right: Element) return Vector is
  3286.  
  3287.       --!-------------------------------------------------------------
  3288.       --!
  3289.       --! Name:
  3290.       --!    "+"
  3291.       --!
  3292.       --! Purpose:
  3293.       --!    This function adds a value to all elements of a vector.
  3294.       --!
  3295.       --! Parameters:
  3296.       --!    Left
  3297.       --!       is the vector.
  3298.       --!
  3299.       --!    Right
  3300.       --!       is the value.
  3301.       --!
  3302.       --! Exceptions:
  3303.       --!    Not applicable.
  3304.       --!
  3305.       --! Notes:
  3306.       --!    Not applicable.
  3307.       --!
  3308.       --!-------------------------------------------------------------
  3309.  
  3310.       Result: Vector (Left'range);
  3311.  
  3312.    begin
  3313.       for I in Left'range loop
  3314.          Result (I) := Left (I) + Right;
  3315.       end loop;
  3316.  
  3317.       return (Result);
  3318.    end "+";
  3319.  
  3320.    pragma Page;
  3321.    -------------------------------------------------------------------
  3322.  
  3323.    function "+" (Left: Element; Right: Vector) return Vector is
  3324.  
  3325.       --!-------------------------------------------------------------
  3326.       --!
  3327.       --! Name:
  3328.       --!    "+"
  3329.       --!
  3330.       --! Purpose:
  3331.       --!    This function adds a value to all elements of a vector.
  3332.       --!
  3333.       --! Parameters:
  3334.       --!    Left
  3335.       --!       is the value.
  3336.       --!
  3337.       --!    Right
  3338.       --!       is the vector.
  3339.       --!
  3340.       --! Exceptions:
  3341.       --!    Not applicable.
  3342.       --!
  3343.       --! Notes:
  3344.       --!    Not applicable.
  3345.       --!
  3346.       --!-------------------------------------------------------------
  3347.  
  3348.       Result: Vector (Right'range);
  3349.  
  3350.    begin
  3351.       for I in Right'range loop
  3352.          Result (I) := Left + Right (I);
  3353.       end loop;
  3354.  
  3355.       return (Result);
  3356.    end "+";
  3357.  
  3358.    pragma Page;
  3359.    -------------------------------------------------------------------
  3360.  
  3361.    function "+" (Left: Element; Right: Matrix) return Matrix is
  3362.  
  3363.       --!-------------------------------------------------------------
  3364.       --!
  3365.       --! Name:
  3366.       --!    "+"
  3367.       --!
  3368.       --! Purpose:
  3369.       --!    This function adds a value to all elements of a matrix.
  3370.       --!
  3371.       --! Parameters:
  3372.       --!    Left
  3373.       --!       is the value.
  3374.       --!
  3375.       --!    Right
  3376.       --!       is the matrix.
  3377.       --!
  3378.       --! Exceptions:
  3379.       --!    Not applicable.
  3380.       --!
  3381.       --! Notes:
  3382.       --!    Not applicable.
  3383.       --!
  3384.       --!-------------------------------------------------------------
  3385.  
  3386.       Result: Matrix (Right'range (1), Right'range (2));
  3387.  
  3388.    begin
  3389.       for I in Right'range (1) loop
  3390.          for J in Right'range (2) loop
  3391.             Result (I, J) := Left + Right (I, J);
  3392.          end loop;
  3393.       end loop;
  3394.  
  3395.       return (Result);
  3396.    end "+";
  3397.  
  3398.    pragma Page;
  3399.    -------------------------------------------------------------------
  3400.  
  3401.    function "+" (Left: Matrix; Right: Element) return Matrix is
  3402.  
  3403.       --!-------------------------------------------------------------
  3404.       --!
  3405.       --! Name:
  3406.       --!    "+"
  3407.       --!
  3408.       --! Purpose:
  3409.       --!    This function adds a value to all elements of a matrix.
  3410.       --!
  3411.       --! Parameters:
  3412.       --!    Left
  3413.       --!       is the matrix.
  3414.       --!
  3415.       --!    Right
  3416.       --!       is the value.
  3417.       --!
  3418.       --! Exceptions:
  3419.       --!    Not applicable.
  3420.       --!
  3421.       --! Notes:
  3422.       --!    Not applicable.
  3423.       --!
  3424.       --!-------------------------------------------------------------
  3425.  
  3426.       Result: Matrix (Left'range (1), Left'range (2));
  3427.  
  3428.    begin
  3429.       for I in Left'range (1) loop
  3430.          for J in Left'range (2) loop
  3431.             Result (I, J) := Left (I, J) + Right;
  3432.          end loop;
  3433.       end loop;
  3434.  
  3435.       return (Result);
  3436.    end "+";
  3437.  
  3438.    pragma Page;
  3439.    -------------------------------------------------------------------
  3440.  
  3441.    function "+" (Left: Vector; Right: Vector) return Vector is
  3442.  
  3443.       --!-------------------------------------------------------------
  3444.       --!
  3445.       --! Name:
  3446.       --!    "+"
  3447.       --!
  3448.       --! Purpose:
  3449.       --!    This function adds corresponding elements of a vector.
  3450.       --!
  3451.       --! Parameters:
  3452.       --!    Left
  3453.       --!       is a vector.
  3454.       --!
  3455.       --!    Right
  3456.       --!       is a vector.
  3457.       --!
  3458.       --! Exceptions:
  3459.       --!    Matrix_Error
  3460.       --!       is raised if the vectors are not the same size.
  3461.       --!
  3462.       --! Notes:
  3463.       --!    Not applicable.
  3464.       --!
  3465.       --!-------------------------------------------------------------
  3466.  
  3467.       Result: Vector (Left'range);
  3468.       J: Index := Right'First;
  3469.  
  3470.    begin
  3471.       if (Left'Length /= Right'Length) then
  3472.          raise Matrix_Error;
  3473.       end if;
  3474.  
  3475.       for I in Left'range loop
  3476.          Result (I) := Left (I) + Right (J);
  3477.          exit when (J = Right'Last);
  3478.          J := Index'Succ (J);
  3479.       end loop;
  3480.  
  3481.       return (Result);
  3482.    end "+";
  3483.  
  3484.    pragma Page;
  3485.    -------------------------------------------------------------------
  3486.  
  3487.    function "+" (Left: Matrix; Right: Vector) return Matrix is
  3488.  
  3489.       --!-------------------------------------------------------------
  3490.       --!
  3491.       --! Name:
  3492.       --!    "+"
  3493.       --!
  3494.       --! Purpose:
  3495.       --!    This function adds all elements of a vector to a matrix
  3496.       --!    by first converting the vector to a matrix of one column.
  3497.       --!
  3498.       --! Parameters:
  3499.       --!    Left
  3500.       --!       is the matrix.
  3501.       --!
  3502.       --!    Left
  3503.       --!       is the vector.
  3504.       --!
  3505.       --! Exceptions:
  3506.       --!    Matrix_Error
  3507.       --!       is raised if the resulting matrices are not the same 
  3508.       --!       size.
  3509.       --!
  3510.       --! Notes:
  3511.       --!    Not applicable.
  3512.       --!
  3513.       --!-------------------------------------------------------------
  3514.  
  3515.    begin
  3516.       if (Left'Length (1) = 1) then
  3517.          return (Left + To_Matrix (Right));
  3518.  
  3519.       elsif (Left'Length (2) = 1) then
  3520.          return (Left + Transpose (Right));
  3521.  
  3522.       else
  3523.          raise Matrix_Error;
  3524.       end if;
  3525.    end "+";
  3526.  
  3527.    pragma Page;
  3528.    -------------------------------------------------------------------
  3529.  
  3530.    function "+" (Left: Vector; Right: Matrix) return Matrix is
  3531.  
  3532.       --!-------------------------------------------------------------
  3533.       --!
  3534.       --! Name:
  3535.       --!    "+"
  3536.       --!
  3537.       --! Purpose:
  3538.       --!    This function adds corresponding elements of a vector
  3539.       --!    to a matrix by first converting the vector to a matrix.
  3540.       --!
  3541.       --! Parameters:
  3542.       --!    Left
  3543.       --!       is the vector.
  3544.       --!
  3545.       --!    Right
  3546.       --!       is the matrix.
  3547.       --!
  3548.       --! Exceptions:
  3549.       --!    Matrix_Error
  3550.       --!       is raised if the resulting matrices are not the same
  3551.       --!       size.
  3552.       --!
  3553.       --! Notes:
  3554.       --!    Not applicable.
  3555.       --!
  3556.       --!-------------------------------------------------------------
  3557.  
  3558.    begin
  3559.       if (Right'Length (1) = 1) then
  3560.          return (To_Matrix (Left) + Right);
  3561.  
  3562.       elsif (Right'Length (2) = 1) then
  3563.          return (Transpose (Left) + Right);
  3564.  
  3565.       else
  3566.          raise Matrix_Error;
  3567.       end if;
  3568.    end "+";
  3569.  
  3570.    pragma Page;
  3571.    -------------------------------------------------------------------
  3572.  
  3573.    function "+" (Left: Matrix; Right: Matrix) return Matrix is
  3574.  
  3575.       --!-------------------------------------------------------------
  3576.       --!
  3577.       --! Name:
  3578.       --!    "+"
  3579.       --!
  3580.       --! Purpose:
  3581.       --!    This function adds corresponding elements of matrices.
  3582.       --!
  3583.       --! Parameters:
  3584.       --!    Left
  3585.       --!       is a matrix.
  3586.       --!
  3587.       --!    Right
  3588.       --!       is a matrix.
  3589.       --!
  3590.       --! Exceptions:
  3591.       --!    Matrix_Error
  3592.       --!       is raised if the matrices are not the same size.
  3593.       --!
  3594.       --! Notes:
  3595.       --!    Not applicable.
  3596.       --!
  3597.       --!-------------------------------------------------------------
  3598.  
  3599.       Result: Matrix (Left'range (1), Left'range (2));
  3600.       L: Index;
  3601.       M: Index;
  3602.  
  3603.    begin
  3604.       if (Left'Length (1) /= Right'Length (1)) or
  3605.          (Left'Length (2) /= Right'Length (2)) then
  3606.          raise Matrix_Error;
  3607.       end if;
  3608.  
  3609.       L := Right'First (1);
  3610.       for I in Left'range (1) loop
  3611.  
  3612.          M := Right'First (2);
  3613.          for J in Left'range (2) loop
  3614.             Result (I, J) := Left (I, J) + Right (L, M);
  3615.  
  3616.             exit when (M = Right'Last (2));
  3617.             M := Index'Succ (M);
  3618.          end loop;
  3619.  
  3620.          exit when (L = Right'Last (1));
  3621.          L := Index'Succ (L);
  3622.       end loop;
  3623.  
  3624.       return (Result);
  3625.    end "+";
  3626.  
  3627.    pragma Page;
  3628.    -------------------------------------------------------------------
  3629.  
  3630.    function "*" (Left: Vector;  Right: Element) return Vector is
  3631.  
  3632.       --!-------------------------------------------------------------
  3633.       --!
  3634.       --! Name:
  3635.       --!    "*"
  3636.       --!
  3637.       --! Purpose:
  3638.       --!    This function multiplies all elements of a vector by
  3639.       --!    a value.
  3640.       --!
  3641.       --! Parameters:
  3642.       --!    Left
  3643.       --!       is the vector.
  3644.       --!
  3645.       --!    Right
  3646.       --!       is the value.
  3647.       --!
  3648.       --! Exceptions:
  3649.       --!    Not applicable.
  3650.       --!
  3651.       --! Notes:
  3652.       --!    Not applicable.
  3653.       --!
  3654.       --!-------------------------------------------------------------
  3655.  
  3656.       Result: Vector (Left'range);
  3657.  
  3658.    begin
  3659.       for I in Left'range loop
  3660.          Result (I) := Left (I) * Right;
  3661.       end loop;
  3662.  
  3663.       return (Result);
  3664.    end "*";
  3665.  
  3666.    pragma Page;
  3667.    -------------------------------------------------------------------
  3668.  
  3669.    function "*" (Left: Element; Right: Vector) return Vector is
  3670.  
  3671.       --!-------------------------------------------------------------
  3672.       --!
  3673.       --! Name:
  3674.       --!    "*"
  3675.       --!
  3676.       --! Purpose:
  3677.       --!    This function multiplies all elements of a vector by a 
  3678.       --!    value.
  3679.       --!
  3680.       --! Parameters:
  3681.       --!    Left
  3682.       --!       is the value.
  3683.       --!
  3684.       --!    Right
  3685.       --!       is the vector.
  3686.       --!
  3687.       --! Exceptions:
  3688.       --!    Not applicable.
  3689.       --!
  3690.       --! Notes:
  3691.       --!    Not applicable.
  3692.       --!
  3693.       --!-------------------------------------------------------------
  3694.  
  3695.       Result: Vector (Right'range);
  3696.  
  3697.    begin
  3698.       for I in Right'range loop
  3699.          Result (I) := Left * Right (I);
  3700.       end loop;
  3701.  
  3702.       return (Result);
  3703.    end "*";
  3704.  
  3705.    pragma Page;
  3706.    -------------------------------------------------------------------
  3707.  
  3708.    function "*" (Left: Element; Right: Matrix) return Matrix is
  3709.  
  3710.       --!-------------------------------------------------------------
  3711.       --!
  3712.       --! Name:
  3713.       --!    "*"
  3714.       --!
  3715.       --! Purpose:
  3716.       --!    This function multiplies all elements of a matrix by a
  3717.       --!    value.
  3718.       --!
  3719.       --! Parameters:
  3720.       --!    Left
  3721.       --!       is the value.
  3722.       --!
  3723.       --!    Right
  3724.       --!       is the matrix.
  3725.       --!
  3726.       --! Exceptions:
  3727.       --!    Not applicable.
  3728.       --!
  3729.       --! Notes:
  3730.       --!    Not applicable.
  3731.       --!
  3732.       --!-------------------------------------------------------------
  3733.  
  3734.       Result: Matrix (Right'range (1), Right'range (2));
  3735.  
  3736.    begin
  3737.       for I in Right'range (1) loop
  3738.          for J in Right'range (2) loop
  3739.             Result (I, J) := Left * Right (I, J);
  3740.          end loop;
  3741.       end loop;
  3742.  
  3743.       return (Result);
  3744.    end "*";
  3745.  
  3746.    pragma Page;
  3747.    -------------------------------------------------------------------
  3748.  
  3749.    function "*" (Left: Matrix; Right: Element) return Matrix is
  3750.  
  3751.       --!-------------------------------------------------------------
  3752.       --!
  3753.       --! Name:
  3754.       --!    "*"
  3755.       --!
  3756.       --! Purpose:
  3757.       --!    This function multiplies all elements of a matrix by a
  3758.       --!    value.
  3759.       --!
  3760.       --! Parameters:
  3761.       --!    Left
  3762.       --!       is the matrix.
  3763.       --!
  3764.       --!    Right
  3765.       --!       is the value.
  3766.       --!
  3767.       --! Exceptions:
  3768.       --!    Not applicable.
  3769.       --!
  3770.       --! Notes:
  3771.       --!    Not applicable.
  3772.       --!
  3773.       --!-------------------------------------------------------------
  3774.  
  3775.       Result: Matrix (Left'range (1), Left'range (2));
  3776.  
  3777.    begin
  3778.       for I in Left'range (1) loop
  3779.          for J in Left'range (2) loop
  3780.             Result (I, J) := Left (I, J) * Right;
  3781.          end loop;
  3782.       end loop;
  3783.  
  3784.       return (Result);
  3785.    end "*";
  3786.  
  3787.    pragma Page;
  3788.    -------------------------------------------------------------------
  3789.  
  3790.    function "*" (Left: Vector; Right: Vector) return Matrix is
  3791.  
  3792.       --!-------------------------------------------------------------
  3793.       --!
  3794.       --! Name:
  3795.       --!    "*"
  3796.       --!
  3797.       --! Purpose:
  3798.       --!    This function performs a matrix multiplication of two
  3799.       --!    vectors by first converting one to a matrix of one row
  3800.       --!    and the other to a matrix of one column.
  3801.       --!
  3802.       --! Parameters:
  3803.       --!    Left
  3804.       --!       is a vector.
  3805.       --!
  3806.       --!    Right
  3807.       --!       is a vector.
  3808.       --!
  3809.       --! Exceptions:
  3810.       --!    Matrix_Error
  3811.       --!       is raised if the resulting matrices are not the 
  3812.       --!       correct shape.
  3813.       --!
  3814.       --! Notes:
  3815.       --!    Not applicable.
  3816.       --!
  3817.       --!-------------------------------------------------------------
  3818.  
  3819.    begin
  3820.       return (To_Matrix (Left) * Transpose (Right));
  3821.    end "*";
  3822.  
  3823.    pragma Page;
  3824.    -------------------------------------------------------------------
  3825.  
  3826.    function "*" (Left: Vector; Right: Matrix) return Matrix is
  3827.  
  3828.       --!-------------------------------------------------------------
  3829.       --!
  3830.       --! Name:
  3831.       --!    "*"
  3832.       --!
  3833.       --! Purpose:
  3834.       --!    This function performs a matrix multiplication of a 
  3835.       --!    vector and a matrix by first converting the vector
  3836.       --!    to a matrix of one row.
  3837.       --!
  3838.       --! Parameters:
  3839.       --!    Left
  3840.       --!       is the vector.
  3841.       --!
  3842.       --!    Right
  3843.       --!       is the matrix.
  3844.       --!
  3845.       --! Exceptions:
  3846.       --!    Matrix_Error
  3847.       --!       is raised if the resulting matrices are not the
  3848.       --!       correct shape.
  3849.       --!
  3850.       --! Notes:
  3851.       --!    Not applicable.
  3852.       --!
  3853.       --!-------------------------------------------------------------
  3854.  
  3855.    begin
  3856.       return (To_Matrix (Left) * Right);
  3857.    end "*";
  3858.  
  3859.    pragma Page;
  3860.    -------------------------------------------------------------------
  3861.  
  3862.    function "*" (Left: Matrix; Right: Vector) return Matrix is
  3863.  
  3864.       --!-------------------------------------------------------------
  3865.       --!
  3866.       --! Name:
  3867.       --!    "*"
  3868.       --!
  3869.       --! Purpose:
  3870.       --!    This function performs a matrix multiplication of a
  3871.       --!    matrix and a vector by first converting the vector
  3872.       --!    to a matrix of one column.
  3873.       --!
  3874.       --! Parameters:
  3875.       --!    Left
  3876.       --!       is the matrix.
  3877.       --!
  3878.       --!    Right
  3879.       --!       is the vector.
  3880.       --!
  3881.       --! Exceptions:
  3882.       --!    Matrix_Error
  3883.       --!       is raised if the resulting matrices are not the 
  3884.       --!       correct shape.
  3885.       --!
  3886.       --! Notes:
  3887.       --!    Not applicable.
  3888.       --!
  3889.       --!-------------------------------------------------------------
  3890.  
  3891.    begin
  3892.       return (Left * Transpose (Right));
  3893.    end "*";
  3894.  
  3895.    pragma Page;
  3896.    -------------------------------------------------------------------
  3897.  
  3898.    function "*" (Left: Matrix; Right: Matrix) return Matrix is
  3899.  
  3900.       --!-------------------------------------------------------------
  3901.       --!
  3902.       --! Name:
  3903.       --!    "*"
  3904.       --!
  3905.       --! Purpose:
  3906.       --!    This function performs a matrix multiplication of 
  3907.       --!    two matrices.
  3908.       --!
  3909.       --! Parameters:
  3910.       --!    Left
  3911.       --!       is a matrix.
  3912.       --!
  3913.       --!    Right
  3914.       --!       is a matrix.
  3915.       --!
  3916.       --! Exceptions:
  3917.       --!    Matrix_Error
  3918.       --!       is raised if the matrices are not the correct shape.
  3919.       --!
  3920.       --! Notes:
  3921.       --!    The left matrix must have dimensionality of NxL and the
  3922.       --!    right matrix must be LxM. The result will be NxM.
  3923.       --!
  3924.       --!-------------------------------------------------------------
  3925.  
  3926.       Sum: Element;
  3927.       Result: Matrix (Left'range (1), Right'range (2));
  3928.  
  3929.    begin
  3930.       if (Left'Length (2) /= Right'Length (1)) then
  3931.          raise Matrix_Error;
  3932.       end if;
  3933.  
  3934.       for I in Left'range (1) loop
  3935.          for J in Right'range (2) loop
  3936.             Sum := Zero;
  3937.  
  3938.             for K in Left'range (2) loop
  3939.                Sum := Sum + Left (I, K) * Right (K, J);
  3940.             end loop;
  3941.  
  3942.             Result (I, J) := Sum;
  3943.          end loop;
  3944.       end loop;
  3945.  
  3946.       return (Result);
  3947.    end "*";
  3948.  
  3949.    pragma Page;
  3950.    -------------------------------------------------------------------
  3951.  
  3952.    function "/" (Left: Vector;  Right: Element) return Vector is
  3953.  
  3954.       --!-------------------------------------------------------------
  3955.       --!
  3956.       --! Name:
  3957.       --!    "/"
  3958.       --!
  3959.       --! Purpose:
  3960.       --!    This function divides all elements of a vector by a 
  3961.       --!    value.
  3962.       --!
  3963.       --! Parameters:
  3964.       --!    Left
  3965.       --!       is the vector.
  3966.       --!
  3967.       --!    Right
  3968.       --!       is the value.
  3969.       --!
  3970.       --! Exceptions:
  3971.       --!    Not applicable.
  3972.       --!
  3973.       --! Notes:
  3974.       --!    Not applicable.
  3975.       --!
  3976.       --!-------------------------------------------------------------
  3977.  
  3978.       Result: Vector (Left'range);
  3979.  
  3980.    begin
  3981.       for I in Left'range loop
  3982.          Result (I) := Left (I) / Right;
  3983.       end loop;
  3984.  
  3985.       return (Result);
  3986.    end "/";
  3987.  
  3988.    pragma Page;
  3989.    -------------------------------------------------------------------
  3990.  
  3991.    function "/" (Left: Element; Right: Vector) return Vector is
  3992.  
  3993.       --!-------------------------------------------------------------
  3994.       --!
  3995.       --! Name:
  3996.       --!    "/"
  3997.       --!
  3998.       --! Purpose:
  3999.       --!    This function divides a value by all elements in a 
  4000.       --!    vector.
  4001.       --!
  4002.       --! Parameters:
  4003.       --!    Left
  4004.       --!       is the value.
  4005.       --!
  4006.       --!    Right
  4007.       --!       is the value.
  4008.       --!
  4009.       --! Exceptions:
  4010.       --!    Not applicable.
  4011.       --!
  4012.       --! Notes:
  4013.       --!    Not applicable.
  4014.       --!
  4015.       --!-------------------------------------------------------------
  4016.  
  4017.       Result: Vector (Right'range);
  4018.  
  4019.    begin
  4020.       for I in Right'range loop
  4021.          Result (I) := Left / Right (I);
  4022.       end loop;
  4023.  
  4024.       return (Result);
  4025.    end "/";
  4026.  
  4027.    pragma Page;
  4028.    -------------------------------------------------------------------
  4029.  
  4030.    function "/" (Left: Element; Right: Matrix) return Matrix is
  4031.  
  4032.       --!-------------------------------------------------------------
  4033.       --!
  4034.       --! Name:
  4035.       --!    "/"
  4036.       --!
  4037.       --! Purpose:
  4038.       --!    This function divides a value by all elements of a 
  4039.       --!    matrix.
  4040.       --!
  4041.       --! Parameters:
  4042.       --!    Left
  4043.       --!       is the value.
  4044.       --!
  4045.       --!    Right
  4046.       --!       is the matrix.
  4047.       --!
  4048.       --! Exceptions:
  4049.       --!    Not applicable.
  4050.       --!
  4051.       --! Notes:
  4052.       --!    Not applicable.
  4053.       --!
  4054.       --!-------------------------------------------------------------
  4055.  
  4056.       Result: Matrix (Right'range (1), Right'range (2));
  4057.  
  4058.    begin
  4059.       for I in Right'range (1) loop
  4060.          for J in Right'range (2) loop
  4061.             Result (I, J) := Left / Right (I, J);
  4062.          end loop;
  4063.       end loop;
  4064.  
  4065.       return (Result);
  4066.    end "/";
  4067.  
  4068.    pragma Page;
  4069.    -------------------------------------------------------------------
  4070.  
  4071.    function "/" (Left: Matrix; Right: Element) return Matrix is
  4072.  
  4073.       --!-------------------------------------------------------------
  4074.       --!
  4075.       --! Name:
  4076.       --!    "/"
  4077.       --!
  4078.       --! Purpose:
  4079.       --!    This function divides all elements of a matrix by a 
  4080.       --!    value.
  4081.       --!
  4082.       --! Parameters:
  4083.       --!    Left
  4084.       --!       is the matrix.
  4085.       --!
  4086.       --!    Right
  4087.       --!       is the value.
  4088.       --!
  4089.       --! Exceptions:
  4090.       --!    Not applicable.
  4091.       --!
  4092.       --! Notes:
  4093.       --!    Not applicable.
  4094.       --!
  4095.       --!-------------------------------------------------------------
  4096.  
  4097.       Result: Matrix (Left'range (1), Left'range (2));
  4098.  
  4099.    begin
  4100.       for I in Left'range (1) loop
  4101.          for J in Left'range (2) loop
  4102.             Result (I, J) := Left (I, J) / Right;
  4103.          end loop;
  4104.       end loop;
  4105.  
  4106.       return (Result);
  4107.    end "/";
  4108.  
  4109.    pragma Page;
  4110.    -------------------------------------------------------------------
  4111.  
  4112.    function Inverse (Item: Matrix) return Matrix is
  4113.  
  4114.       --!-------------------------------------------------------------
  4115.       --!
  4116.       --! Name:
  4117.       --!    Inverse
  4118.       --!
  4119.       --! Purpose:
  4120.       --!    This function calculates the single inverse of a matrix.
  4121.       --!
  4122.       --! Parameters:
  4123.       --!    Item
  4124.       --!       is the matrix to invert.
  4125.       --!
  4126.       --! Exceptions:
  4127.       --!    Matrix_Error
  4128.       --!       is raised if the matrix is not square.
  4129.       --!
  4130.       --!    Inverse_Error
  4131.       --!       is raised if the matrix inverse cannot be perfomed.
  4132.       --!
  4133.       --! Notes:
  4134.       --!    Only 3x3 matrices (or smaller) will be inverted.
  4135.       --!
  4136.       --!-------------------------------------------------------------
  4137.  
  4138.       function Det (Item: Matrix) return Element is
  4139.          -- Compute the determinant of a 2x2 matrix.
  4140.       begin
  4141.          if (Item'Length (1) /= 2) or
  4142.             (Item'Length (2) /= 2) then
  4143.             raise Matrix_Error;
  4144.          else
  4145.             declare
  4146.                A: Element renames
  4147.                   Item (Item'First (1),     Item'First (2));
  4148.                B: Element renames
  4149.                   Item (Item'First (1),     Item'First (2) + 1);
  4150.                C: Element renames
  4151.                   Item (Item'First (1) + 1, Item'First (2));
  4152.                D: Element renames
  4153.                   Item (Item'First (1) + 1, Item'First (2) + 1);
  4154.             begin
  4155.                return (A*D - B*C);
  4156.             end;
  4157.          end if;
  4158.       end Det;
  4159.  
  4160.       pragma Page;
  4161.       ----------------------------------------------------------------
  4162.  
  4163.    begin
  4164.       if (Item'Length (1) /= Item'Length (2)) then
  4165.          raise Matrix_Error;
  4166.       end if;
  4167.  
  4168.       if (Item'Length (1) = 1) then
  4169.          return (1.0 / Item);
  4170.  
  4171.       elsif (Item'Length (1) = 2) then
  4172.  
  4173.          declare
  4174.             A: Element renames
  4175.                Item (Item'First (1),     Item'First (2));
  4176.             B: Element renames
  4177.                Item (Item'First (1),     Item'First (2) + 1);
  4178.             C: Element renames
  4179.                Item (Item'First (1) + 1, Item'First (2));
  4180.             D: Element renames
  4181.                Item (Item'First (1) + 1, Item'First (2) + 1);
  4182.             X: Element := Det (Item);
  4183.          begin
  4184.             if (X = Zero) then
  4185.                raise Inverse_Error;
  4186.             else
  4187.                return (( D/X, -B/X),
  4188.                        (-C/X,  A/X));
  4189.             end if;
  4190.          end;
  4191.  
  4192.       elsif (Item'Length (1) = 3) then
  4193.          declare
  4194.             A: Element renames
  4195.                Item (Item'First (1),     Item'First (2));
  4196.             B: Element renames
  4197.                Item (Item'First (1),     Item'First (2) + 1);
  4198.             C: Element renames
  4199.                Item (Item'First (1),     Item'First (2) + 2);
  4200.             D: Element renames
  4201.                Item (Item'First (1) + 1, Item'First (2));
  4202.             E: Element renames
  4203.                Item (Item'First (1) + 1, Item'First (2) + 1);
  4204.             F: Element renames
  4205.                Item (Item'First (1) + 1, Item'First (2) + 2);
  4206.             G: Element renames
  4207.                Item (Item'First (1) + 2, Item'First (2));
  4208.             H: Element renames
  4209.                Item (Item'First (1) + 2, Item'First (2) + 1);
  4210.             I: Element renames
  4211.                Item (Item'First (1) + 2, Item'First (2) + 2);
  4212.  
  4213.             Result: Matrix (Item'First(1) .. Item'Last(1),
  4214.                             Item'First(2) .. Item'Last(2));
  4215.  
  4216.             A1: Element renames
  4217.                 Result (Result'First (1),     Result'First (2));
  4218.             B1: Element renames
  4219.                 Result (Result'First (1),     Result'First (2) + 1);
  4220.             C1: Element renames
  4221.                 Result (Result'First (1),     Result'First (2) + 2);
  4222.             D1: Element renames
  4223.                 Result (Result'First (1) + 1, Result'First (2));
  4224.             E1: Element renames
  4225.                 Result (Result'First (1) + 1, Result'First (2) + 1);
  4226.             F1: Element renames
  4227.                 Result (Result'First (1) + 1, Result'First (2) + 2);
  4228.             G1: Element renames
  4229.                 Result (Result'First (1) + 2, Result'First (2));
  4230.             H1: Element renames
  4231.                 Result (Result'First (1) + 2, Result'First (2) + 1);
  4232.             I1: Element renames
  4233.                 Result (Result'First (1) + 2, Result'First (2) + 2);
  4234.  
  4235.             X: Element := (A*E*I + B*F*G + C*D*H -
  4236.                            C*E*G - B*D*I - A*F*H);
  4237.          begin
  4238.             if (X = Zero) then
  4239.                raise Inverse_Error;
  4240.             else
  4241.                -- Create matrix of cofactors.
  4242.                A1 := + Det (Matrix' ((E,F),
  4243.                                      (H,I)));
  4244.                B1 := - Det (Matrix' ((D,F),
  4245.                                      (G,I)));
  4246.                C1 := + Det (Matrix' ((D,E),
  4247.                                      (G,H)));
  4248.                D1 := - Det (Matrix' ((B,C),
  4249.                                      (H,I)));
  4250.                E1 := + Det (Matrix' ((A,C),
  4251.                                      (G,I)));
  4252.                F1 := - Det (Matrix' ((A,B),
  4253.                                      (G,H)));
  4254.                G1 := + Det (Matrix' ((B,C),
  4255.                                      (E,F)));
  4256.                H1 := - Det (Matrix' ((A,C),
  4257.                                      (D,F)));
  4258.                I1 := + Det (Matrix' ((A,B),
  4259.                                      (D,E)));
  4260.  
  4261.                -- Generate adjoint matrix.
  4262.                Result := Transpose (Result);
  4263.  
  4264.                return (Result / X);
  4265.             end if;
  4266.          end;
  4267.       else
  4268.          raise Matrix_Error; -- Gaussian elimination required.
  4269.       end if;
  4270.    end Inverse;
  4271.  
  4272.    pragma Page;
  4273.    -------------------------------------------------------------------
  4274.  
  4275.    function "**" (Left: Matrix; Right: Integer) return Matrix is
  4276.  
  4277.       --!-------------------------------------------------------------
  4278.       --!
  4279.       --! Name:
  4280.       --!    "**"
  4281.       --!
  4282.       --! Purpose:
  4283.       --!    This function computes the general inverse of a matrix.
  4284.       --!
  4285.       --! Parameters:
  4286.       --!    Left
  4287.       --!       is the matrix to be inverted.
  4288.       --!
  4289.       --!    Right
  4290.       --!       is the power of the inversion.
  4291.       --!
  4292.       --! Exceptions:
  4293.       --!    Matrix_Error
  4294.       --!       is raised if the matrix is not square.
  4295.       --!
  4296.       --!    Inverse_Error
  4297.       --!       is raised if the matrix inverse cannot be perfomed.
  4298.       --!
  4299.       --! Notes:
  4300.       --!    Only 3x3 matrices (or smaller) will be inverted.
  4301.       --!
  4302.       --!-------------------------------------------------------------
  4303.  
  4304.       Factor,
  4305.       Result: Matrix (Left'range (1), Left'range (2));
  4306.  
  4307.    begin
  4308.       if (Right = -1) then
  4309.          return (Inverse (Left));
  4310.       end if;
  4311.  
  4312.       if (Left'Length (1) /= Left'Length (2)) then
  4313.          raise Matrix_Error;
  4314.       end if;
  4315.  
  4316.       if (Right = 0) then
  4317.          return (Identity (Left));
  4318.  
  4319.       elsif (Right > 0) then
  4320.          Factor := Left;
  4321.          Result := Factor;
  4322.  
  4323.       elsif (Right < 0) then
  4324.          Factor := Inverse (Left);
  4325.          Result := Factor;
  4326.       end if;
  4327.  
  4328.       for I in 1 .. Integer'Pred (abs (Right)) loop
  4329.          Result := Result * Factor;
  4330.       end loop;
  4331.  
  4332.       return (Result);
  4333.    end "**";
  4334.  
  4335. end Kalman_Matrix_Lib;
  4336. --::::::::::::::::::::::::::::
  4337. --KALMAN-STRING-SPEC.ADA
  4338. --::::::::::::::::::::::::::::
  4339.  
  4340. package Kalman_String is
  4341.  
  4342.    --!----------------------------------------------------------------
  4343.    --!
  4344.    --! Name:
  4345.    --!    Kalman_String
  4346.    --!
  4347.    --! Purpose:
  4348.    --!    This package provides a text type and procedures necessary
  4349.    --!    to initialize, compare and manipulate items of the type.
  4350.    --!
  4351.    --! Adapted from:
  4352.    --!    Common APSE Interface Set
  4353.    --!    Version 1.3, August 1984
  4354.    --!    Ada Joint Program Office
  4355.    --!
  4356.    --! Exceptions:
  4357.    --!    Not applicable.
  4358.    --!
  4359.    --! Notes:
  4360.    --!    Not applicable.
  4361.    --!
  4362.    --! Contract:
  4363.    --!    Ada Tracking Package Using Kalman Filter Methods
  4364.    --!    Contract No. N66001-85-C-0044 (31 December 1984)
  4365.    --!
  4366.    --! Prepared for:
  4367.    --!    Naval Ocean Systems Center (WIS JPMO)
  4368.    --!    271 Catalina Blvd., Building A-33
  4369.    --!    San Diego, CA 92152
  4370.    --!
  4371.    --! Prepared by:
  4372.    --!    Software Systems Engineering
  4373.    --!    Federal Systems Group
  4374.    --!
  4375.    --!    Sanders Associates, Inc.
  4376.    --!    95 Canal Street
  4377.    --!    Nashua, NH 03061
  4378.    --!
  4379.    --! Author:
  4380.    --!    Daryl R. Winters
  4381.    --!
  4382.    --! Changes:
  4383.    --!    03-APR-1985
  4384.    --!       Moved Text_Data type declaration from body to private
  4385.    --!       part of specification because TeleSoft could not find
  4386.    --!       the components of an incomplete type.
  4387.    --!
  4388.    --!    04-APR-1985
  4389.    --!       Changed Kalman_Text to Kalman_String because of TeleSoft
  4390.    --!       file naming conflict with Kalman_Text_Io.
  4391.    --!
  4392.    --!----------------------------------------------------------------
  4393.  
  4394.    subtype Index is Natural;
  4395.    type Text_Type is limited private;
  4396.  
  4397.    -------------------------------------------------------------------
  4398.  
  4399.    function Length (Text : in Text_Type) return Index;
  4400.    function Value  (Text : in Text_Type) return String;
  4401.    function Empty  (Text : in Text_Type) return Boolean;
  4402.  
  4403.    -------------------------------------------------------------------
  4404.  
  4405.    procedure Initialize (Text : in out Text_Type);
  4406.    procedure Free       (Text : in out Text_Type);
  4407.  
  4408.    -------------------------------------------------------------------
  4409.  
  4410.    function Text (Value : in String)    return Text_Type;
  4411.    function Text (Value : in Character) return Text_Type;
  4412.  
  4413.    -------------------------------------------------------------------
  4414.  
  4415.    function "&" (Left  : in Text_Type;
  4416.                  Right : in Text_Type) return Text_Type;
  4417.    function "&" (Left  : in Text_Type;
  4418.                  Right : in String)    return Text_Type;
  4419.    function "&" (Left  : in Text_Type;
  4420.                  Right : in Character) return Text_Type;
  4421.    function "&" (Left  : in String;
  4422.                  Right : in Text_Type) return Text_Type;
  4423.    function "&" (Left  : in Character;
  4424.                  Right : in Text_Type) return Text_Type;
  4425.  
  4426.    -------------------------------------------------------------------
  4427.  
  4428.    function "="  (Left  : in Text_Type;
  4429.                   Right : in Text_Type) return Boolean;
  4430.    function "<"  (Left  : in Text_Type;
  4431.                   Right : in Text_Type) return Boolean;
  4432.    function "<=" (Left  : in Text_Type;
  4433.                   Right : in Text_Type) return Boolean;
  4434.    function ">"  (Left  : in Text_Type;
  4435.                   Right : in Text_Type) return Boolean;
  4436.    function ">=" (Left  : in Text_Type;
  4437.                   Right : in Text_Type) return Boolean;
  4438.  
  4439.    -------------------------------------------------------------------
  4440.  
  4441.    procedure Set (Object : in out Text_Type;
  4442.                   Value  : in     Text_Type);
  4443.    procedure Set (Object : in out Text_Type;
  4444.                   Value  : in     String);
  4445.    procedure Set (Object : in out Text_Type;
  4446.                   Value  : in     Character);
  4447.  
  4448.    -------------------------------------------------------------------
  4449.  
  4450.    procedure Append (Tail : in     Text_Type;
  4451.                      To   : in out Text_Type);
  4452.    procedure Append (Tail : in     String;
  4453.                      To   : in out Text_Type);
  4454.    procedure Append (Tail : in     Character;
  4455.                      To   : in out Text_Type);
  4456.  
  4457.    -------------------------------------------------------------------
  4458.  
  4459.    procedure Amend (Object   : in out Text_Type;
  4460.                     By       : in     Text_Type;
  4461.                     Position : in     Index := 1);
  4462.    procedure Amend (Object   : in out Text_Type;
  4463.                     By       : in     String;
  4464.                     Position : in     Index := 1);
  4465.    procedure Amend (Object   : in out Text_Type;
  4466.                     By       : in     Character;
  4467.                     Position : in     Index := 1);
  4468.  
  4469.    -------------------------------------------------------------------
  4470.  
  4471.    function Locate (Fragment : in Text_Type;
  4472.                     Within   : in Text_Type;
  4473.                     Position : in Index := 1) return Index;
  4474.    function Locate (Fragment : in String;
  4475.                     Within   : in Text_Type;
  4476.                     Position : in Index := 1) return Index;
  4477.    function Locate (Fragment : in Character;
  4478.                     Within   : in Text_Type;
  4479.                     Position : in Index := 1) return Index;
  4480.  
  4481. private
  4482.  
  4483.    type Text_Data;
  4484.    type Text_Type is access Text_Data;
  4485.  
  4486.    type Text_Data is
  4487.       record
  4488.          Length : Index := 0;
  4489.          Value  : String (1..256);
  4490.       end record;
  4491.  
  4492. end Kalman_String;
  4493. --::::::::::::::::::::::::::::
  4494. --KALMAN-STRING-BODY.ADA
  4495. --::::::::::::::::::::::::::::
  4496.  
  4497. package body Kalman_String is
  4498.  
  4499.    --!----------------------------------------------------------------
  4500.    --!
  4501.    --! Name:
  4502.    --!    Kalman_String
  4503.    --!
  4504.    --! Purpose:
  4505.    --!    This package body provides the procedures necessary
  4506.    --!    to initialize, compare, and manipulate items of
  4507.    --!    the private type Text.
  4508.    --!
  4509.    --! Exceptions:
  4510.    --!    Not applicable.
  4511.    --!
  4512.    --! Notes:
  4513.    --!    Not applicable.
  4514.    --!
  4515.    --! Contract:
  4516.    --!    Ada Tracking Package Using Kalman Filter Methods
  4517.    --!    Contract No. N66001-85-C-0044 (31 December 1984)
  4518.    --!
  4519.    --! Prepared for:
  4520.    --!    Naval Ocean Systems Center (WIS JPMO)
  4521.    --!    271 Catalina Blvd., Building A-33
  4522.    --!    San Diego, CA 92152
  4523.    --!
  4524.    --! Prepared by:
  4525.    --!    Software Systems Engineering
  4526.    --!    Federal Systems Group
  4527.    --!
  4528.    --!    Sanders Associates, Inc.
  4529.    --!    95 Canal Street
  4530.    --!    Nashua, NH 03061
  4531.    --!
  4532.    --! Author:
  4533.    --!    Daryl R. Winters
  4534.    --!
  4535.    --! Changes:
  4536.    --!    03-APR-1985
  4537.    --!       Moved Text_Data type declaration from body to private
  4538.    --!       part of specification because TeleSoft could not find
  4539.    --!       the components of an incomplete type.
  4540.    --!
  4541.    --!    04-APR-1985
  4542.    --!       Changed Kalman_Text to Kalman_String because of TeleSoft
  4543.    --!       file naming conflict with Kalman_Text_Io.
  4544.    --!
  4545.    --!----------------------------------------------------------------
  4546.  
  4547.    pragma Page;
  4548.    ------------------------------------------------------------------
  4549.  
  4550.    function Check (Text : in Text_Type) return Text_Type is
  4551.  
  4552.       --!-------------------------------------------------------------
  4553.       --!
  4554.       --! Name:
  4555.       --!    Check
  4556.       --!
  4557.       --! Purpose:
  4558.       --!    This local function returns an access to text.
  4559.       --!    If the input access variable has not yet been
  4560.       --!    allocated, then Check performs the allocation.
  4561.       --!
  4562.       --! Parameters:
  4563.       --!    Text
  4564.       --!       is an access to some text.
  4565.       --!
  4566.       --! Exceptions:
  4567.       --!    Not applicable.
  4568.       --!
  4569.       --! Notes:
  4570.       --!    Not applicable.
  4571.       --!
  4572.       --!-------------------------------------------------------------
  4573.  
  4574.       Result : Text_Type := Text;
  4575.       Value  : Text_Data;
  4576.  
  4577.    begin
  4578.       begin
  4579.          Value := Text.all;
  4580.       exception
  4581.          when Constraint_Error =>
  4582.             Result := new Text_Data;
  4583.       end;
  4584.  
  4585.       return Result;
  4586.    end Check;
  4587.  
  4588.    pragma Page;
  4589.    ------------------------------------------------------------------
  4590.  
  4591.    function Length (Text : in Text_Type) return Index is
  4592.  
  4593.       --!-------------------------------------------------------------
  4594.       --!
  4595.       --! Name:
  4596.       --!    Length
  4597.       --!
  4598.       --! Purpose:
  4599.       --!    This function returns the length of the text string
  4600.       --!    contained in the text data.
  4601.       --!
  4602.       --! Parameters:
  4603.       --!    Text
  4604.       --!       is an access to text data.
  4605.       --!
  4606.       --! Exceptions:
  4607.       --!    Not applicable.
  4608.       --!
  4609.       --! Notes:
  4610.       --!    Not applicable.
  4611.       --!
  4612.       --!-------------------------------------------------------------
  4613.  
  4614.       Result : Text_Type := Check (Text);
  4615.  
  4616.    begin
  4617.       return Result.Length;
  4618.    end Length;
  4619.  
  4620.    pragma Page;
  4621.    ------------------------------------------------------------------
  4622.  
  4623.    function Value (Text : in Text_Type) return String is
  4624.  
  4625.       --!-------------------------------------------------------------
  4626.       --!
  4627.       --! Name:
  4628.       --!    Value
  4629.       --!
  4630.       --! Purpose:
  4631.       --!    This function returns the string contained within the
  4632.       --!    text data.
  4633.       --!
  4634.       --! Parameters:
  4635.       --!    Text
  4636.       --!       is an access to text data.
  4637.       --!
  4638.       --! Exceptions:
  4639.       --!    Not applicable.
  4640.       --!
  4641.       --! Notes:
  4642.       --!    Not applicable.
  4643.       --!
  4644.       --!-------------------------------------------------------------
  4645.  
  4646.       Result : Text_Type := Check (Text);
  4647.  
  4648.    begin
  4649.       return Result.Value (1 .. Result.Length);
  4650.    end Value;
  4651.  
  4652.    pragma Page;
  4653.    ------------------------------------------------------------------
  4654.  
  4655.    function Empty (Text : in Text_Type) return Boolean is
  4656.  
  4657.       --!-------------------------------------------------------------
  4658.       --!
  4659.       --! Name:
  4660.       --!    Empty
  4661.       --!
  4662.       --! Purpose:
  4663.       --!    This function returns a boolean value which indicates
  4664.       --!    whether the indicated text is empty.
  4665.       --!
  4666.       --! Parameters:
  4667.       --!    Text
  4668.       --!       is an access to text data.
  4669.       --!
  4670.       --! Exceptions:
  4671.       --!    Not applicable.
  4672.       --!
  4673.       --! Notes:
  4674.       --!    Not applicable.
  4675.       --!
  4676.       --!-------------------------------------------------------------
  4677.  
  4678.       Result : Text_Type := Check (Text);
  4679.  
  4680.    begin
  4681.       return Result.Length = 0;
  4682.    end Empty;
  4683.  
  4684.    pragma Page;
  4685.    ------------------------------------------------------------------
  4686.  
  4687.    procedure Initialize (Text : in out Text_Type) is
  4688.  
  4689.       --!-------------------------------------------------------------
  4690.       --!
  4691.       --! Name:
  4692.       --!    Initialize
  4693.       --!
  4694.       --! Purpose:
  4695.       --!    This procedure destroys the access by Text to Text_Data
  4696.       --!    (if any access exists) and allocates new Text_Data to
  4697.       --!    which Text is pointed.
  4698.       --!
  4699.       --! Parameters:
  4700.       --!    Text
  4701.       --!       is an access to Text_Data.
  4702.       --!
  4703.       --! Exceptions:
  4704.       --!    Not applicable.
  4705.       --!
  4706.       --! Notes:
  4707.       --!    Not applicable.
  4708.       --!
  4709.       --!-------------------------------------------------------------
  4710.  
  4711.    begin
  4712.       Free (Text);
  4713.       Text := new Text_Data;
  4714.    end Initialize;
  4715.  
  4716.    pragma Page;
  4717.    ------------------------------------------------------------------
  4718.  
  4719.    procedure Free (Text : in out Text_Type) is
  4720.  
  4721.       --!-------------------------------------------------------------
  4722.       --!
  4723.       --! Name:
  4724.       --!    Free
  4725.       --!
  4726.       --! Purpose:
  4727.       --!    This procedure destroys the access of Text to Text_Data.
  4728.       --!
  4729.       --! Parameters:
  4730.       --!    Text
  4731.       --!       is an access to text data.
  4732.       --!
  4733.       --! Exceptions:
  4734.       --!    Not applicable.
  4735.       --!
  4736.       --! Notes:
  4737.       --!    Not applicable.
  4738.       --!
  4739.       --!-------------------------------------------------------------
  4740.  
  4741.    begin
  4742.       Text := null;
  4743.    end Free;
  4744.  
  4745.    pragma Page;
  4746.    ------------------------------------------------------------------
  4747.  
  4748.    function Text (Value : in String) return Text_Type is
  4749.  
  4750.       --!-------------------------------------------------------------
  4751.       --!
  4752.       --! Name:
  4753.       --!    Text
  4754.       --!
  4755.       --! Purpose:
  4756.       --!    This function returns text data initialized from
  4757.       --!    the input string.
  4758.       --!
  4759.       --! Parameters:
  4760.       --!    Value
  4761.       --!       is a string.
  4762.       --!
  4763.       --! Exceptions:
  4764.       --!    Not applicable.
  4765.       --!
  4766.       --! Notes:
  4767.       --!    Not applicable.
  4768.       --!
  4769.       --!-------------------------------------------------------------
  4770.  
  4771.       Result : Text_Type;
  4772.  
  4773.    begin
  4774.       Initialize (Result);
  4775.  
  4776.       if (Value'Length > 0) then
  4777.          Result.Value (1 .. Value'Length) := Value;
  4778.       end if;
  4779.  
  4780.       Result.Length := Value'Length;
  4781.       return Result;
  4782.    end Text;
  4783.  
  4784.    pragma Page;
  4785.    ------------------------------------------------------------------
  4786.  
  4787.    function Text (Value : in Character) return Text_Type is
  4788.  
  4789.       --!-------------------------------------------------------------
  4790.       --!
  4791.       --! Name:
  4792.       --!    Text
  4793.       --!
  4794.       --! Purpose:
  4795.       --!    This function returns text data initialized from the
  4796.       --!    input character.
  4797.       --!
  4798.       --! Parameters:
  4799.       --!    Value
  4800.       --!       is a character.
  4801.       --!
  4802.       --! Exceptions:
  4803.       --!    Not applicable.
  4804.       --!
  4805.       --! Notes:
  4806.       --!    Not applicable.
  4807.       --!
  4808.       --!-------------------------------------------------------------
  4809.  
  4810.       Result : Text_Type;
  4811.  
  4812.    begin
  4813.       Initialize (Result);
  4814.  
  4815.       Result.Value (1) := Value;
  4816.       Result.Length := 1;
  4817.       return Result;
  4818.    end Text;
  4819.  
  4820.    pragma Page;
  4821.    ------------------------------------------------------------------
  4822.  
  4823.    function "&" (Left  : in Text_Type;
  4824.                  Right : in Text_Type) return Text_Type is
  4825.  
  4826.       --!-------------------------------------------------------------
  4827.       --!
  4828.       --! Name:
  4829.       --!    "&"
  4830.       --!
  4831.       --! Purpose:
  4832.       --!    This function returns new text in which the Right
  4833.       --!    text has been appended to the Left text.
  4834.       --!
  4835.       --! Parameters:
  4836.       --!    Left
  4837.       --!       is an access to text data.
  4838.       --!    Right
  4839.       --!       is an access to text data.
  4840.       --!
  4841.       --! Exceptions:
  4842.       --!    Not applicable.
  4843.       --!
  4844.       --! Notes:
  4845.       --!    Not applicable.
  4846.       --!
  4847.       --!-------------------------------------------------------------
  4848.  
  4849.       Result : Text_Type;
  4850.       L : Text_Type := Check (Left);
  4851.       R : Text_Type := Check (Right);
  4852.  
  4853.    begin
  4854.       Initialize (Result);
  4855.  
  4856.       Result.Value (1 .. L.Length) := L.Value (1 .. L.Length);
  4857.       Result.Value (L.Length + 1 .. L.Length + R.Length) 
  4858.          := R.Value (1 .. R.Length);
  4859.       Result.Length := L.Length + R.Length;
  4860.       return Result;
  4861.    end "&";
  4862.  
  4863.    pragma Page;
  4864.    ------------------------------------------------------------------
  4865.  
  4866.    function "&" (Left  : in Text_Type;
  4867.                  Right : in String) return Text_Type is
  4868.  
  4869.       --!-------------------------------------------------------------
  4870.       --!
  4871.       --! Name:
  4872.       --!    "&"
  4873.       --!
  4874.       --! Purpose:
  4875.       --!    This function returns new text in which the Right
  4876.       --!    string has been appended to the Left text.
  4877.       --!
  4878.       --! Parameters:
  4879.       --!    Left
  4880.       --!       is an access to text data.
  4881.       --!    Right
  4882.       --!       is a string.
  4883.       --!
  4884.       --! Exceptions:
  4885.       --!    Not applicable.
  4886.       --!
  4887.       --! Notes:
  4888.       --!    Not applicable.
  4889.       --!
  4890.       --!-------------------------------------------------------------
  4891.  
  4892.    begin
  4893.       return Left & Text (Right);
  4894.    end "&";
  4895.  
  4896.    pragma Page;
  4897.    ------------------------------------------------------------------
  4898.  
  4899.    function "&" (Left  : in Text_Type;
  4900.                  Right : in Character) return Text_Type is
  4901.  
  4902.       --!-------------------------------------------------------------
  4903.       --!
  4904.       --! Name:
  4905.       --!    "&"
  4906.       --!
  4907.       --! Purpose:
  4908.       --!    This function returns new text in which the Right
  4909.       --!    character has been appended to the Left text.
  4910.       --!
  4911.       --! Parameters:
  4912.       --!    Left
  4913.       --!       is an access to text data.
  4914.       --!    Right
  4915.       --!       is a character.
  4916.       --!
  4917.       --! Exceptions:
  4918.       --!    Not applicable.
  4919.       --!
  4920.       --! Notes:
  4921.       --!    Not applicable.
  4922.       --!
  4923.       --!-------------------------------------------------------------
  4924.  
  4925.    begin
  4926.       return Left & Text (Right);
  4927.    end "&";
  4928.  
  4929.    pragma Page;
  4930.    ------------------------------------------------------------------
  4931.  
  4932.    function "&" (Left  : in String;
  4933.                  Right : in Text_Type) return Text_Type is
  4934.  
  4935.       --!-------------------------------------------------------------
  4936.       --!
  4937.       --! Name:
  4938.       --!    "&"
  4939.       --!
  4940.       --! Purpose:
  4941.       --!    This function returns new text in which the Right
  4942.       --!    text has been appended to the Left string.
  4943.       --!
  4944.       --! Parameters:
  4945.       --!    Left
  4946.       --!       is a string.
  4947.       --!    Right
  4948.       --!       is an access to text data.
  4949.       --!
  4950.       --! Exceptions:
  4951.       --!    Not applicable.
  4952.       --!
  4953.       --! Notes:
  4954.       --!    Not applicable.
  4955.       --!
  4956.       --!-------------------------------------------------------------
  4957.  
  4958.    begin
  4959.       return Text (Left) & Right;
  4960.    end "&";
  4961.  
  4962.    pragma Page;
  4963.    ------------------------------------------------------------------
  4964.  
  4965.    function "&" (Left  : in Character;
  4966.                  Right : in Text_Type) return Text_Type is
  4967.  
  4968.       --!-------------------------------------------------------------
  4969.       --!
  4970.       --! Name:
  4971.       --!    "&"
  4972.       --!
  4973.       --! Purpose:
  4974.       --!    This function returns new text in which the Right
  4975.       --!    text has been appended to the Left character.
  4976.       --!
  4977.       --! Parameters:
  4978.       --!    Left
  4979.       --!       is a character.
  4980.       --!    Right
  4981.       --!       is an access to text data.
  4982.       --!
  4983.       --! Exceptions:
  4984.       --!    Not applicable.
  4985.       --!
  4986.       --! Notes:
  4987.       --!    Not applicable.
  4988.       --!
  4989.       --!-------------------------------------------------------------
  4990.  
  4991.    begin
  4992.       return Text (Left) & Right;
  4993.    end "&";
  4994.  
  4995.    pragma Page;
  4996.    ------------------------------------------------------------------
  4997.  
  4998.    function "=" (Left  : in Text_Type;
  4999.                  Right : in Text_Type) return Boolean is
  5000.  
  5001.       --!-------------------------------------------------------------
  5002.       --!
  5003.       --! Name:
  5004.       --!    "="
  5005.       --!
  5006.       --! Purpose:
  5007.       --!    This function returns a boolean which indicates whether
  5008.       --!    the Left text is equal to the Right text.
  5009.       --!
  5010.       --! Parameters:
  5011.       --!    Left 
  5012.       --!       is an access to text data.
  5013.       --!    Right
  5014.       --!       is an access to text data.
  5015.       --!
  5016.       --! Exceptions:
  5017.       --!    Not applicable.
  5018.       --!
  5019.       --! Notes:
  5020.       --!    Not applicable.
  5021.       --!
  5022.       --!-------------------------------------------------------------
  5023.  
  5024.       L : Text_Type := Check (Left);
  5025.       R : Text_Type := Check (Right);
  5026.  
  5027.    begin
  5028.       return L.Value (1 .. L.Length) = R.Value (1 .. R.Length);
  5029.    end "=";
  5030.  
  5031.    pragma Page;
  5032.    ------------------------------------------------------------------
  5033.  
  5034.    function "<" (Left  : in Text_Type;
  5035.                  Right : in Text_Type) return Boolean is
  5036.  
  5037.       --!-------------------------------------------------------------
  5038.       --!
  5039.       --! Name:
  5040.       --!    "<"
  5041.       --!
  5042.       --! Purpose:
  5043.       --!    This function returns a boolean which indicates whether
  5044.       --!    the Left text is less than the Right text.
  5045.       --!
  5046.       --! Parameters:
  5047.       --!    Left 
  5048.       --!       is an access to text data.
  5049.       --!    Right
  5050.       --!       is an access to text data.
  5051.       --!
  5052.       --! Exceptions:
  5053.       --!    Not applicable.
  5054.       --!
  5055.       --! Notes:
  5056.       --!    Not applicable.
  5057.       --!
  5058.       --!-------------------------------------------------------------
  5059.  
  5060.       L : Text_Type := Check (Left);
  5061.       R : Text_Type := Check (Right);
  5062.  
  5063.    begin
  5064.       return L.Value (1 .. L.Length) < R.Value (1 .. R.Length);
  5065.    end "<";
  5066.  
  5067.    pragma Page;
  5068.    ------------------------------------------------------------------
  5069.  
  5070.    function "<=" (Left  : in Text_Type;
  5071.                   Right : in Text_Type) return Boolean is
  5072.  
  5073.       --!-------------------------------------------------------------
  5074.       --!
  5075.       --! Name:
  5076.       --!    "<="
  5077.       --!
  5078.       --! Purpose:
  5079.       --!    This function returns a boolean which indicates whether
  5080.       --!    the Left text is less than or equal to the Right text.
  5081.       --!
  5082.       --! Parameters:
  5083.       --!    Left 
  5084.       --!       is an access to text data.
  5085.       --!    Right
  5086.       --!       is an access to text data.
  5087.       --!
  5088.       --! Exceptions:
  5089.       --!    Not applicable.
  5090.       --!
  5091.       --! Notes:
  5092.       --!    Not applicable.
  5093.       --!
  5094.       --!-------------------------------------------------------------
  5095.  
  5096.       L : Text_Type := Check (Left);
  5097.       R : Text_Type := Check (Right);
  5098.  
  5099.    begin
  5100.       return L.Value (1 .. L.Length) <= R.Value (1 .. R.Length);
  5101.    end "<=";
  5102.  
  5103.    pragma Page;
  5104.    ------------------------------------------------------------------
  5105.  
  5106.    function ">" (Left  : in Text_Type;
  5107.                  Right : in Text_Type) return Boolean is
  5108.  
  5109.       --!-------------------------------------------------------------
  5110.       --!
  5111.       --! Name:
  5112.       --!    ">"
  5113.       --!
  5114.       --! Purpose:
  5115.       --!    This function returns a boolean which indicates whether
  5116.       --!    the Left text is greater than the Right text.
  5117.       --!
  5118.       --! Parameters:
  5119.       --!    Left 
  5120.       --!       is an access to text data.
  5121.       --!    Right
  5122.       --!       is an access to text data.
  5123.       --!
  5124.       --! Exceptions:
  5125.       --!    Not applicable.
  5126.       --!
  5127.       --! Notes:
  5128.       --!    Not applicable.
  5129.       --!
  5130.       --!-------------------------------------------------------------
  5131.  
  5132.       L : Text_Type := Check (Left);
  5133.       R : Text_Type := Check (Right);
  5134.  
  5135.    begin
  5136.       return L.Value (1 .. L.Length) > R.Value (1 .. R.Length);
  5137.    end ">";
  5138.  
  5139.    pragma Page;
  5140.    ------------------------------------------------------------------
  5141.  
  5142.    function ">=" (Left  : in Text_Type;
  5143.                   Right : in Text_Type) return Boolean is
  5144.  
  5145.       --!-------------------------------------------------------------
  5146.       --!
  5147.       --! Name:
  5148.       --!    ">="
  5149.       --!
  5150.       --! Purpose:
  5151.       --!    This function returns a boolean which indicates whether
  5152.       --!    the Left text is greater than or equal to the Right text.
  5153.       --!
  5154.       --! Parameters:
  5155.       --!    Left 
  5156.       --!       is an access to text data.
  5157.       --!    Right
  5158.       --!       is an access to text data.
  5159.       --!
  5160.       --! Exceptions:
  5161.       --!    Not applicable.
  5162.       --!
  5163.       --! Notes:
  5164.       --!    Not applicable.
  5165.       --!
  5166.       --!-------------------------------------------------------------
  5167.  
  5168.       L : Text_Type := Check (Left);
  5169.       R : Text_Type := Check (Right);
  5170.  
  5171.    begin
  5172.       return L.Value (1 .. L.Length) >= R.Value (1 .. R.Length);
  5173.    end ">=";
  5174.  
  5175.    pragma Page;
  5176.    ------------------------------------------------------------------
  5177.  
  5178.    procedure Set (Object : in out Text_Type;
  5179.                   Value  : in     Text_Type) is
  5180.  
  5181.       --!-------------------------------------------------------------
  5182.       --!
  5183.       --! Name:
  5184.       --!    Set
  5185.       --!
  5186.       --! Purpose:
  5187.       --!    This procedure sets one text to the value of another.
  5188.       --!
  5189.       --! Parameters:
  5190.       --!    Object
  5191.       --!       is an access to text.
  5192.       --!    Value 
  5193.       --!       is an access to text.
  5194.       --!
  5195.       --! Exceptions:
  5196.       --!    Not applicable.
  5197.       --!
  5198.       --! Notes:
  5199.       --!    Not applicable.
  5200.       --!
  5201.       --!-------------------------------------------------------------
  5202.  
  5203.       Text : Text_Type := Check (Value);
  5204.  
  5205.    begin
  5206.       Initialize (Object);
  5207.       Object.all := Text.all;
  5208.    end Set;
  5209.  
  5210.    pragma Page;
  5211.    ------------------------------------------------------------------
  5212.  
  5213.    procedure Set (Object : in out Text_Type;
  5214.                   Value  : in     String) is
  5215.  
  5216.       --!-------------------------------------------------------------
  5217.       --!
  5218.       --! Name:
  5219.       --!    Set
  5220.       --!
  5221.       --! Purpose:
  5222.       --!    This procedure sets one text to the value of a string.
  5223.       --!
  5224.       --! Parameters:
  5225.       --!    Object
  5226.       --!       is an access to text.
  5227.       --!    Value 
  5228.       --!       is a string.
  5229.       --!
  5230.       --! Exceptions:
  5231.       --!    Not applicable.
  5232.       --!
  5233.       --! Notes:
  5234.       --!    Not applicable.
  5235.       --!
  5236.       --!-------------------------------------------------------------
  5237.  
  5238.    begin
  5239.       Set (Object, Text (Value));
  5240.    end Set;
  5241.  
  5242.    pragma Page;
  5243.    ------------------------------------------------------------------
  5244.  
  5245.    procedure Set (Object : in out Text_Type;
  5246.                   Value  : in     Character) is
  5247.  
  5248.       --!-------------------------------------------------------------
  5249.       --!
  5250.       --! Name:
  5251.       --!    Set
  5252.       --!
  5253.       --! Purpose:
  5254.       --!    This procedure sets one text to the value of a character.
  5255.       --!
  5256.       --! Parameters:
  5257.       --!    Object
  5258.       --!       is an access to text.
  5259.       --!    Value 
  5260.       --!       is a character.
  5261.       --!
  5262.       --! Exceptions:
  5263.       --!    Not applicable.
  5264.       --!
  5265.       --! Notes:
  5266.       --!    Not applicable.
  5267.       --!
  5268.       --!-------------------------------------------------------------
  5269.  
  5270.    begin
  5271.       Set (Object, Text (Value));
  5272.    end Set;
  5273.  
  5274.    pragma Page;
  5275.    ------------------------------------------------------------------
  5276.  
  5277.    procedure Append (Tail : in     Text_Type;
  5278.                      To   : in out Text_Type) is
  5279.  
  5280.       --!-------------------------------------------------------------
  5281.       --!
  5282.       --! Name:
  5283.       --!    Append
  5284.       --!
  5285.       --! Purpose:
  5286.       --!    This procedure appends one text to another.
  5287.       --!
  5288.       --! Parameters:
  5289.       --!    Tail
  5290.       --!       is an access to text data.
  5291.       --!    To
  5292.       --!       is an access to text data.
  5293.       --!
  5294.       --! Exceptions:
  5295.       --!    Not applicable.
  5296.       --!
  5297.       --! Notes:
  5298.       --!    Not applicable.
  5299.       --!
  5300.       --!-------------------------------------------------------------
  5301.  
  5302.    begin
  5303.       To := (To & Tail);
  5304.    end Append;
  5305.  
  5306.    pragma Page;
  5307.    ------------------------------------------------------------------
  5308.  
  5309.    procedure Append (Tail : in     String;
  5310.                      To   : in out Text_Type) is
  5311.  
  5312.       --!-------------------------------------------------------------
  5313.       --!
  5314.       --! Name:
  5315.       --!    Append
  5316.       --!
  5317.       --! Purpose:
  5318.       --!    This procedure appends a string to text.
  5319.       --!
  5320.       --! Parameters:
  5321.       --!    Tail
  5322.       --!       is a string.
  5323.       --!    To
  5324.       --!       is an access to text data.
  5325.       --!
  5326.       --! Exceptions:
  5327.       --!    Not applicable.
  5328.       --!
  5329.       --! Notes:
  5330.       --!    Not applicable.
  5331.       --!
  5332.       --!-------------------------------------------------------------
  5333.  
  5334.    begin
  5335.       Append (Text (Tail), To);
  5336.    end Append;
  5337.  
  5338.    pragma Page;
  5339.    ------------------------------------------------------------------
  5340.  
  5341.    procedure Append (Tail : in     Character;
  5342.                      To   : in out Text_Type) is
  5343.  
  5344.       --!-------------------------------------------------------------
  5345.       --!
  5346.       --! Name:
  5347.       --!    Append
  5348.       --!
  5349.       --! Purpose:
  5350.       --!    This procedure appends a character to text.
  5351.       --!
  5352.       --! Parameters:
  5353.       --!    Tail
  5354.       --!       is a character.
  5355.       --!    To
  5356.       --!       is an access to text data.
  5357.       --!
  5358.       --! Exceptions:
  5359.       --!    Not applicable.
  5360.       --!
  5361.       --! Notes:
  5362.       --!    Not applicable.
  5363.       --!
  5364.       --!-------------------------------------------------------------
  5365.  
  5366.    begin
  5367.       Append (Text (Tail), To);
  5368.    end Append;
  5369.  
  5370.    pragma Page;
  5371.    ------------------------------------------------------------------
  5372.  
  5373.    procedure Amend (Object   : in out Text_Type;
  5374.                     By       : in     Text_Type;
  5375.                     Position : in     Index := 1) is
  5376.  
  5377.       --!-------------------------------------------------------------
  5378.       --!
  5379.       --! Name:
  5380.       --!    Amend
  5381.       --!
  5382.       --! Purpose:
  5383.       --!    This procedure changes the value of text
  5384.       --!    at the specified position.
  5385.       --!
  5386.       --! Parameters:
  5387.       --!    Object
  5388.       --!       is an access to text data.
  5389.       --!    By 
  5390.       --!       is an access to text data (replacement text).
  5391.       --!    Position
  5392.       --!       indicates at which point the replacement is to occur.
  5393.       --!
  5394.       --! Exceptions:
  5395.       --!    Not applicable.
  5396.       --!
  5397.       --! Notes:
  5398.       --!    Not applicable.
  5399.       --!
  5400.       --!-------------------------------------------------------------
  5401.  
  5402.       Text : Text_Type := Check (By);
  5403.  
  5404.    begin
  5405.       Object := Check (Object);
  5406.  
  5407.       Object.Value (Position .. Position + Text.Length - 1) 
  5408.          := Text.Value (1 .. Text.Length);
  5409.  
  5410.       if (Position + Text.Length > Object.Length) then
  5411.          Object.Length := Position + Text.Length;
  5412.       end if;
  5413.    end Amend;
  5414.  
  5415.    pragma Page;
  5416.    ------------------------------------------------------------------
  5417.  
  5418.    procedure Amend (Object   : in out Text_Type;
  5419.                     By       : in     String;
  5420.                     Position : in     Index := 1) is
  5421.  
  5422.       --!-------------------------------------------------------------
  5423.       --!
  5424.       --! Name:
  5425.       --!    Amend
  5426.       --!
  5427.       --! Purpose:
  5428.       --!    This procedure changes the value of text
  5429.       --!    at the specified position.
  5430.       --!
  5431.       --! Parameters:
  5432.       --!    Object
  5433.       --!       is an access to text data.
  5434.       --!    By 
  5435.       --!       is a string (replacement string).
  5436.       --!    Position
  5437.       --!       indicates at which point the replacement is to occur.
  5438.       --!
  5439.       --! Exceptions:
  5440.       --!    Not applicable.
  5441.       --!
  5442.       --! Notes:
  5443.       --!    Not applicable.
  5444.       --!
  5445.       --!-------------------------------------------------------------
  5446.  
  5447.    begin
  5448.       Amend (Object, Text (By), Position);
  5449.    end Amend;
  5450.  
  5451.    pragma Page;
  5452.    ------------------------------------------------------------------
  5453.  
  5454.    procedure Amend (Object   : in out Text_Type;
  5455.                     By       : in     Character;
  5456.                     Position : in     Index := 1) is
  5457.  
  5458.       --!-------------------------------------------------------------
  5459.       --!
  5460.       --! Name:
  5461.       --!    Amend
  5462.       --!
  5463.       --! Purpose:
  5464.       --!    This procedure changes the value of text
  5465.       --!    at the specified position.
  5466.       --!
  5467.       --! Parameters:
  5468.       --!    Object
  5469.       --!       is an access to text data.
  5470.       --!    By 
  5471.       --!       is a character (replacement character).
  5472.       --!    Position
  5473.       --!       indicates at which point the replacement is to occur.
  5474.       --!
  5475.       --! Exceptions:
  5476.       --!    Not applicable.
  5477.       --!
  5478.       --! Notes:
  5479.       --!    Not applicable.
  5480.       --!
  5481.       --!-------------------------------------------------------------
  5482.  
  5483.    begin
  5484.       Amend (Object, Text (By), Position);
  5485.    end Amend;
  5486.  
  5487.    pragma Page;
  5488.    ------------------------------------------------------------------
  5489.  
  5490.    function Locate (Fragment : in Text_Type;
  5491.                     Within   : in Text_Type;
  5492.                     Position : in Index := 1) return Index is
  5493.  
  5494.       --!-------------------------------------------------------------
  5495.       --!
  5496.       --! Name:
  5497.       --!    Locate
  5498.       --!
  5499.       --! Purpose:
  5500.       --!    This function returns the location of the fragment
  5501.       --!    within the text (or zero if the fragment is not found).
  5502.       --!
  5503.       --! Parameters:
  5504.       --!    Fragment
  5505.       --!       is an access to text data.
  5506.       --!    Within
  5507.       --!       is an access to text data.
  5508.       --!    Position
  5509.       --!       is the point at which the search for the
  5510.       --!       fragment is to commence.
  5511.       --!
  5512.       --! Exceptions:
  5513.       --!    Not applicable.
  5514.       --!
  5515.       --! Notes:
  5516.       --!    Not applicable.
  5517.       --!
  5518.       --!-------------------------------------------------------------
  5519.  
  5520.       Result : Index := 0;
  5521.       F : Text_Type := Check (Fragment);
  5522.       W : Text_Type := Check (Within);
  5523.  
  5524.    begin
  5525.       for I in Position .. W.Length - F.Length + 1 loop
  5526.  
  5527.          if (W.Value (I .. I + F.Length - 1) =
  5528.              F.Value (1 .. F.Length)) then
  5529.  
  5530.             Result := I;
  5531.             exit;
  5532.          end if;
  5533.       end loop;
  5534.  
  5535.       return Result;
  5536.    end Locate;
  5537.  
  5538.    pragma Page;
  5539.    ------------------------------------------------------------------
  5540.  
  5541.    function Locate (Fragment : in String;
  5542.                     Within   : in Text_Type;
  5543.                     Position : in Index := 1) return Index is
  5544.  
  5545.       --!-------------------------------------------------------------
  5546.       --!
  5547.       --! Name:
  5548.       --!    Locate
  5549.       --!
  5550.       --! Purpose:
  5551.       --!    This function returns the location of the fragment
  5552.       --!    within the text (or zero if the fragment is not found).
  5553.       --!
  5554.       --! Parameters:
  5555.       --!    Fragment
  5556.       --!       is a string.
  5557.       --!    Within
  5558.       --!       is an access to text data.
  5559.       --!    Position
  5560.       --!       is the point at which the search for the
  5561.       --!       fragment is to commence.
  5562.       --!
  5563.       --! Exceptions:
  5564.       --!    Not applicable.
  5565.       --!
  5566.       --! Notes:
  5567.       --!    Not applicable.
  5568.       --!
  5569.       --!-------------------------------------------------------------
  5570.  
  5571.    begin
  5572.       return Locate (Text (Fragment), Within, Position);
  5573.    end Locate;
  5574.  
  5575.    pragma Page;
  5576.    ------------------------------------------------------------------
  5577.  
  5578.    function Locate (Fragment : in Character;
  5579.                     Within   : in Text_Type;
  5580.                     Position : in Index := 1) return Index is
  5581.  
  5582.       --!-------------------------------------------------------------
  5583.       --!
  5584.       --! Name:
  5585.       --!    Locate
  5586.       --!
  5587.       --! Purpose:
  5588.       --!    This function returns the location of the fragment
  5589.       --!    within the text (or zero if the fragment is not found).
  5590.       --!
  5591.       --! Parameters:
  5592.       --!    Fragment
  5593.       --!       is a character.
  5594.       --!    Within
  5595.       --!       is an access to text data.
  5596.       --!    Position
  5597.       --!       is the point at which the search for the
  5598.       --!       fragment is to commence.
  5599.       --!
  5600.       --! Exceptions:
  5601.       --!    Not applicable.
  5602.       --!
  5603.       --! Notes:
  5604.       --!    Not applicable.
  5605.       --!
  5606.       --!-------------------------------------------------------------
  5607.  
  5608.    begin
  5609.       return Locate (Text (Fragment), Within, Position);
  5610.    end Locate;
  5611.  
  5612.    pragma Page;
  5613.    ------------------------------------------------------------------
  5614.  
  5615. begin
  5616.    null;
  5617. end Kalman_String;
  5618. --::::::::::::::::::::::::::::
  5619. --KALMAN-CHECK-SPEC.ADA
  5620. --::::::::::::::::::::::::::::
  5621.  
  5622. package Kalman_Check is
  5623.  
  5624.    --!----------------------------------------------------------------
  5625.    --!
  5626.    --! Name:
  5627.    --!    Kalman_Check
  5628.    --!
  5629.    --! Purpose:
  5630.    --!    This package determines whether the spelling of a word
  5631.    --!    matches that of a "correct" word given that certain
  5632.    --!    typing or spelling errors may have occurred.
  5633.    --!
  5634.    --! Adapted from:
  5635.    --!    Spelling Correction in User Interfaces,
  5636.    --!    Durham, Lamb, and Saxe, CMU-CS-82-151,
  5637.    --!    Carnegie-Mellon University, 1982.
  5638.    --!
  5639.    --! Interfaces:
  5640.    --!    Possibly_Correct
  5641.    --!       returns a boolean value which indicates whether the
  5642.    --!       spelling of the Word intends the spelling of the 
  5643.    --!       "correct" word.
  5644.    --!
  5645.    --! Exceptions:
  5646.    --!    Not applicable.
  5647.    --!
  5648.    --! Notes:
  5649.    --!    Single missing letters, single incorrect letters, and
  5650.    --!    transposed characters are corrected for when determining
  5651.    --!    whether the spelling might be correct.
  5652.    --!
  5653.    --! Contract:
  5654.    --!    Ada Tracking Package Using Kalman Filter Methods
  5655.    --!    Contract No. N66001-85-C-0044 (31 December 1984)
  5656.    --!
  5657.    --! Prepared for:
  5658.    --!    Naval Ocean Systems Center (WIS JPMO)
  5659.    --!    271 Catalina Blvd., Building A-33
  5660.    --!    San Diego, CA 92152
  5661.    --!
  5662.    --! Prepared by:
  5663.    --!    Software Systems Engineering
  5664.    --!    Federal Systems Group
  5665.    --!
  5666.    --!    Sanders Associates, Inc.
  5667.    --!    95 Canal Street
  5668.    --!    Nashua, NH 03061
  5669.    --!
  5670.    --! Author:
  5671.    --!    Daryl R. Winters
  5672.    --!
  5673.    --!----------------------------------------------------------------
  5674.  
  5675.    function Possibly_Correct
  5676.       (Word, Correct_Word: in String) return Boolean;
  5677.  
  5678. end Kalman_Check;
  5679. --::::::::::::::::::::::::::::
  5680. --KALMAN-CHECK-BODY.ADA
  5681. --::::::::::::::::::::::::::::
  5682.  
  5683. package body Kalman_Check is
  5684.  
  5685.    --!----------------------------------------------------------------
  5686.    --!
  5687.    --! Name:
  5688.    --!    Kalman_Check
  5689.    --!
  5690.    --! Purpose:
  5691.    --!    This package body determines whether the spelling of a word
  5692.    --!    matches that of a "correct" word given that certain
  5693.    --!    typing or spelling errors may have occurred.
  5694.    --!
  5695.    --! Exceptions:
  5696.    --!    Not applicable.
  5697.    --!
  5698.    --! Notes:
  5699.    --!    Single missing letters, single incorrect letters, and
  5700.    --!    transposed characters are corrected for when determining
  5701.    --!    whether the spelling might be correct.
  5702.    --!
  5703.    --! Contract:
  5704.    --!    Ada Tracking Package Using Kalman Filter Methods
  5705.    --!    Contract No. N66001-85-C-0044 (31 December 1984)
  5706.    --!
  5707.    --! Prepared for:
  5708.    --!    Naval Ocean Systems Center (WIS JPMO)
  5709.    --!    271 Catalina Blvd., Building A-33
  5710.    --!    San Diego, CA 92152
  5711.    --!
  5712.    --! Prepared by:
  5713.    --!    Software Systems Engineering
  5714.    --!    Federal Systems Group
  5715.    --!
  5716.    --!    Sanders Associates, Inc.
  5717.    --!    95 Canal Street
  5718.    --!    Nashua, NH 03061
  5719.    --!
  5720.    --! Author:
  5721.    --!    Daryl R. Winters
  5722.    --!
  5723.    --!----------------------------------------------------------------
  5724.  
  5725.    Difference: constant Integer
  5726.                := Character'Pos ('a') - Character'Pos ('A');
  5727.  
  5728.    pragma Page;
  5729.    -------------------------------------------------------------------
  5730.  
  5731.    function Same_Character (A, B: in Character) return Boolean is
  5732.  
  5733.       --!-------------------------------------------------------------
  5734.       --!
  5735.       --! Name:
  5736.       --!    Same_Character
  5737.       --!
  5738.       --! Purpose:
  5739.       --!    This local function returns a boolean value which 
  5740.       --!    indicates whether the input characters are equal.
  5741.       --!
  5742.       --! Parameters:
  5743.       --!    A
  5744.       --!       is a character.
  5745.       --!
  5746.       --!    B
  5747.       --!       is a character.
  5748.       --!
  5749.       --! Exceptions:
  5750.       --!    Not applicable.
  5751.       --!
  5752.       --! Notes:
  5753.       --!    If the characters differ only in case, they are still
  5754.       --!    considered equal.
  5755.       --!
  5756.       --!-------------------------------------------------------------
  5757.  
  5758.       Folded_A,
  5759.       Folded_B: Integer;
  5760.  
  5761.    begin
  5762.       Folded_A := Character'Pos (A);
  5763.       Folded_B := Character'Pos (B);
  5764.  
  5765.       if A in 'a'..'z' then
  5766.          Folded_A := Folded_A - Difference;
  5767.       end if;
  5768.  
  5769.       if B in 'a'..'z' then
  5770.          Folded_B := Folded_B - Difference;
  5771.       end if;
  5772.  
  5773.       return Folded_A = Folded_B;
  5774.    end Same_Character;
  5775.  
  5776.    pragma Page;
  5777.    -------------------------------------------------------------------
  5778.  
  5779.    function First_Difference (A, B: in String) return Integer is
  5780.  
  5781.       --!-------------------------------------------------------------
  5782.       --!
  5783.       --! Name:
  5784.       --!    First_Difference
  5785.       --!
  5786.       --! Purpose:
  5787.       --!    This local function returns the first character position
  5788.       --!    in which the two strings are not equal.
  5789.       --!
  5790.       --! Parameters:
  5791.       --!    A
  5792.       --!       is a string.
  5793.       --!
  5794.       --!    B
  5795.       --!       is a string.
  5796.       --!
  5797.       --! Exceptions:
  5798.       --!    Not applicable.
  5799.       --!
  5800.       --! Notes:
  5801.       --!    If one or both of the strings are null, then
  5802.       --!    First_Difference returns a zero index. If the two
  5803.       --!    strings are equal throughout the length of the
  5804.       --!    smaller of the two, then First_Difference returns
  5805.       --!    one greater than the lenght of the shorter as the
  5806.       --!    index.
  5807.       --!
  5808.       --!-------------------------------------------------------------
  5809.  
  5810.       Last_Index: Integer;
  5811.  
  5812.    begin
  5813.       if A'Length <= B'Length then
  5814.          Last_Index := A'Length;
  5815.       else
  5816.          Last_Index := B'Length;
  5817.       end if;
  5818.  
  5819.       if Last_Index = 0 then
  5820.          return 0;
  5821.       end if;
  5822.  
  5823.       for I in 1 .. Last_Index loop
  5824.  
  5825.          if not Same_Character (A (I), B (I)) then
  5826.             return I;
  5827.          end if;
  5828.       end loop;
  5829.  
  5830.       return Last_Index + 1;
  5831.    end First_Difference;
  5832.  
  5833.    pragma Page;
  5834.    -------------------------------------------------------------------
  5835.  
  5836.    function Match_Substring
  5837.       (A, B:    in String;
  5838.        First_A,
  5839.        First_B: in Natural) return Boolean is
  5840.  
  5841.       --!-------------------------------------------------------------
  5842.       --!
  5843.       --! Name:
  5844.       --!    Match_Substring
  5845.       --!
  5846.       --! Purpose:
  5847.       --!    This local function returns a boolean value which
  5848.       --!    indicates whether the specified substrings of the
  5849.       --!    strings are equal.
  5850.       --!
  5851.       --! Parameters:
  5852.       --!    A
  5853.       --!       is a string.
  5854.       --!
  5855.       --!    B
  5856.       --!       is a string.
  5857.       --!
  5858.       --!    First_A
  5859.       --!       is the index position of the start of the substring
  5860.       --!       of A.
  5861.       --!
  5862.       --!    First_B
  5863.       --!       is the index position of the start of the substring 
  5864.       --!       of B.
  5865.       --!
  5866.       --! Exceptions:
  5867.       --!    Not applicable.
  5868.       --!
  5869.       --! Notes:
  5870.       --!    If the length of the substring of B is greater than
  5871.       --!    the length of the substring of A, then the substrings
  5872.       --!    can not match. Otherwise, it is determined whether the
  5873.       --!    substrings match throughout the length of the substring
  5874.       --!    of B.
  5875.       --!
  5876.       --!-------------------------------------------------------------
  5877.  
  5878.    begin
  5879.       if First_B > B'Length then
  5880.          return True;
  5881.       elsif (First_A > A'Length) or
  5882.             ((B'Last - First_B) > (A'Last - First_A)) then
  5883.          return False;
  5884.       end if;
  5885.  
  5886.       for I in 0 .. (B'Last - First_B) loop
  5887.          if not Same_Character
  5888.             (A (I+ First_A),
  5889.              B (I + First_B)) then return False;
  5890.          end if;
  5891.       end loop;
  5892.  
  5893.       return True;
  5894.    end Match_Substring;
  5895.  
  5896.    pragma Page;
  5897.    -------------------------------------------------------------------
  5898.  
  5899.    function Possibly_Correct
  5900.       (Word,
  5901.        Correct_Word: in String) return Boolean is
  5902.  
  5903.       --!-------------------------------------------------------------
  5904.       --!
  5905.       --! Name:
  5906.       --!    Possibly_Correct
  5907.       --!
  5908.       --! Purpose:
  5909.       --!    This function returns a boolean which indicates whether
  5910.       --!    the spelling of Word might intend the spelling of the
  5911.       --!    Correct_Word.
  5912.       --!
  5913.       --! Parameters:
  5914.       --!    Word
  5915.       --!       is a string.
  5916.       --!
  5917.       --!    Correct_Word
  5918.       --!       is a string which contains the "correct" spelling.
  5919.       --!
  5920.       --! Exceptions:
  5921.       --!    Not applicable.
  5922.       --!
  5923.       --! Notes:
  5924.       --!    Single missing letters, single incorrect letters, and
  5925.       --!    transposed characters are corrected for when determining
  5926.       --!    whether the spelling might be correct.
  5927.       --!
  5928.       --!-------------------------------------------------------------
  5929.  
  5930.       Index: Integer;
  5931.  
  5932.       A: String (1..Word'Length);
  5933.       B: String (1..Correct_Word'Length);
  5934.  
  5935.    begin
  5936.       if (A'Length = 0) or (B'Length = 0) then
  5937.          return False;
  5938.       end if;
  5939.  
  5940.       A := Word;
  5941.       B := Correct_Word;
  5942.  
  5943.       -- Can't match if word is more than one longer.
  5944.       if (A'Length - 1) > B'Length then
  5945.          return False;
  5946.       end if;
  5947.  
  5948.       -- Step 1: Find index of first different characters.
  5949.       Index := First_Difference (B, A);
  5950.  
  5951.       -- Assume wrong letter if difference is at end of word.
  5952.       if (Index = A'Length) and (A'Length > 2) then
  5953.          return True;
  5954.       end if;
  5955.  
  5956.       -- Step 2: Check for transposed characters and tail match.
  5957.       if (B'Last > Index) and (A'Last > Index) then
  5958.  
  5959.          if Same_Character (B (Index),     A (Index + 1)) and
  5960.             Same_Character (B (Index + 1), A (Index))     and
  5961.  
  5962.             Match_Substring (B, A, Index+2, Index+2) then
  5963.             return True;
  5964.          end if;
  5965.       end if;
  5966.  
  5967.       -- Step 3: Apply remaining tail substring matches.
  5968.       if Match_Substring (B, A, Index+1, Index) then
  5969.          return True;
  5970.       end if;
  5971.  
  5972.       -- Don't try other tests on two character strings.
  5973.       if A'Length = 2 then
  5974.          return False;
  5975.       end if;
  5976.  
  5977.       if Match_Substring (B, A, Index, Index+1) then
  5978.          return True;
  5979.       end if;
  5980.  
  5981.       if Match_Substring (B, A, Index+1, Index+1) then
  5982.          return True;
  5983.       end if;
  5984.  
  5985.       return False;
  5986.    end Possibly_Correct;
  5987.  
  5988. end Kalman_Check;
  5989. --::::::::::::::::::::::::::::
  5990. --KALMAN-TEXT-IO-SPEC.ADA
  5991. --::::::::::::::::::::::::::::
  5992.  
  5993. with Text_Io;
  5994. use Text_Io;
  5995.  
  5996. package Kalman_Text_Io is
  5997.  
  5998.    --!----------------------------------------------------------------
  5999.    --!
  6000.    --! Name:
  6001.    --!    Kalman_Text_Io
  6002.    --!
  6003.    --! Purpose:
  6004.    --!    This package provides support for the friendly I/O used
  6005.    --!    by the Ada Kalman Filter. Lines read in by a Get_Line
  6006.    --!    will be saved in Buffer for later reference.
  6007.    --!
  6008.    --! Interfaces:
  6009.    --!    Get_Line
  6010.    --!       is called to read a Buffer from File after displaying
  6011.    --!       the Prompt string to Current_Output.
  6012.    --!
  6013.    --!    Buffer
  6014.    --!       is the current line read by a Get_Line routine.
  6015.    --!
  6016.    --!    Length
  6017.    --!       is the Length of Buffer.
  6018.    --!
  6019.    --!    Index
  6020.    --!       is the current Index position of Buffer.
  6021.    --!
  6022.    --! Exceptions:
  6023.    --!    Not applicable.
  6024.    --!
  6025.    --! Notes:
  6026.    --!    A Buffer is not read if characters still remain from the
  6027.    --!    previous call to Get_Line.
  6028.    --!
  6029.    --! Contract:
  6030.    --!    Ada Tracking Package Using Kalman Filter Methods
  6031.    --!    Contract No. N66001-85-C-0044 (31 December 1984)
  6032.    --!
  6033.    --! Prepared for:
  6034.    --!    Naval Ocean Systems Center (WIS JPMO)
  6035.    --!    271 Catalina Blvd., Building A-33
  6036.    --!    San Diego, CA 92152
  6037.    --!
  6038.    --! Prepared by:
  6039.    --!    Software Systems Engineering
  6040.    --!    Federal Systems Group
  6041.    --!
  6042.    --!    Sanders Associates, Inc.
  6043.    --!    95 Canal Street
  6044.    --!    Nashua, NH 03061
  6045.    --!
  6046.    --! Author:
  6047.    --!    Daryl R. Winters
  6048.    --!
  6049.    --!----------------------------------------------------------------
  6050.  
  6051.    Index:  Natural := 0;    -- Current character position.
  6052.    Length: Natural := 0;    -- Current line length.
  6053.    Buffer: String (1..256); -- Current line.
  6054.  
  6055.    procedure Get_Line (File   : in File_Type;
  6056.                        Prompt : in String := "");
  6057.  
  6058.    procedure Get_Line (Prompt : in String := "");
  6059.  
  6060. end Kalman_Text_Io;
  6061. --::::::::::::::::::::::::::::
  6062. --KALMAN-TEXT-IO-BODY.ADA
  6063. --::::::::::::::::::::::::::::
  6064.  
  6065. package body Kalman_Text_Io is
  6066.  
  6067.    --!----------------------------------------------------------------
  6068.    --!
  6069.    --! Name:
  6070.    --!    Kalman_Text_Io
  6071.    --!
  6072.    --! Purpose:
  6073.    --!    This package body provides support for the friendly I/O used
  6074.    --!    by the Ada Kalman Filter. Lines read in by a Get_Line
  6075.    --!    will be saved in Buffer for later reference.
  6076.    --!
  6077.    --! Exceptions:
  6078.    --!    Not applicable.
  6079.    --!
  6080.    --! Notes:
  6081.    --!    A Buffer is not read if characters still remain from the
  6082.    --!    previous call to Get_Line.
  6083.    --!
  6084.    --! Contract:
  6085.    --!    Ada Tracking Package Using Kalman Filter Methods
  6086.    --!    Contract No. N66001-85-C-0044 (31 December 1984)
  6087.    --!
  6088.    --! Prepared for:
  6089.    --!    Naval Ocean Systems Center (WIS JPMO)
  6090.    --!    271 Catalina Blvd., Building A-33
  6091.    --!    San Diego, CA 92152
  6092.    --!
  6093.    --! Prepared by:
  6094.    --!    Software Systems Engineering
  6095.    --!    Federal Systems Group
  6096.    --!
  6097.    --!    Sanders Associates, Inc.
  6098.    --!    95 Canal Street
  6099.    --!    Nashua, NH 03061
  6100.    --!
  6101.    --! Author:
  6102.    --!    Daryl R. Winters
  6103.    --!
  6104.    --! Changes:
  6105.    --!    26-APR-1985
  6106.    --!       Added code to skip the remainder of the line when an
  6107.    --!       Ada comment line ("-- text") is found.
  6108.    --!
  6109.    --!----------------------------------------------------------------
  6110.  
  6111.    pragma Page;
  6112.    -------------------------------------------------------------------
  6113.  
  6114.    procedure Get_Line (File   : in File_Type;
  6115.                        Prompt : in String := "") is
  6116.  
  6117.       --!-------------------------------------------------------------
  6118.       --!
  6119.       --! Name:
  6120.       --!    Get_Line
  6121.       --!
  6122.       --! Purpose:
  6123.       --!    This procedure gets a line from the specified File
  6124.       --!    if the current Buffer is empty.
  6125.       --!
  6126.       --! Parameters:
  6127.       --!    File
  6128.       --!       is the specified input file.
  6129.       --! 
  6130.       --!   Prompt
  6131.       --!       is the prompt string.
  6132.       --!
  6133.       --! Exceptions:
  6134.       --!    Not applicable.
  6135.       --!
  6136.       --! Notes:
  6137.       --!    If the current Buffer is empty, then an attempt is
  6138.       --!    made to read a new buffer from the specified file.
  6139.       --!    A prompt is issued if the user has specified one.
  6140.       --!    Preceding blanks, trailing blanks, and comments
  6141.       --!    (any string beginning with "--" to the end-of-line)
  6142.       --!    are ignored.
  6143.       --!
  6144.       --!-------------------------------------------------------------
  6145.  
  6146.       Display_Prompt : Boolean := (Prompt /= "");
  6147.  
  6148.    begin
  6149.  
  6150.       loop
  6151.          if (Index <= 0) or (Index > Length) then
  6152.  
  6153.             if (Display_Prompt) then
  6154.                Put (Prompt);
  6155.             end if;
  6156.  
  6157.             Get_Line (File, Buffer, Length);
  6158.  
  6159.             if (Display_Prompt) then
  6160.                New_Line;
  6161.             end if;
  6162.  
  6163.             Index := Buffer'First;
  6164.  
  6165.             -- Skip trailing blanks.
  6166.             for I in reverse Index .. Length loop
  6167.  
  6168.                if (Buffer (I) /= ' ') then
  6169.                   Length := I;
  6170.                   exit;
  6171.                end if;
  6172.             end loop;
  6173.          end if;
  6174.  
  6175.          -- Skip preceding blanks.
  6176.          for I in Index .. Length loop
  6177.  
  6178.             if (Buffer (I) /= ' ') then
  6179.                Index := I;
  6180.                exit;
  6181.             end if;
  6182.          end loop;
  6183.  
  6184.          if (Index+1 <= Length) and then
  6185.             (Buffer (Index..Index+1) = "--") then
  6186.             Index := Length + 1; -- Skip comment.
  6187.          else
  6188.             exit; -- No comment line.
  6189.          end if;
  6190.       end loop;
  6191.  
  6192.    end Get_Line;
  6193.  
  6194.    pragma Page;
  6195.    -------------------------------------------------------------------
  6196.  
  6197.    procedure Get_Line (Prompt : in String := "") is
  6198.  
  6199.       --!-------------------------------------------------------------
  6200.       --!
  6201.       --! Name:
  6202.       --!    Get_Line
  6203.       --!
  6204.       --! Purpose:
  6205.       --!    This procedure gets a line from the current input
  6206.       --!    if the current Buffer is empty.
  6207.       --!
  6208.       --! Parameters:
  6209.       --!   Prompt
  6210.       --!       is the prompt string.
  6211.       --!
  6212.       --! Exceptions:
  6213.       --!    Not applicable.
  6214.       --!
  6215.       --! Notes:
  6216.       --!    If the current Buffer is empty, then an attempt is
  6217.       --!    made to read a new buffer from the current input.
  6218.       --!    A prompt is issued if the user has specified one.
  6219.       --!    Preceding blanks, trailing blanks, and comments
  6220.       --!    (any string beginning with "--" to the end-of-line)
  6221.       --!    are ignored.
  6222.       --!
  6223.       --!-------------------------------------------------------------
  6224.  
  6225.    begin
  6226.  
  6227.       Get_Line (Current_Input, Prompt);
  6228.  
  6229.    end Get_Line;
  6230.  
  6231. end Kalman_Text_Io;
  6232. --::::::::::::::::::::::::::::
  6233. --GENERIC-FIXED-IO-SPEC.ADA
  6234. --::::::::::::::::::::::::::::
  6235.  
  6236. with Text_Io;
  6237. use Text_Io;
  6238.  
  6239. generic
  6240.    type Num is delta <>;
  6241.  
  6242. package Generic_Fixed_Io is
  6243.  
  6244.    --!----------------------------------------------------------------
  6245.    --!
  6246.    --! Name:
  6247.    --!    Generic_Fixed_Io
  6248.    --!
  6249.    --! Purpose:
  6250.    --!    This generic package provides a friendly version of the
  6251.    --!    package Text_Io.Fixed_Io for the Ada Kalman Filter.
  6252.    --!
  6253.    --! Interfaces:
  6254.    --!    Same as Text_Io.Fixed_Io.
  6255.    --!
  6256.    --! Exceptions:
  6257.    --!    Same as Text_Io.Fixed_Io.
  6258.    --!
  6259.    --!
  6260.    --! Notes:
  6261.    --!    Friendly features include:
  6262.    --!       prompting the user for input,
  6263.    --!       converting integer input to type Num,
  6264.    --!       displaying error messages when invalid input is entered,
  6265.    --!       and indicating the range of correct input after an
  6266.    --!       error is encountered.
  6267.    --!
  6268.    --! Contract:
  6269.    --!    Ada Tracking Package Using Kalman Filter Methods
  6270.    --!    Contract No. N66001-85-C-0044 (31 December 1984)
  6271.    --!
  6272.    --! Prepared for:
  6273.    --!    Naval Ocean Systems Center (WIS JPMO)
  6274.    --!    271 Catalina Blvd., Building A-33
  6275.    --!    San Diego, CA 92152
  6276.    --!
  6277.    --! Prepared by:
  6278.    --!    Software Systems Engineering
  6279.    --!    Federal Systems Group
  6280.    --!
  6281.    --!    Sanders Associates, Inc.
  6282.    --!    95 Canal Street
  6283.    --!    Nashua, NH 03061
  6284.    --!
  6285.    --! Author:
  6286.    --!    Daryl R. Winters
  6287.    --!
  6288.    --!----------------------------------------------------------------
  6289.  
  6290.    Default_Fore : Field := Num'Fore;
  6291.    Default_Aft  : Field := Num'Aft;
  6292.    Default_Exp  : Field := 0;
  6293.  
  6294.    -------------------------------------------------------------------
  6295.  
  6296.    procedure Get (File   : in  File_Type;
  6297.                   Item   : out Num;
  6298.                   Width  : in  Field  := 0;
  6299.                   Prompt : in  String := "");
  6300.  
  6301.    procedure Get (Item   : out Num;
  6302.                   Width  : in  Field  := 0;
  6303.                   Prompt : in  String := "");
  6304.  
  6305.    -------------------------------------------------------------------
  6306.  
  6307.    procedure Put (File : in File_Type;
  6308.                   Item : in Num;
  6309.                   Fore : in Field := Default_Fore;
  6310.                   Aft  : in Field := Default_Aft;
  6311.                   Exp  : in Field := Default_Exp);
  6312.  
  6313.    procedure Put (Item : in Num;
  6314.                   Fore : in Field := Default_Fore;
  6315.                   Aft  : in Field := Default_Aft;
  6316.                   Exp  : in Field := Default_Exp);
  6317.  
  6318.    -------------------------------------------------------------------
  6319.  
  6320.    procedure Get (From : in  String;
  6321.                   Item : out Num;
  6322.                   Last : out Positive);
  6323.  
  6324.    procedure Put (To   : out String;
  6325.                   Item : in  Num;
  6326.                   Aft  : in  Field   := Default_Aft;
  6327.                   Exp  : in  Integer := Default_Exp);
  6328.  
  6329. end Generic_Fixed_Io;
  6330. --::::::::::::::::::::::::::::
  6331. --GENERIC-FIXED-IO-BODY.ADA
  6332. --::::::::::::::::::::::::::::
  6333.  
  6334. with Text_Io;
  6335. with Kalman_Text_Io;
  6336.  
  6337. use Text_Io;
  6338. use Kalman_Text_Io;
  6339.  
  6340. package body Generic_Fixed_Io is
  6341.  
  6342.    --!----------------------------------------------------------------
  6343.    --!
  6344.    --! Name:
  6345.    --!    Generic_Fixed_Io
  6346.    --!
  6347.    --! Purpose:
  6348.    --!    This generic package body provides a friendly version of the
  6349.    --!    package Text_Io.Fixed_Io for the Ada Kalman Filter.
  6350.    --!
  6351.    --!
  6352.    --! Notes:
  6353.    --!    Friendly features include:
  6354.    --!       prompting the user for input,
  6355.    --!       converting integer input to type Num,
  6356.    --!       displaying error messages when invalid input is entered,
  6357.    --!       and indicating the range of correct input after an
  6358.    --!       error is encountered.
  6359.    --!
  6360.    --! Contract:
  6361.    --!    Ada Tracking Package Using Kalman Filter Methods
  6362.    --!    Contract No. N66001-85-C-0044 (31 December 1984)
  6363.    --!
  6364.    --! Prepared for:
  6365.    --!    Naval Ocean Systems Center (WIS JPMO)
  6366.    --!    271 Catalina Blvd., Building A-33
  6367.    --!    San Diego, CA 92152
  6368.    --!
  6369.    --! Prepared by:
  6370.    --!    Software Systems Engineering
  6371.    --!    Federal Systems Group
  6372.    --!
  6373.    --!    Sanders Associates, Inc.
  6374.    --!    95 Canal Street
  6375.    --!    Nashua, NH 03061
  6376.    --!
  6377.    --! Author:
  6378.    --!    Daryl R. Winters
  6379.    --!
  6380.    --! Changes:
  6381.    --!    26-APR-1985
  6382.    --!       Added check for empty Index before accessing Line array
  6383.    --!       in Get procedure. This could have resulted in an index
  6384.    --!       out of bounds.
  6385.    --!
  6386.    --!----------------------------------------------------------------
  6387.  
  6388.    package Fixed_Io is
  6389.       new Text_Io.Fixed_Io (Num);
  6390.  
  6391.    package Integer_Io is
  6392.       new Text_Io.Integer_Io (Integer);
  6393.  
  6394.    pragma Page;
  6395.    -------------------------------------------------------------------
  6396.  
  6397.    procedure Get(File   : in  File_Type;
  6398.                  Item   : out Num;
  6399.                  Width  : in  Field  := 0;
  6400.                  Prompt : in  String := "") is
  6401.  
  6402.       --!-------------------------------------------------------------
  6403.       --!
  6404.       --! Name:
  6405.       --!    Get
  6406.       --!
  6407.       --! Purpose:
  6408.       --!    This procedure displays the Prompt to Current_Output
  6409.       --!    and then attempts to read a value of type Num from the
  6410.       --!    specified File. If an Integer value is read, it is
  6411.       --!    converted to Num. If an invalid value is read, an
  6412.       --!    error message is displayed to Current_Output, and
  6413.       --!    a new value is read from the specified File.
  6414.       --!
  6415.       --! Parameters:
  6416.       --!    File
  6417.       --!       is the file from which the Item will be read.
  6418.       --!
  6419.       --!    Item
  6420.       --!       returns the Num value as read from File.
  6421.       --!
  6422.       --!    Width
  6423.       --!       is the maximum field width for Item.
  6424.       --!
  6425.       --!    Prompt
  6426.       --!       is the prompt to be displayed to Current_Output.
  6427.       --!
  6428.       --! Exceptions:
  6429.       --!    Not applicable.
  6430.       --!
  6431.       --! Notes:
  6432.       --!    Not applicable.
  6433.       --!
  6434.       --!-------------------------------------------------------------
  6435.  
  6436.       Last:   Natural; -- Last character returned from Get.
  6437.       Field:  Natural; -- Field length (based on width).
  6438.       Number: Integer; -- Local integer value for Get.
  6439.  
  6440.    begin
  6441.  
  6442.       loop
  6443.          Get_Line (File, Prompt);
  6444.  
  6445.          if (Width = 0) then
  6446.             Field := Length;
  6447.          elsif (Index + Width - 1 > Length) then
  6448.             Field := Length;
  6449.          else
  6450.             Field := Index + Width - 1;
  6451.          end if;
  6452.  
  6453.          begin
  6454.             -- Check for Fixed number.
  6455.             if (Index >= Buffer'First) and then
  6456.                (Buffer (Index) = '.') then
  6457.                Fixed_Io.Get ("0" & Buffer (Index..Field), Item, Last);
  6458.             else
  6459.                Fixed_Io.Get (Buffer (Index..Field), Item, Last);
  6460.             end if;
  6461.  
  6462.             Index := Last + 1;
  6463.             return;
  6464.          exception
  6465.             when others =>
  6466.                begin
  6467.                   -- Check for integer number.
  6468.                   Integer_Io.Get (Buffer (Index..Field),
  6469.                                   Number, Last);
  6470.                   Item := Num (Number);
  6471.                   Index := Last + 1;
  6472.                   return;
  6473.                exception
  6474.                   when others =>
  6475.                      Last := Length;
  6476.  
  6477.                      -- Find next blank.
  6478.                      for I in Index + 1 .. Length loop
  6479.  
  6480.                         if (Buffer (I) = ' ') then
  6481.                            Last := I - 1;
  6482.                            exit;
  6483.                         end if;
  6484.                      end loop;
  6485.                end;
  6486.          end;
  6487.  
  6488.          if (Index > Length) then
  6489.             New_Line;
  6490.             Put ("%FIXED-E-EMPTY, ");
  6491.             Put ("A correct value ");
  6492.             Put ("is in the range:");
  6493.             New_Line;
  6494.          else
  6495.             New_Line;
  6496.             Put ("%FIXED-E-RANGE, ");
  6497.             Put ("The value """);
  6498.             Put (Buffer (Index..Last));
  6499.             Put (""" is not in the range:");
  6500.             New_Line;
  6501.          end if;
  6502.  
  6503.          Put ("   ");
  6504.          Put (Num'First, Fore => 1);
  6505.          Put ("  ..  ");
  6506.          Put (Num'Last, Fore => 1);
  6507.          New_Line;
  6508.  
  6509.          New_Line;
  6510.          Put ("%FIXED-E-RETRY, ");
  6511.          Put ("Please enter a ");
  6512.  
  6513.          if (Index <= Length) then
  6514.             Put ("correct ");
  6515.          end if;
  6516.  
  6517.          Put ("value.");
  6518.          New_Line;
  6519.  
  6520.          Index := Last + 1;
  6521.       end loop;
  6522.  
  6523.    end Get;
  6524.  
  6525.    pragma Page;
  6526.    -------------------------------------------------------------------
  6527.  
  6528.    procedure Get(Item   : out Num;
  6529.                  Width  : in  Field  := 0;
  6530.                  Prompt : in  String := "") is
  6531.  
  6532.       --!-------------------------------------------------------------
  6533.       --!
  6534.       --! Name:
  6535.       --!    Get
  6536.       --!
  6537.       --! Purpose:
  6538.       --!    This procedure displays the Prompt to Current_Output
  6539.       --!    and then attempts to read a value of type Num from 
  6540.       --!    Current_Input. If an Integer value is read, it is
  6541.       --!    converted to Num. If an invalid value is read, an
  6542.       --!    error message is displayed to Current_Output, and
  6543.       --!    a new value is read from the Current_Input.
  6544.       --!
  6545.       --! Parameters:
  6546.       --!    Item
  6547.       --!       returns the Num value as read from Current_Input.
  6548.       --!
  6549.       --!    Width
  6550.       --!       is the maximum field width for Item.
  6551.       --!
  6552.       --!    Prompt
  6553.       --!       is the prompt to be displayed to Current_Output.
  6554.       --!
  6555.       --! Exceptions:
  6556.       --!    Not applicable.
  6557.       --!
  6558.       --! Notes:
  6559.       --!    Not applicable.
  6560.       --!
  6561.       --!-------------------------------------------------------------
  6562.  
  6563.    begin
  6564.  
  6565.       Get (Current_Input, Item, Width, Prompt);
  6566.  
  6567.    end Get;
  6568.  
  6569.    pragma Page;
  6570.    -------------------------------------------------------------------
  6571.  
  6572.    procedure Put(File : in File_Type;
  6573.                  Item : in Num;
  6574.                  Fore : in Field := Default_Fore;
  6575.                  Aft  : in Field := Default_Aft;
  6576.                  Exp  : in Field := Default_Exp) is
  6577.  
  6578.       --!-------------------------------------------------------------
  6579.       --!
  6580.       --! Name:
  6581.       --!    Put
  6582.       --!
  6583.       --! Purpose:
  6584.       --!    This procedure writes an Item of type Num to the 
  6585.       --!    specified File using the field definitions.
  6586.       --!
  6587.       --! Parameters:
  6588.       --!    Same as Fixed_Io.Put (File, Item, Fore, Aft, Exp).
  6589.       --!
  6590.       --! Exceptions:
  6591.       --!    Same as Fixed_Io.Put (File, Item, Fore, Aft, Exp).
  6592.       --!
  6593.       --! Notes:
  6594.       --!    Not applicable.
  6595.       --!
  6596.       --!-------------------------------------------------------------
  6597.  
  6598.    begin
  6599.  
  6600.       Fixed_Io.Put (File, Item, Fore, Aft, Exp);
  6601.  
  6602.    end Put;
  6603.  
  6604.    pragma Page;
  6605.    -------------------------------------------------------------------
  6606.  
  6607.    procedure Put(Item : in Num;
  6608.                  Fore : in Field := Default_Fore;
  6609.                  Aft  : in Field := Default_Aft;
  6610.                  Exp  : in Field := Default_Exp) is
  6611.  
  6612.       --!-------------------------------------------------------------
  6613.       --!
  6614.       --! Name:
  6615.       --!    Put
  6616.       --!
  6617.       --! Purpose:
  6618.       --!    This procedure writes an Item of type Num to 
  6619.       --!    standard output using the field definitions.
  6620.       --!
  6621.       --! Parameters:
  6622.       --!    Same as Fixed_Io.Put (Item, Fore, Aft, Exp).
  6623.       --!
  6624.       --! Exceptions:
  6625.       --!    Same as Fixed_Io.Put (Item, Fore, Aft, Exp).
  6626.       --!
  6627.       --! Notes:
  6628.       --!    Not applicable.
  6629.       --!
  6630.       --!-------------------------------------------------------------
  6631.  
  6632.    begin
  6633.  
  6634.       Fixed_Io.Put (Item, Fore, Aft, Exp);
  6635.  
  6636.    end Put;
  6637.  
  6638.    pragma Page;
  6639.    -------------------------------------------------------------------
  6640.  
  6641.    procedure Get (From : in  String;
  6642.                   Item : out Num;
  6643.                   Last : out Positive) is
  6644.  
  6645.       --!-------------------------------------------------------------
  6646.       --!
  6647.       --! Name:
  6648.       --!    Get
  6649.       --!
  6650.       --! Purpose:
  6651.       --!    This procedure attempts to read an Item of type Num from
  6652.       --!    the String From.
  6653.       --!
  6654.       --! Parameters:
  6655.       --!    Same as Fixed_Io.Get (From, Item , Last).
  6656.       --!
  6657.       --! Exceptions:
  6658.       --!    Same as Fixed_Io.Get (From, Item , Last).
  6659.       --!
  6660.       --! Notes:
  6661.       --!    Not applicable.
  6662.       --!
  6663.       --!-------------------------------------------------------------
  6664.  
  6665.    begin
  6666.  
  6667.       Fixed_Io.Get (From, Item, Last);
  6668.  
  6669.    end Get;
  6670.  
  6671.    pragma Page;
  6672.    -------------------------------------------------------------------
  6673.  
  6674.    procedure Put (To   : out String;
  6675.                   Item : in  Num;
  6676.                   Aft  : in  Field   := Default_Aft;
  6677.                   Exp  : in  Integer := Default_Exp) is
  6678.  
  6679.       --!-------------------------------------------------------------
  6680.       --!
  6681.       --! Name:
  6682.       --!    Put
  6683.       --!
  6684.       --! Purpose:
  6685.       --!    This procedure writes an Item of type Num to the
  6686.       --!    String To.
  6687.       --!
  6688.       --! Parameters:
  6689.       --!    Same as Fixed_Io.Put (To, Item, Aft, Exp).
  6690.       --!
  6691.       --! Exceptions:
  6692.       --!    Same as Fixed_Io.Put (To, Item, Aft, Exp).
  6693.       --!
  6694.       --! Notes:
  6695.       --!    Not applicable.
  6696.       --!
  6697.       --!-------------------------------------------------------------
  6698.  
  6699.    begin
  6700.  
  6701.       Fixed_Io.Put (To, Item, Aft, Exp);
  6702.  
  6703.    end Put;
  6704.  
  6705. end Generic_Fixed_Io;
  6706. --::::::::::::::::::::::::::::
  6707. --GENERIC-INTEGER-IO-SPEC.ADA
  6708. --::::::::::::::::::::::::::::
  6709.  
  6710. with Text_Io;
  6711. use Text_Io;
  6712.  
  6713. generic
  6714.    type Num is range <>;
  6715.  
  6716. package Generic_Integer_Io is
  6717.  
  6718.    --!----------------------------------------------------------------
  6719.    --!
  6720.    --! Name:
  6721.    --!    Generic_Integer_Io
  6722.    --!
  6723.    --! Purpose:
  6724.    --!    This generic package provides a friendly version of the
  6725.    --!    package Text_Io.Integer_Io for the Ada Kalman Filter.
  6726.    --!
  6727.    --! Interfaces:
  6728.    --!    Same as Text_Io.Integer_Io.
  6729.    --!
  6730.    --! Exceptions:
  6731.    --!    Same as Text_Io.Integer_Io.
  6732.    --!
  6733.    --! Notes:
  6734.    --!    Friendly features include:
  6735.    --!       prompting the user for input,
  6736.    --!       converting float input to type Num,
  6737.    --!       displaying error messages when invalid input is entered,
  6738.    --!       and indicating the range of correct input after an
  6739.    --!       error is encountered.
  6740.    --!
  6741.    --! Contract:
  6742.    --!    Ada Tracking Package Using Kalman Filter Methods
  6743.    --!    Contract No. N66001-85-C-0044 (31 December 1984)
  6744.    --!
  6745.    --! Prepared for:
  6746.    --!    Naval Ocean Systems Center (WIS JPMO)
  6747.    --!    271 Catalina Blvd., Building A-33
  6748.    --!    San Diego, CA 92152
  6749.    --!
  6750.    --! Prepared by:
  6751.    --!    Software Systems Engineering
  6752.    --!    Federal Systems Group
  6753.    --!
  6754.    --!    Sanders Associates, Inc.
  6755.    --!    95 Canal Street
  6756.    --!    Nashua, NH 03061
  6757.    --!
  6758.    --! Author:
  6759.    --!    Daryl R. Winters
  6760.    --!
  6761.    --!----------------------------------------------------------------
  6762.  
  6763.    Default_Width : Field := Num'Width;
  6764.    Default_Base  : Field := 10;
  6765.  
  6766.    -------------------------------------------------------------------
  6767.  
  6768.    procedure Get (File   : in  File_Type;
  6769.                   Item   : out Num;
  6770.                   Width  : in  Field  := 0;
  6771.                   Prompt : in  String := "");
  6772.  
  6773.    procedure Get (Item   : out Num;
  6774.                   Width  : in  Field  := 0;
  6775.                   Prompt : in  String := "");
  6776.  
  6777.    -------------------------------------------------------------------
  6778.  
  6779.    procedure Put (File  : in File_Type;
  6780.                   Item  : in Num;
  6781.                   Width : in Field := Default_Width;
  6782.                   Base  : in Field := Default_Base);
  6783.  
  6784.    procedure Put (Item  : in Num;
  6785.                   Width : in Field := Default_Width;
  6786.                   Base  : in Field := Default_Base);
  6787.  
  6788.    -------------------------------------------------------------------
  6789.  
  6790.    procedure Get (From : in  String;
  6791.                   Item : out Num;
  6792.                   Last : out Positive);
  6793.  
  6794.    procedure Put (To   : out String;
  6795.                   Item : in  Num;
  6796.                   Base : in  Field   := Default_Base);
  6797.  
  6798. end Generic_Integer_Io;
  6799. --::::::::::::::::::::::::::::
  6800. --GENERIC-INTEGER-IO-BODY.ADA
  6801. --::::::::::::::::::::::::::::
  6802.  
  6803. with Text_Io;
  6804. with Kalman_Text_Io;
  6805.  
  6806. use Text_Io;
  6807. use Kalman_Text_Io;
  6808.  
  6809. package body Generic_Integer_Io is
  6810.  
  6811.    --!----------------------------------------------------------------
  6812.    --!
  6813.    --! Name:
  6814.    --!    Generic_Integer_Io
  6815.    --!
  6816.    --! Purpose:
  6817.    --!    This generic package body provides a friendly version of the
  6818.    --!    package Text_Io.Float_Io for the Ada Kalman Filter.
  6819.    --!
  6820.    --! Notes:
  6821.    --!    Friendly features include:
  6822.    --!       prompting the user for input,
  6823.    --!       converting float input to type Num,
  6824.    --!       displaying error messages when invalid input is entered,
  6825.    --!       and indicating the range of correct input after an
  6826.    --!       error is encountered.
  6827.    --!
  6828.    --! Contract:
  6829.    --!    Ada Tracking Package Using Kalman Filter Methods
  6830.    --!    Contract No. N66001-85-C-0044 (31 December 1984)
  6831.    --!
  6832.    --! Prepared for:
  6833.    --!    Naval Ocean Systems Center (WIS JPMO)
  6834.    --!    271 Catalina Blvd., Building A-33
  6835.    --!    San Diego, CA 92152
  6836.    --!
  6837.    --! Prepared by:
  6838.    --!    Software Systems Engineering
  6839.    --!    Federal Systems Group
  6840.    --!
  6841.    --!    Sanders Associates, Inc.
  6842.    --!    95 Canal Street
  6843.    --!    Nashua, NH 03061
  6844.    --!
  6845.    --! Author:
  6846.    --!    Daryl R. Winters
  6847.    --!
  6848.    --! Changes:
  6849.    --!    26-APR-1985
  6850.    --!       Added check for empty Index before accessing Line array
  6851.    --!       in Get procedure. This could have resulted in an index
  6852.    --!       out of bounds.
  6853.    --!
  6854.    --!----------------------------------------------------------------
  6855.  
  6856.    package Integer_Io is
  6857.       new Text_Io.Integer_Io (Num);
  6858.  
  6859.    package Float_Io is
  6860.       new Text_Io.Float_Io (Float);
  6861.  
  6862.    pragma Page;
  6863.    -------------------------------------------------------------------
  6864.  
  6865.    procedure Get(File   : in  File_Type;
  6866.                  Item   : out Num;
  6867.                  Width  : in  Field  := 0;
  6868.                  Prompt : in  String := "") is
  6869.  
  6870.       --!-------------------------------------------------------------
  6871.       --!
  6872.       --! Name:
  6873.       --!    Get
  6874.       --!
  6875.       --! Purpose:
  6876.       --!    This procedure displays the Prompt to Current_Output
  6877.       --!    and then attempts to read a value of type Num from the
  6878.       --!    specified File. If an Integer value is read, it is
  6879.       --!    converted to Num. If an invalid value is read, an
  6880.       --!    error message is displayed to Current_Output, and
  6881.       --!    a new value is read from the specified File.
  6882.       --!
  6883.       --! Parameters:
  6884.       --!    File
  6885.       --!       is the file from which the Item will be read.
  6886.       --!
  6887.       --!    Item
  6888.       --!       returns the Num value as read from File.
  6889.       --!
  6890.       --!    Width
  6891.       --!       is the maximum field width for Item.
  6892.       --!
  6893.       --!    Prompt
  6894.       --!       is the prompt to be displayed to Current_Output.
  6895.       --!
  6896.       --! Exceptions:
  6897.       --!    Not applicable.
  6898.       --!
  6899.       --! Notes:
  6900.       --!    Not applicable.
  6901.       --!
  6902.       --!-------------------------------------------------------------
  6903.  
  6904.       Last:   Natural; -- Last character returned from Get.
  6905.       Field:  Natural; -- Field length (based on width).
  6906.       Number: Float;   -- Local float value for Get.
  6907.  
  6908.    begin
  6909.  
  6910.       loop
  6911.          Get_Line (File, Prompt);
  6912.  
  6913.          if (Width = 0) then
  6914.             Field := Length;
  6915.          elsif (Index + Width - 1 > Length) then
  6916.             Field := Length;
  6917.          else
  6918.             Field := Index + Width - 1;
  6919.          end if;
  6920.  
  6921.          begin
  6922.             -- Check for float number.
  6923.             if (Index >= Buffer'First) and then
  6924.                (Buffer (Index) = '.') then
  6925.                Float_Io.Get ("0" & Buffer (Index..Field),
  6926.                              Number, Last);
  6927.             else
  6928.                Float_Io.Get (Buffer (Index..Field), Number, Last);
  6929.             end if;
  6930.  
  6931.             Item := Num (Number);
  6932.             Index := Last + 1;
  6933.             return;
  6934.          exception
  6935.             when others =>
  6936.                begin
  6937.                   -- Check for integer number.
  6938.                   Integer_Io.Get (Buffer (Index..Field),
  6939.                                   Item, Last);
  6940.                   Index := Last + 1;
  6941.                   return;
  6942.                exception
  6943.                   when others =>
  6944.                      Last := Length;
  6945.  
  6946.                      -- Find next blank.
  6947.                      for I in Index + 1 .. Length loop
  6948.  
  6949.                         if (Buffer (I) = ' ') then
  6950.                            Last := I - 1;
  6951.                            exit;
  6952.                         end if;
  6953.                      end loop;
  6954.                end;
  6955.          end;
  6956.  
  6957.          if (Index > Length) then
  6958.             New_Line;
  6959.             Put ("%INTEGER-E-EMPTY, ");
  6960.             Put ("A correct value ");
  6961.             Put ("is in the range:");
  6962.             New_Line;
  6963.          else
  6964.             New_Line;
  6965.             Put ("%INTEGER-E-RANGE, ");
  6966.             Put ("The value """);
  6967.             Put (Buffer (Index..Last));
  6968.             Put (""" is not in the range:");
  6969.             New_Line;
  6970.          end if;
  6971.  
  6972.          Put ("   ");
  6973.          Put (Num'First, Width => 1);
  6974.          Put ("  ..  ");
  6975.          Put (Num'Last, Width => 1);
  6976.          New_Line;
  6977.  
  6978.          New_Line;
  6979.          Put ("%INTEGER-E-RETRY, ");
  6980.          Put ("Please enter a ");
  6981.  
  6982.          if (Index <= Length) then
  6983.             Put ("correct ");
  6984.          end if;
  6985.  
  6986.          Put ("value.");
  6987.          New_Line;
  6988.  
  6989.          Index := Last + 1;
  6990.       end loop;
  6991.  
  6992.    end Get;
  6993.  
  6994.    pragma Page;
  6995.    -------------------------------------------------------------------
  6996.  
  6997.    procedure Get(Item   : out Num;
  6998.                  Width  : in  Field  := 0;
  6999.                  Prompt : in  String := "") is
  7000.  
  7001.       --!-------------------------------------------------------------
  7002.       --!
  7003.       --! Name:
  7004.       --!    Get
  7005.       --!
  7006.       --! Purpose:
  7007.       --!    This procedure displays the Prompt to Current_Output
  7008.       --!    and then attempts to read a value of type Num from 
  7009.       --!    Current_Input. If an Integer value is read, it is
  7010.       --!    converted to Num. If an invalid value is read, an
  7011.       --!    error message is displayed to Current_Output, and
  7012.       --!    a new value is read from the Current_Input.
  7013.       --!
  7014.       --! Parameters:
  7015.       --!    Item
  7016.       --!       returns the Num value as read from Current_Input.
  7017.       --!
  7018.       --!    Width
  7019.       --!       is the maximum field width for Item.
  7020.       --!
  7021.       --!    Prompt
  7022.       --!       is the prompt to be displayed to Current_Output.
  7023.       --!
  7024.       --! Exceptions:
  7025.       --!    Not applicable.
  7026.       --!
  7027.       --! Notes:
  7028.       --!    Not applicable.
  7029.       --!
  7030.       --!-------------------------------------------------------------
  7031.  
  7032.    begin
  7033.  
  7034.       Get (Current_Input, Item, Width, Prompt);
  7035.  
  7036.    end Get;
  7037.  
  7038.    pragma Page;
  7039.    -------------------------------------------------------------------
  7040.  
  7041.    procedure Put(File  : in File_Type;
  7042.                  Item  : in Num;
  7043.                  Width : in Field := Default_Width;
  7044.                  Base  : in Field := Default_Base) is
  7045.  
  7046.       --!-------------------------------------------------------------
  7047.       --!
  7048.       --! Name:
  7049.       --!    Put
  7050.       --!
  7051.       --! Purpose:
  7052.       --!    This procedure writes an Item of type Num to the
  7053.       --!    specified File using the field definitions.
  7054.       --!
  7055.       --! Parameters:
  7056.       --!    Same as Integer_Io.Put (File, Item, Width, Base).
  7057.       --!
  7058.       --! Exceptions:
  7059.       --!    Same as Integer_Io.Put (File, Item, Width, Base).
  7060.       --!
  7061.       --! Notes:
  7062.       --!    Not applicable.
  7063.       --!
  7064.       --!-------------------------------------------------------------
  7065.  
  7066.    begin
  7067.  
  7068.       Integer_Io.Put (File, Item, Width, Base);
  7069.  
  7070.    end Put;
  7071.  
  7072.    pragma Page;
  7073.    -------------------------------------------------------------------
  7074.  
  7075.    procedure Put(Item  : in Num;
  7076.                  Width : in Field := Default_Width;
  7077.                  Base  : in Field := Default_Base) is
  7078.  
  7079.       --!-------------------------------------------------------------
  7080.       --!
  7081.       --! Name:
  7082.       --!    Put
  7083.       --!
  7084.       --! Purpose:
  7085.       --!    This procedure writes an Item of type Num to 
  7086.       --!    standard output using the field definitions.
  7087.       --!
  7088.       --! Parameters:
  7089.       --!    Same as Integer_Io.Put (Item, Width, Base).
  7090.       --!
  7091.       --! Exceptions:
  7092.       --!    Same as Integer_Io.Put (Item, Width, Base).
  7093.       --!
  7094.       --! Notes:
  7095.       --!    Not applicable.
  7096.       --!
  7097.       --!-------------------------------------------------------------
  7098.  
  7099.    begin
  7100.  
  7101.       Integer_Io.Put (Item, Width, Base);
  7102.  
  7103.    end Put;
  7104.  
  7105.    pragma Page;
  7106.    -------------------------------------------------------------------
  7107.  
  7108.    procedure Get (From : in  String;
  7109.                   Item : out Num;
  7110.                   Last : out Positive) is
  7111.  
  7112.       --!-------------------------------------------------------------
  7113.       --!
  7114.       --! Name:
  7115.       --!    Get
  7116.       --!
  7117.       --! Purpose:
  7118.       --!    This procedure attempts to read an Item of type Num
  7119.       --!    from the String From.
  7120.       --!
  7121.       --! Parameters:
  7122.       --!    Same as Integer_Io.Get (From, Item, Last).
  7123.       --!
  7124.       --! Exceptions:
  7125.       --!    Same as Integer_Io.Get (From, Item, Last).
  7126.       --!
  7127.       --! Notes:
  7128.       --!    Not aplicable.
  7129.       --!
  7130.       --!-------------------------------------------------------------
  7131.  
  7132.    begin
  7133.  
  7134.       Integer_Io.Get (From, Item, Last);
  7135.  
  7136.    end Get;
  7137.  
  7138.    pragma Page;
  7139.    -------------------------------------------------------------------
  7140.  
  7141.    procedure Put (To   : out String;
  7142.                   Item : in  Num;
  7143.                   Base : in Field := Default_Base) is
  7144.  
  7145.       --!-------------------------------------------------------------
  7146.       --!
  7147.       --! Name:
  7148.       --!    Put
  7149.       --!
  7150.       --! Purpose:
  7151.       --!    This procedure attempts to write an Item of type Num
  7152.       --!    to the String To.
  7153.       --!
  7154.       --! Parameters:
  7155.       --!    Same as Integer_Io.Put (To, Item, Base).
  7156.       --!
  7157.       --! Exceptions:
  7158.       --!    Same as Integer_Io.Put (To, Item, Base).
  7159.       --!
  7160.       --! Notes:
  7161.       --!    Not applicable.
  7162.       --!
  7163.       --!-------------------------------------------------------------
  7164.  
  7165.    begin
  7166.  
  7167.       Integer_Io.Put (To, Item, Base);
  7168.  
  7169.    end Put;
  7170.  
  7171. end Generic_Integer_Io;
  7172. --::::::::::::::::::::::::::::
  7173. --GENERIC-FLOAT-IO-SPEC.ADA
  7174. --::::::::::::::::::::::::::::
  7175.  
  7176. with Text_Io;
  7177. use Text_Io;
  7178.  
  7179. generic
  7180.    type Num is digits <>;
  7181.  
  7182. package Generic_Float_Io is
  7183.  
  7184.    --!----------------------------------------------------------------
  7185.    --!
  7186.    --! Name:
  7187.    --!    Generic_Float_Io
  7188.    --!
  7189.    --! Purpose:
  7190.    --!    This generic package provides a friendly version of the
  7191.    --!    package Text_Io.Float_Io for the Ada Kalman Filter.
  7192.    --!
  7193.    --! Interfaces:
  7194.    --!    Same as Text_Io.Float_Io.
  7195.    --!
  7196.    --! Exceptions:
  7197.    --!    Same as Text_Io.Float_Io.
  7198.    --!
  7199.    --!
  7200.    --! Notes:
  7201.    --!    Friendly features include:
  7202.    --!       prompting the user for input,
  7203.    --!       converting integer input to type Num,
  7204.    --!       displaying error messages when invalid input is entered,
  7205.    --!       and indicating the range of correct input after an
  7206.    --!       error is encountered.
  7207.    --!
  7208.    --! Contract:
  7209.    --!    Ada Tracking Package Using Kalman Filter Methods
  7210.    --!    Contract No. N66001-85-C-0044 (31 December 1984)
  7211.    --!
  7212.    --! Prepared for:
  7213.    --!    Naval Ocean Systems Center (WIS JPMO)
  7214.    --!    271 Catalina Blvd., Building A-33
  7215.    --!    San Diego, CA 92152
  7216.    --!
  7217.    --! Prepared by:
  7218.    --!    Software Systems Engineering
  7219.    --!    Federal Systems Group
  7220.    --!
  7221.    --!    Sanders Associates, Inc.
  7222.    --!    95 Canal Street
  7223.    --!    Nashua, NH 03061
  7224.    --!
  7225.    --! Author:
  7226.    --!    Daryl R. Winters
  7227.    --!
  7228.    --!----------------------------------------------------------------
  7229.  
  7230.    Default_Fore : Field := 2;
  7231.    Default_Aft  : Field := Num'digits-1;
  7232.    Default_Exp  : Field := 3;
  7233.  
  7234.    -------------------------------------------------------------------
  7235.  
  7236.    procedure Get (File   : in  File_Type;
  7237.                   Item   : out Num;
  7238.                   Width  : in  Field  := 0;
  7239.                   Prompt : in  String := "");
  7240.  
  7241.    procedure Get (Item   : out Num;
  7242.                   Width  : in  Field  := 0;
  7243.                   Prompt : in  String := "");
  7244.  
  7245.    -------------------------------------------------------------------
  7246.  
  7247.    procedure Put (File : in File_Type;
  7248.                   Item : in Num;
  7249.                   Fore : in Field := Default_Fore;
  7250.                   Aft  : in Field := Default_Aft;
  7251.                   Exp  : in Field := Default_Exp);
  7252.  
  7253.    procedure Put (Item : in Num;
  7254.                   Fore : in Field := Default_Fore;
  7255.                   Aft  : in Field := Default_Aft;
  7256.                   Exp  : in Field := Default_Exp);
  7257.  
  7258.    -------------------------------------------------------------------
  7259.  
  7260.    procedure Get (From : in  String;
  7261.                   Item : out Num;
  7262.                   Last : out Positive);
  7263.  
  7264.    procedure Put (To   : out String;
  7265.                   Item : in  Num;
  7266.                   Aft  : in  Field   := Default_Aft;
  7267.                   Exp  : in  Integer := Default_Exp);
  7268.  
  7269. end Generic_Float_Io;
  7270. --::::::::::::::::::::::::::::
  7271. --GENERIC-FLOAT-IO-BODY.ADA
  7272. --::::::::::::::::::::::::::::
  7273.  
  7274. with Text_Io;
  7275. with Kalman_Text_Io;
  7276.  
  7277. use Text_Io;
  7278. use Kalman_Text_Io;
  7279.  
  7280. package body Generic_Float_Io is
  7281.  
  7282.    --!----------------------------------------------------------------
  7283.    --!
  7284.    --! Name:
  7285.    --!    Generic_Float_Io
  7286.    --!
  7287.    --! Purpose:
  7288.    --!    This generic package body provides a friendly version of the
  7289.    --!    package Text_Io.Float_Io for the Ada Kalman Filter.
  7290.    --!
  7291.    --! Notes:
  7292.    --!    Friendly features include:
  7293.    --!       prompting the user for input,
  7294.    --!       converting integer input to type Num,
  7295.    --!       displaying error messages when invalid input is entered,
  7296.    --!       and indicating the range of correct input after an
  7297.    --!       error is encountered.
  7298.    --!
  7299.    --! Contract:
  7300.    --!    Ada Tracking Package Using Kalman Filter Methods
  7301.    --!    Contract No. N66001-85-C-0044 (31 December 1984)
  7302.    --!
  7303.    --! Prepared for:
  7304.    --!    Naval Ocean Systems Center (WIS JPMO)
  7305.    --!    271 Catalina Blvd., Building A-33
  7306.    --!    San Diego, CA 92152
  7307.    --!
  7308.    --! Prepared by:
  7309.    --!    Software Systems Engineering
  7310.    --!    Federal Systems Group
  7311.    --!
  7312.    --!    Sanders Associates, Inc.
  7313.    --!    95 Canal Street
  7314.    --!    Nashua, NH 03061
  7315.    --!
  7316.    --! Author:
  7317.    --!    Daryl R. Winters
  7318.    --!
  7319.    --! Changes:
  7320.    --!    26-APR-1985
  7321.    --!       Added check for empty Index before accessing Line array
  7322.    --!       in Get procedure. This could have resulted in an index
  7323.    --!       out of bounds.
  7324.    --!
  7325.    --!----------------------------------------------------------------
  7326.  
  7327.    package Float_Io is
  7328.       new Text_Io.Float_Io (Num);
  7329.  
  7330.    package Integer_Io is
  7331.       new Text_Io.Integer_Io (Integer);
  7332.  
  7333.    pragma Page;
  7334.    -------------------------------------------------------------------
  7335.  
  7336.    procedure Get(File   : in  File_Type;
  7337.                  Item   : out Num;
  7338.                  Width  : in  Field  := 0;
  7339.                  Prompt : in  String := "") is
  7340.  
  7341.       --!-------------------------------------------------------------
  7342.       --!
  7343.       --! Name:
  7344.       --!    Get
  7345.       --!
  7346.       --! Purpose:
  7347.       --!    This procedure displays the Prompt to Current_Output
  7348.       --!    and then attempts to read a value of type Num from the
  7349.       --!    specified File. If an Integer value is read, it is
  7350.       --!    converted to Num. If an invalid value is read, an
  7351.       --!    error message is displayed to Current_Output, and
  7352.       --!    a new value is read from the specified File.
  7353.       --!
  7354.       --! Parameters:
  7355.       --!    File
  7356.       --!       is the file from which the Item will be read.
  7357.       --!
  7358.       --!    Item
  7359.       --!       returns the Num value as read from File.
  7360.       --!
  7361.       --!    Width
  7362.       --!       is the maximum field width for Item.
  7363.       --!
  7364.       --!    Prompt
  7365.       --!       is the prompt to be displayed to Current_Output.
  7366.       --!
  7367.       --! Exceptions:
  7368.       --!    Not applicable.
  7369.       --!
  7370.       --! Notes:
  7371.       --!    Not applicable.
  7372.       --!
  7373.       --!-------------------------------------------------------------
  7374.  
  7375.       Last:   Natural; -- Last character returned from Get.
  7376.       Field:  Natural; -- Field length (based on width).
  7377.       Number: Integer; -- Local integer value for Get.
  7378.  
  7379.    begin
  7380.  
  7381.       loop
  7382.          Get_Line (File, Prompt);
  7383.  
  7384.          if (Width = 0) then
  7385.             Field := Length;
  7386.          elsif (Index + Width - 1 > Length) then
  7387.             Field := Length;
  7388.          else
  7389.             Field := Index + Width - 1;
  7390.          end if;
  7391.  
  7392.          begin
  7393.             -- Check for float number.
  7394.             if (Index >= Buffer'First) and then
  7395.                (Buffer (Index) = '.') then
  7396.                Float_Io.Get ("0" & Buffer (Index..Field), Item, Last);
  7397.             else
  7398.                Float_Io.Get (Buffer (Index..Field), Item, Last);
  7399.             end if;
  7400.  
  7401.             Index := Last + 1;
  7402.             return;
  7403.          exception
  7404.             when others =>
  7405.                begin
  7406.                   -- Check for integer number.
  7407.                   Integer_Io.Get (Buffer (Index..Field),
  7408.                                   Number, Last);
  7409.                   Item := Num (Number);
  7410.                   Index := Last + 1;
  7411.                   return;
  7412.                exception
  7413.                   when others =>
  7414.                      Last := Length;
  7415.  
  7416.                      -- Find next blank.
  7417.                      for I in Index + 1 .. Length loop
  7418.  
  7419.                         if (Buffer (I) = ' ') then
  7420.                            Last := I - 1;
  7421.                            exit;
  7422.                         end if;
  7423.                      end loop;
  7424.                end;
  7425.          end;
  7426.  
  7427.          if (Index > Length) then
  7428.             New_Line;
  7429.             Put ("%FLOAT-E-EMPTY, ");
  7430.             Put ("A correct value ");
  7431.             Put ("is in the range:");
  7432.             New_Line;
  7433.          else
  7434.             New_Line;
  7435.             Put ("%FLOAT-E-RANGE, ");
  7436.             Put ("The value """);
  7437.             Put (Buffer (Index..Last));
  7438.             Put (""" is not in the range:");
  7439.             New_Line;
  7440.          end if;
  7441.  
  7442.          Put ("   ");
  7443.          Put (Num'First, Fore => 1);
  7444.          Put ("  ..  ");
  7445.          Put (Num'Last, Fore => 1);
  7446.          New_Line;
  7447.  
  7448.          New_Line;
  7449.          Put ("%FLOAT-E-RETRY, ");
  7450.          Put ("Please enter a ");
  7451.  
  7452.          if (Index <= Length) then
  7453.             Put ("correct ");
  7454.          end if;
  7455.  
  7456.          Put ("value.");
  7457.          New_Line;
  7458.  
  7459.          Index := Last + 1;
  7460.       end loop;
  7461.  
  7462.    end Get;
  7463.  
  7464.    pragma Page;
  7465.    -------------------------------------------------------------------
  7466.  
  7467.    procedure Get(Item   : out Num;
  7468.                  Width  : in  Field  := 0;
  7469.                  Prompt : in  String := "") is
  7470.  
  7471.       --!-------------------------------------------------------------
  7472.       --!
  7473.       --! Name:
  7474.       --!    Get
  7475.       --!
  7476.       --! Purpose:
  7477.       --!    This procedure displays the Prompt to Current_Output
  7478.       --!    and then attempts to read a value of type Num from 
  7479.       --!    Current_Input. If an Integer value is read, it is
  7480.       --!    converted to Num. If an invalid value is read, an
  7481.       --!    error message is displayed to Current_Output, and
  7482.       --!    a new value is read from the Current_Input.
  7483.       --!
  7484.       --! Parameters:
  7485.       --!    Item
  7486.       --!       returns the Num value as read from Current_Input.
  7487.       --!
  7488.       --!    Width
  7489.       --!       is the maximum field width for Item.
  7490.       --!
  7491.       --!    Prompt
  7492.       --!       is the prompt to be displayed to Current_Output.
  7493.       --!
  7494.       --! Exceptions:
  7495.       --!    Not applicable.
  7496.       --!
  7497.       --! Notes:
  7498.       --!    Not applicable.
  7499.       --!
  7500.       --!-------------------------------------------------------------
  7501.  
  7502.    begin
  7503.  
  7504.       Get (Current_Input, Item, Width, Prompt);
  7505.  
  7506.    end Get;
  7507.  
  7508.    pragma Page;
  7509.    -------------------------------------------------------------------
  7510.  
  7511.    procedure Put(File : in File_Type;
  7512.                  Item : in Num;
  7513.                  Fore : in Field := Default_Fore;
  7514.                  Aft  : in Field := Default_Aft;
  7515.                  Exp  : in Field := Default_Exp) is
  7516.  
  7517.       --!-------------------------------------------------------------
  7518.       --!
  7519.       --! Name:
  7520.       --!    Put
  7521.       --!
  7522.       --! Purpose:
  7523.       --!    This procedure writes the Item of type Num to the
  7524.       --!    specified File using the field definitions.
  7525.       --!
  7526.       --! Parameters:
  7527.       --!    File
  7528.       --!       is the file to which the Item will be written.
  7529.       --!
  7530.       --!    Item
  7531.       --!       is the Num value to be written to File.
  7532.       --!
  7533.       --!    Fore, Aft, Exp
  7534.       --!       Same as Float_Io.
  7535.       --!
  7536.       --! Exceptions:
  7537.       --!    Same as Float_Io.
  7538.       --!
  7539.       --! Notes:
  7540.       --!    Not applicable.
  7541.       --!
  7542.       --!-------------------------------------------------------------
  7543.  
  7544.    begin
  7545.  
  7546.       Float_Io.Put (File, Item, Fore, Aft, Exp);
  7547.  
  7548.    end Put;
  7549.  
  7550.    pragma Page;
  7551.    -------------------------------------------------------------------
  7552.  
  7553.    procedure Put(Item : in Num;
  7554.                  Fore : in Field := Default_Fore;
  7555.                  Aft  : in Field := Default_Aft;
  7556.                  Exp  : in Field := Default_Exp) is
  7557.  
  7558.       --!-------------------------------------------------------------
  7559.       --!
  7560.       --! Name:
  7561.       --!    Put
  7562.       --!
  7563.       --! Purpose:
  7564.       --!    This procedure writes the Item of type Num to 
  7565.       --!    standard output using the field definitions.
  7566.       --!
  7567.       --! Parameters:
  7568.       --!    Item
  7569.       --!       is the Num value to be written to File.
  7570.       --!
  7571.       --!    Fore, Aft, Exp
  7572.       --!       Same as Float_Io.
  7573.       --!
  7574.       --! Exceptions:
  7575.       --!    Same as Float_Io.
  7576.       --!
  7577.       --! Notes:
  7578.       --!    Not applicable.
  7579.       --!
  7580.       --!-------------------------------------------------------------
  7581.  
  7582.    begin
  7583.  
  7584.       Float_Io.Put (Item, Fore, Aft, Exp);
  7585.  
  7586.    end Put;
  7587.  
  7588.    pragma Page;
  7589.    -------------------------------------------------------------------
  7590.  
  7591.    procedure Get (From : in  String;
  7592.                   Item : out Num;
  7593.                   Last : out Positive) is
  7594.  
  7595.       --!-------------------------------------------------------------
  7596.       --!
  7597.       --! Name:
  7598.       --!    Get
  7599.       --!
  7600.       --! Purpose:
  7601.       --!    This procedure attempts to get an Item of type Num
  7602.       --!    from the String From.
  7603.       --!
  7604.       --! Parameters:
  7605.       --!    Same as Float_Io.Get (From, Item, Last).
  7606.       --!
  7607.       --! Exceptions:
  7608.       --!    Same as Float_Io.Get (From, Item, Last).
  7609.       --!
  7610.       --! Notes:
  7611.       --!    Not applicable.
  7612.       --!
  7613.       --!-------------------------------------------------------------
  7614.  
  7615.    begin
  7616.  
  7617.       Float_Io.Get (From, Item, Last);
  7618.  
  7619.    end Get;
  7620.  
  7621.    pragma Page;
  7622.    -------------------------------------------------------------------
  7623.  
  7624.    procedure Put (To   : out String;
  7625.                   Item : in  Num;
  7626.                   Aft  : in  Field   := Default_Aft;
  7627.                   Exp  : in  Integer := Default_Exp) is
  7628.  
  7629.       --!-------------------------------------------------------------
  7630.       --!
  7631.       --! Name:
  7632.       --!    Put
  7633.       --!
  7634.       --! Purpose:
  7635.       --!    This procedure writes an Item of type Num to the
  7636.       --!    String To using the field definitions.
  7637.       --!
  7638.       --! Parameters:
  7639.       --!    Same as Float_Io.Put (To, Item, Aft, Exp).
  7640.       --!
  7641.       --! Exceptions:
  7642.       --!    Same as Float_Io.Put (To, Item, Aft, Exp).
  7643.       --!
  7644.       --! Notes:
  7645.       --!    Not applicable.
  7646.       --!
  7647.       --!-------------------------------------------------------------
  7648.  
  7649.    begin
  7650.  
  7651.       Float_Io.Put (To, Item, Aft, Exp);
  7652.  
  7653.    end Put;
  7654.  
  7655. end Generic_Float_Io;
  7656. --::::::::::::::::::::::::::::
  7657. --GENERIC-SPELLING-IO-SPEC.ADA
  7658. --::::::::::::::::::::::::::::
  7659.  
  7660. with Text_Io;
  7661. use Text_Io;
  7662.  
  7663. generic
  7664.    type Enumeration is (<>);
  7665.  
  7666. package Generic_Spelling_Io is
  7667.  
  7668.    --!----------------------------------------------------------------
  7669.    --!
  7670.    --! Name:
  7671.    --!    Generic_Spelling_Io
  7672.    --!
  7673.    --! Purpose:
  7674.    --!    This generic package provides a friendly means of reading
  7675.    --!    and writing Enumeration values.
  7676.    --!
  7677.    --! Interfaces:
  7678.    --!    Get
  7679.    --!       reads an Item of type Enumeration after prompting the 
  7680.    --!       user.
  7681.    --!
  7682.    --!    Put
  7683.    --!       writes the image of an Item of type Enumeration.
  7684.    --!
  7685.    --! Exceptions:
  7686.    --!    Spelling_Error
  7687.    --!       is an internal exception which is raised if user input
  7688.    --!       matches none or more than one of the Enumeration values.
  7689.    --!
  7690.    --! Notes:
  7691.    --!    Friendly features of this package include:
  7692.    --!       entering least number of characters which provide
  7693.    --!          unambiguous result,
  7694.    --!       corrections of missing characters,
  7695.    --!       corrections of two letter transpositions.
  7696.    --!    It is expected that these features account for about 85 %
  7697.    --!    of all spelling errors.
  7698.    --!
  7699.    --!    If Assume is False in the call to Get, an Enumeration
  7700.    --!    value which is selected as a match to the input word,
  7701.    --!    though not a perfect match, is displayed with an informatory
  7702.    --!    message on standard output.
  7703.    --!
  7704.    --! Contract:
  7705.    --!    Ada Tracking Package Using Kalman Filter Methods
  7706.    --!    Contract No. N66001-85-C-0044 (31 December 1984)
  7707.    --!
  7708.    --! Prepared for:
  7709.    --!    Naval Ocean Systems Center (WIS JPMO)
  7710.    --!    271 Catalina Blvd., Building A-33
  7711.    --!    San Diego, CA 92152
  7712.    --!
  7713.    --! Prepared by:
  7714.    --!    Software Systems Engineering
  7715.    --!    Federal Systems Group
  7716.    --!
  7717.    --!    Sanders Associates, Inc.
  7718.    --!    95 Canal Street
  7719.    --!    Nashua, NH 03061
  7720.    --!
  7721.    --! Author:
  7722.    --!    Daryl R. Winters
  7723.    --!
  7724.    --!----------------------------------------------------------------
  7725.  
  7726.    pragma Page;
  7727.    -------------------------------------------------------------------
  7728.  
  7729.    Spelling_Error: exception;
  7730.  
  7731.    procedure Get (File:   in  File_Type;
  7732.                   Item:   out Enumeration;
  7733.                   Prompt: in  String  := "";
  7734.                   Assume: in  Boolean := True);
  7735.  
  7736.    procedure Get (Item:   out Enumeration;
  7737.                   Prompt: in  String  := "";
  7738.                   Assume: in  Boolean := True);
  7739.  
  7740.    procedure Put (File: in File_Type;
  7741.                   Item: in Enumeration);
  7742.  
  7743.    procedure Put (Item: in Enumeration);
  7744.  
  7745.  
  7746. end Generic_Spelling_Io;
  7747. --::::::::::::::::::::::::::::
  7748. --GENERIC-SPELLING-IO-BODY.ADA
  7749. --::::::::::::::::::::::::::::
  7750.  
  7751. with Text_Io;
  7752. with Kalman_String;
  7753. with Kalman_Check;
  7754. with Kalman_Text_Io;
  7755.  
  7756. use Text_Io;
  7757. use Kalman_String;
  7758. use Kalman_Check;
  7759. use Kalman_Text_Io;
  7760.  
  7761. package body Generic_Spelling_Io is
  7762.  
  7763.    --!----------------------------------------------------------------
  7764.    --!
  7765.    --! Name:
  7766.    --!    Generic_Spelling_Io
  7767.    --!
  7768.    --! Purpose:
  7769.    --!    This generic package body provides a friendly means of 
  7770.    --!    reading and writing Enumeration values.
  7771.    --!
  7772.    --! Exceptions:
  7773.    --!    Spelling_Error
  7774.    --!       is an internal exception which is raised if user input
  7775.    --!       matches none or more than one of the Enumeration values.
  7776.    --!
  7777.    --! Notes:
  7778.    --!    Friendly features of this package include:
  7779.    --!       entering least number of characters which provide
  7780.    --!          unambiguous result,
  7781.    --!       corrections of missing characters,
  7782.    --!       corrections of two letter transpositions.
  7783.    --!    It is expected that these features account for about 85 %
  7784.    --!    of all spelling errors.
  7785.    --!
  7786.    --!    If Assume is False in the call to Get, an Enumeration
  7787.    --!    value which is selected as a match to the input word,
  7788.    --!    though not a perfect match, is displayed with an informatory
  7789.    --!    message on standard output.
  7790.    --!
  7791.    --! Contract:
  7792.    --!    Ada Tracking Package Using Kalman Filter Methods
  7793.    --!    Contract No. N66001-85-C-0044 (31 December 1984)
  7794.    --!
  7795.    --! Prepared for:
  7796.    --!    Naval Ocean Systems Center (WIS JPMO)
  7797.    --!    271 Catalina Blvd., Building A-33
  7798.    --!    San Diego, CA 92152
  7799.    --!
  7800.    --! Prepared by:
  7801.    --!    Software Systems Engineering
  7802.    --!    Federal Systems Group
  7803.    --!
  7804.    --!    Sanders Associates, Inc.
  7805.    --!    95 Canal Street
  7806.    --!    Nashua, NH 03061
  7807.    --!
  7808.    --! Author:
  7809.    --!    Daryl R. Winters
  7810.    --!
  7811.    --! Changes:
  7812.    --!    04-APR-1985
  7813.    --!       Changed Kalman_Text to Kalman_String because of TeleSoft
  7814.    --!       file naming conflict with Kalman_Text_Io.
  7815.    --!
  7816.    --!----------------------------------------------------------------
  7817.  
  7818.    Index:  Natural renames Kalman_Text_Io.Index;
  7819.    Length: Natural renames Kalman_Text_Io.Length;
  7820.  
  7821.    pragma Page;
  7822.    -------------------------------------------------------------------
  7823.  
  7824.    Difference: constant Integer
  7825.                := Character'Pos ('a') - Character'Pos ('A');
  7826.  
  7827.    type Enumeration_Table is
  7828.       array (Enumeration'First .. Enumeration'Last) of Text_Type;
  7829.  
  7830.    Symbol: Enumeration_Table;
  7831.  
  7832.    pragma Page;
  7833.    -------------------------------------------------------------------
  7834.  
  7835.    function Correct
  7836.  
  7837.       (Word:   in String;
  7838.        Assume: in Boolean := False) return Enumeration is
  7839.  
  7840.       --!-------------------------------------------------------------
  7841.       --!
  7842.       --! Name:
  7843.       --!    Correct
  7844.       --!
  7845.       --! Purpose:
  7846.       --!    This local function returns an Enumeration value which
  7847.       --!    best matches the input Word.
  7848.       --!
  7849.       --! Parameters:
  7850.       --!    Word
  7851.       --!       is a string which is compared to values of type 
  7852.       --!       Enumeration.
  7853.       --! 
  7854.       --!    Assume
  7855.       --!       is a boolean which indicates whether a message 
  7856.       --!       informing the user of the selected match is displayed.
  7857.       --!
  7858.       --! Exceptions:
  7859.       --!    Spelling_Error
  7860.       --!       is raised if the Word matches none or more than one
  7861.       --!       of the Enumeration values.
  7862.       --!
  7863.       --! Notes:
  7864.       --!    If more than one value "matches" the Word, the list of
  7865.       --!    potential matches is displayed before Spelling_Error is
  7866.       --!    raised. If none match, then all values of type 
  7867.       --!    Enumeration are displayed.
  7868.       --!
  7869.       --!-------------------------------------------------------------
  7870.  
  7871.       Match_Count: Integer := 0;
  7872.       Last_Match: Enumeration;
  7873.  
  7874.       Found: Boolean;
  7875.  
  7876.       type Match_Array is
  7877.            array (Enumeration'First .. Enumeration'Last) of Boolean;
  7878.  
  7879.       Match: Match_Array;
  7880.  
  7881.       pragma Page;
  7882.       ----------------------------------------------------------------
  7883.  
  7884.       function Convert (Value: String) return String is
  7885.  
  7886.          --!----------------------------------------------------------
  7887.          --!
  7888.          --! Name:
  7889.          --!    Convert
  7890.          --!
  7891.          --! Purpose:
  7892.          --!    This local function returns the input string after
  7893.          --!    converting upper case to lower case.
  7894.          --!
  7895.          --! Parameters:
  7896.          --!    Value 
  7897.          --!       is a string.
  7898.          --!
  7899.          --! Exceptions:
  7900.          --!    Not applicable.
  7901.          --!
  7902.          --! Notes:
  7903.          --!    Not applicable.
  7904.          --!
  7905.          --!----------------------------------------------------------
  7906.  
  7907.          Result: String (Value'range) := Value;
  7908.  
  7909.       begin
  7910.          if (Result'Length > 0) then
  7911.  
  7912.             if (Result (Result'First) = ''') then
  7913.                -- Don't convert characters.
  7914.                return (Result);
  7915.             end if;
  7916.  
  7917.             if (Result (Result'Last) = ''') then
  7918.                -- Don't convert characters.
  7919.                return (Result);
  7920.             end if;
  7921.          end if;
  7922.  
  7923.          for I in Result'range loop
  7924.             if (Result (I) in 'a'..'z') then
  7925.                Result (I) := Character'Val
  7926.                              (Character'Pos
  7927.                               (Result (I)) - Difference);
  7928.             end if;
  7929.          end loop;
  7930.          return (Result);
  7931.       end Convert;
  7932.  
  7933.       pragma Page;
  7934.       ----------------------------------------------------------------
  7935.  
  7936.       function Compare (A, B: String) return Boolean is
  7937.  
  7938.          --!----------------------------------------------------------
  7939.          --!
  7940.          --! Name:
  7941.          --!    Compare
  7942.          --!
  7943.          --! Purpose:
  7944.          --!    This local function returns a boolean value which 
  7945.          --!    indicates whether the first character of the strings
  7946.          --!    are equal.
  7947.          --!
  7948.          --! Parameters:
  7949.          --!    A
  7950.          --!       is a string.
  7951.          --!
  7952.          --!    B
  7953.          --!       is a string.
  7954.          --!
  7955.          --! Exceptions:
  7956.          --!    Not applicable.
  7957.          --!
  7958.          --! Notes:
  7959.          --!    Letters in upper case and lower case are considered
  7960.          --!    equal.
  7961.          --!
  7962.          --!----------------------------------------------------------
  7963.  
  7964.          X1: Integer := A'First;
  7965.          Y1: Integer := B'First;
  7966.  
  7967.          X: String (X1..X1) := A (X1..X1);
  7968.          Y: String (Y1..Y1) := B (Y1..Y1);
  7969.  
  7970.       begin
  7971.          return (Convert (X) = Convert (Y));
  7972.       end Compare;
  7973.  
  7974.       pragma Page;
  7975.       ----------------------------------------------------------------
  7976.  
  7977.    begin
  7978.  
  7979.       for I in Enumeration'First .. Enumeration'Last loop
  7980.  
  7981.          if (Kalman_String.Length (Symbol (I)) = 0) then
  7982.             Match (I) := False;
  7983.          elsif (Word'Length = 1) then
  7984.             Match (I) := Compare (Word, Value (Symbol (I)));
  7985.          elsif (Word'Length = 2) then
  7986.             Match (I) := Compare (Word, Value (Symbol (I)));
  7987.          else
  7988.             Match (I) := Possibly_Correct (Word, Value (Symbol (I)));
  7989.          end if;
  7990.  
  7991.          if (Match (I)) then
  7992.             Match_Count := Match_Count + 1;
  7993.             Last_Match := I;
  7994.          end if;
  7995.       end loop;
  7996.  
  7997.       if (Match_Count = 1) then
  7998.          if (not Assume) then
  7999.             if (Convert (Word) /= Value (Symbol (Last_Match))) then
  8000.                New_Line;
  8001.                Put ("%SPELL-I-ASSUME, ");
  8002.                Put ("The value """);
  8003.                Put (Convert (Word));
  8004.                Put (""" is assumed to be """);
  8005.                Put (Value (Symbol (Last_Match)));
  8006.                Put (""".");
  8007.                New_Line;
  8008.                New_Line;
  8009.             end if;
  8010.          else
  8011.             null;
  8012.          end if;
  8013.  
  8014.          return Last_Match;
  8015.  
  8016.       elsif (Match_Count > 1) then
  8017.  
  8018.          New_Line;
  8019.          Put ("%SPELL-E-ANYONE, ");
  8020.          Put ("The value """);
  8021.          Put (Convert (Word));
  8022.          Put (""" could be any of the following:");
  8023.          New_Line;
  8024.  
  8025.          for I in Enumeration'First .. Last_Match loop
  8026.             if (Match (I)) then
  8027.                Put ("   ");
  8028.                Put (Value (Symbol (I)));
  8029.                New_Line;
  8030.             end if;
  8031.          end loop;
  8032.  
  8033.          raise Spelling_Error;
  8034.       else
  8035.          New_Line;
  8036.          Put ("%SPELL-E-UNKNOWN, ");
  8037.          Put ("The value """);
  8038.          Put (Convert (Word));
  8039.          Put (""" is not one of the following:");
  8040.          New_Line;
  8041.  
  8042.          for I in Enumeration'First .. Enumeration'Last loop
  8043.             Put ("   ");
  8044.             Put (Value (Symbol (I)));
  8045.             New_Line;
  8046.          end loop;
  8047.  
  8048.          raise Spelling_Error;
  8049.       end if;
  8050.    end Correct;
  8051.  
  8052.    pragma Page;
  8053.    -------------------------------------------------------------------
  8054.  
  8055.    procedure Get (File:   in  File_Type;
  8056.                   Item:   out Enumeration;
  8057.                   Prompt: in  String  := "";
  8058.                   Assume: in  Boolean := True) is
  8059.  
  8060.       --!-------------------------------------------------------------
  8061.       --!
  8062.       --! Name:
  8063.       --!    Get
  8064.       --!
  8065.       --! Purpose:
  8066.       --!    This procedure reads an Item of type Enumeration from
  8067.       --!    File after prompting.
  8068.       --!
  8069.       --! Parameters:
  8070.       --!    File
  8071.       --!       is the input file.
  8072.       --!
  8073.       --!    Item
  8074.       --!       is the selected Enumeration value.
  8075.       --!
  8076.       --!    Prompt
  8077.       --!       is the prompt string.
  8078.       --!
  8079.       --!    Assume
  8080.       --!       is a boolean which indicates whether a message 
  8081.       --!       informing the user of the selected match is displayed.
  8082.       --!
  8083.       --! Exceptions:
  8084.       --!    Not applicable.
  8085.       --!
  8086.       --! Notes:
  8087.       --!    The user if reprompted if a spelling error occurs.
  8088.       --!
  8089.       --!-------------------------------------------------------------
  8090.  
  8091.       Last: Natural;
  8092.  
  8093.    begin
  8094.       loop
  8095.          Get_Line (File, Prompt);
  8096.  
  8097.          if (Index > Length) then
  8098.             New_Line;
  8099.             Put ("%SPELL-E-LEGAL, ");
  8100.             Put ("A correct value is one of the following:");
  8101.             New_Line;
  8102.  
  8103.             for I in Enumeration'First .. Enumeration'Last loop
  8104.                Put ("   ");
  8105.                Put (Value (Symbol (I)));
  8106.                New_Line;
  8107.             end loop;
  8108.  
  8109.             New_Line;
  8110.             Put ("%SPELL-E-EMPTY, ");
  8111.             Put ("Please enter a value.");
  8112.             New_Line;
  8113.          else
  8114.             -- Skip preceding blanks.
  8115.             for I in Index .. Length loop
  8116.  
  8117.                if (Buffer (I) /= ' ') then
  8118.                   Index := I;
  8119.                   exit;
  8120.                end if;
  8121.             end loop;
  8122.  
  8123.             Last := Length;
  8124.  
  8125.             -- Find next blank.
  8126.             for I in Index + 1 .. Length loop
  8127.  
  8128.                if (Buffer (I) = ' ') then
  8129.                   Last := I - 1;
  8130.                   exit;
  8131.                end if;
  8132.             end loop;
  8133.  
  8134.             begin
  8135.                Item := Correct (Buffer (Index..Last), Assume);
  8136.                Index := Last + 1;
  8137.                exit;
  8138.             exception
  8139.                when Spelling_Error =>
  8140.                   New_Line;
  8141.                   Put ("%SPELL-E-RETRY, ");
  8142.                   Put ("Please re-enter the correct value.");
  8143.                   New_Line;
  8144.  
  8145.                   Index := Last + 1;
  8146.             end;
  8147.          end if;
  8148.       end loop;
  8149.    end Get;
  8150.  
  8151.    pragma Page;
  8152.    -------------------------------------------------------------------
  8153.  
  8154.    procedure Get (Item:   out Enumeration;
  8155.                   Prompt: in  String  := "";
  8156.                   Assume: in  Boolean := True) is
  8157.  
  8158.       --!-------------------------------------------------------------
  8159.       --!
  8160.       --! Name:
  8161.       --!    Get
  8162.       --!
  8163.       --! Purpose:
  8164.       --!    This procedure reads an Item of type Enumeration from
  8165.       --!    Current_Input after prompting.
  8166.       --!
  8167.       --! Parameters:
  8168.       --!    Item
  8169.       --!       is the selected Enumeration value.
  8170.       --!
  8171.       --!    Prompt
  8172.       --!       is the prompt string.
  8173.       --!
  8174.       --!    Assume
  8175.       --!       is a boolean which indicates whether a message 
  8176.       --!       informing the user of the selected match is displayed.
  8177.       --!
  8178.       --! Exceptions:
  8179.       --!    Not applicable.
  8180.       --!
  8181.       --! Notes:
  8182.       --!    The user if reprompted if a spelling error occurs.
  8183.       --!
  8184.       --!-------------------------------------------------------------
  8185.  
  8186.    begin
  8187.  
  8188.       Get (Current_Input, Item, Prompt, Assume);
  8189.  
  8190.    end Get;
  8191.  
  8192.    pragma Page;
  8193.    -------------------------------------------------------------------
  8194.  
  8195.    procedure Put (File: in File_Type;
  8196.                   Item: in Enumeration) is
  8197.  
  8198.       --!-------------------------------------------------------------
  8199.       --!
  8200.       --! Name:
  8201.       --!    Put
  8202.       --!
  8203.       --! Purpose:
  8204.       --!    This procedure writes the image of an Item of type 
  8205.       --!    Enumeration to File.
  8206.       --!
  8207.       --! Parameters:
  8208.       --!    File
  8209.       --!       is the output file.
  8210.       --!
  8211.       --!   Item
  8212.       --!       is the Enumeration value.
  8213.       --!
  8214.       --! Exceptions:
  8215.       --!    Not applicable.
  8216.       --!
  8217.       --! Notes:
  8218.       --!    Not applicable.
  8219.       --!
  8220.       --!-------------------------------------------------------------
  8221.  
  8222.    begin
  8223.  
  8224.       Put (File, Enumeration'Image (Item));
  8225.  
  8226.    end Put;
  8227.  
  8228.    pragma Page;
  8229.    -------------------------------------------------------------------
  8230.  
  8231.    procedure Put (Item: in Enumeration) is
  8232.  
  8233.       --!-------------------------------------------------------------
  8234.       --!
  8235.       --! Name:
  8236.       --!    Put
  8237.       --!
  8238.       --! Purpose:
  8239.       --!    This procedure writes the image of an Item of type 
  8240.       --!    Enumeration to standard output.
  8241.       --!
  8242.       --! Parameters:
  8243.       --!   Item
  8244.       --!       is the Enumeration value.
  8245.       --!
  8246.       --! Exceptions:
  8247.       --!    Not applicable.
  8248.       --!
  8249.       --! Notes:
  8250.       --!    Not applicable.
  8251.       --!
  8252.       --!-------------------------------------------------------------
  8253.  
  8254.    begin
  8255.  
  8256.       Put (Enumeration'Image (Item));
  8257.  
  8258.    end Put;
  8259.  
  8260.    pragma Page;
  8261.    -------------------------------------------------------------------
  8262.  
  8263. begin
  8264.  
  8265.    for I in Enumeration'First .. Enumeration'Last loop
  8266.       Set (Symbol (I), Enumeration'Image (I));
  8267.    end loop;
  8268.  
  8269. end Generic_Spelling_Io;
  8270. --::::::::::::::::::::::::::::
  8271. --KALMAN-DURATION-IO-SPEC.ADA
  8272. --::::::::::::::::::::::::::::
  8273.  
  8274. with Generic_Fixed_Io;
  8275.  
  8276. package Kalman_Duration_Io is
  8277.  
  8278.    --!----------------------------------------------------------------
  8279.    --!
  8280.    --! Name:
  8281.    --!    Kalman_Duration_Io
  8282.    --!
  8283.    --! Purpose:
  8284.    --!    This generic package instantiation provides a library unit
  8285.    --!    instantiation of the package Generic_Fixed_Io in order to
  8286.    --!    minimize the compilation overhead of the Ada Kalman Filter.
  8287.    --!
  8288.    --! Interfaces:
  8289.    --!    Same as package Generic_Fixed_Io.
  8290.    --!
  8291.    --! Exceptions:
  8292.    --!    Same as package Generic_Fixed_Io.
  8293.    --!
  8294.    --! Notes:
  8295.    --!    Not applicable.
  8296.    --!
  8297.    --! Contract:
  8298.    --!    Ada Tracking Package Using Kalman Filter Methods
  8299.    --!    Contract No. N66001-85-C-0044 (31 December 1984)
  8300.    --!
  8301.    --! Prepared for:
  8302.    --!    Naval Ocean Systems Center (WIS JPMO)
  8303.    --!    271 Catalina Blvd., Building A-33
  8304.    --!    San Diego, CA 92152
  8305.    --!
  8306.    --! Prepared by:
  8307.    --!    Software Systems Engineering
  8308.    --!    Federal Systems Group
  8309.    --!
  8310.    --!    Sanders Associates, Inc.
  8311.    --!    95 Canal Street
  8312.    --!    Nashua, NH 03061
  8313.    --!
  8314.    --! Author:
  8315.    --!    Jeffrey G. Smith
  8316.    --!
  8317.    --!----------------------------------------------------------------
  8318.  
  8319.    new Generic_Fixed_Io (Duration);
  8320. --::::::::::::::::::::::::::::
  8321. --KALMAN-INTEGER-IO-SPEC.ADA
  8322. --::::::::::::::::::::::::::::
  8323.  
  8324. with Generic_Integer_Io;
  8325.  
  8326. package Kalman_Integer_Io is
  8327.  
  8328.    --!----------------------------------------------------------------
  8329.    --!
  8330.    --! Name:
  8331.    --!    Kalman_Integer_Io
  8332.    --!
  8333.    --! Purpose:
  8334.    --!    This generic package instantiation provides a library unit
  8335.    --!    instantiation of the package Generic_Integer_Io in order to
  8336.    --!    minimize the compilation overhead of the Ada Kalman Filter.
  8337.    --!
  8338.    --! Interfaces:
  8339.    --!    Same as package Generic_Integer_Io.
  8340.    --!
  8341.    --! Exceptions:
  8342.    --!    Same as package Generic_Integer_Io.
  8343.    --!
  8344.    --! Notes:
  8345.    --!    Not applicable.
  8346.    --!
  8347.    --! Contract:
  8348.    --!    Ada Tracking Package Using Kalman Filter Methods
  8349.    --!    Contract No. N66001-85-C-0044 (31 December 1984)
  8350.    --!
  8351.    --! Prepared for:
  8352.    --!    Naval Ocean Systems Center (WIS JPMO)
  8353.    --!    271 Catalina Blvd., Building A-33
  8354.    --!    San Diego, CA 92152
  8355.    --!
  8356.    --! Prepared by:
  8357.    --!    Software Systems Engineering
  8358.    --!    Federal Systems Group
  8359.    --!
  8360.    --!    Sanders Associates, Inc.
  8361.    --!    95 Canal Street
  8362.    --!    Nashua, NH 03061
  8363.    --!
  8364.    --! Author:
  8365.    --!    Jeffrey G. Smith
  8366.    --!
  8367.    --!----------------------------------------------------------------
  8368.  
  8369.    new Generic_Integer_Io (Integer);
  8370. with Generic_Float_Io;
  8371.  
  8372. package Kalman_Float_Io is
  8373.  
  8374.    --!----------------------------------------------------------------
  8375.    --!
  8376.    --! Name:
  8377.    --!    Kalman_Float_Io
  8378.    --!
  8379.    --! Purpose:
  8380.    --!    This generic package instantiation provides a library unit
  8381.    --!    instantiation of the package Generic_Float_Io in order to
  8382.    --!    minimize the compilation overhead of the Ada Kalman Filter.
  8383.    --!
  8384.    --! Interfaces:
  8385.    --!    Same as package Generic_Float_Io.
  8386.    --!
  8387.    --! Exceptions:
  8388.    --!    Same as package Generic_Float_Io.
  8389.    --!
  8390.    --! Notes:
  8391.    --!    Not applicable.
  8392.    --!
  8393.    --! Contract:
  8394.    --!    Ada Tracking Package Using Kalman Filter Methods
  8395.    --!    Contract No. N66001-85-C-0044 (31 December 1984)
  8396.    --!
  8397.    --! Prepared for:
  8398.    --!    Naval Ocean Systems Center (WIS JPMO)
  8399.    --!    271 Catalina Blvd., Building A-33
  8400.    --!    San Diego, CA 92152
  8401.    --!
  8402.    --! Prepared by:
  8403.    --!    Software Systems Engineering
  8404.    --!    Federal Systems Group
  8405.    --!
  8406.    --!    Sanders Associates, Inc.
  8407.    --!    95 Canal Street
  8408.    --!    Nashua, NH 03061
  8409.    --!
  8410.    --! Author:
  8411.    --!    Jeffrey G. Smith
  8412.    --!
  8413.    --!----------------------------------------------------------------
  8414.  
  8415.    new Generic_Float_Io (Float);
  8416. --::::::::::::::::::::::::::::
  8417. --KALMAN-TRIG-LIB-SPEC.ADA
  8418. --::::::::::::::::::::::::::::
  8419.  
  8420. package Kalman_Trig_Lib is
  8421.  
  8422.    --!----------------------------------------------------------------
  8423.    --!
  8424.    --! Name:
  8425.    --!    Kalman_Trig_Lib
  8426.    --!
  8427.    --! Purpose:
  8428.    --!    This package provides a common interface to several 
  8429.    --!    different mathematics libraries for the Ada Kalman Filter.
  8430.    --!
  8431.    --! Interfaces:
  8432.    --!    Sqrt
  8433.    --!       returns the square root of the input value.
  8434.    --!
  8435.    --!    Cbrt
  8436.    --!       returns the cube root of the input value.
  8437.    --!
  8438.    --!    Log
  8439.    --!       returns the natural logarithm of the input value.
  8440.    --!
  8441.    --!    Log10
  8442.    --!       returns the base 10 logarithm of the input value.
  8443.    --!
  8444.    --!    Log2
  8445.    --!       returns the base 2 logarithm of the input value.
  8446.    --!
  8447.    --!    Exp
  8448.    --!       returns "e" raised to the power of the input value.
  8449.    --!
  8450.    --!    "**"
  8451.    --!       returns the value raised to the specified power.
  8452.    --!
  8453.    --!    Sin
  8454.    --!       returns the sine of the input angle.
  8455.    --!
  8456.    --!    Cos
  8457.    --!       returns the cosine of the input angle.
  8458.    --!
  8459.    --!    Tan
  8460.    --!       returns the tangent of the input angle.
  8461.    --!
  8462.    --!    Cot
  8463.    --!       returns the cotangent of the input angle.
  8464.    --!
  8465.    --!    Asin
  8466.    --!       returns the arcsine expressed in radians 
  8467.    --!       of the input value.
  8468.    --!
  8469.    --!    Acos
  8470.    --!       returns the arccosine expressed in radians 
  8471.    --!       of the input value.
  8472.    --!
  8473.    --!    Atan
  8474.    --!       returns the arctangent expressed in radians 
  8475.    --!       of the input value.
  8476.    --!
  8477.    --!    Atan2
  8478.    --!       returns the arctangent expressed in radians
  8479.    --!       of the input values.
  8480.    --!
  8481.    --!    Sinh
  8482.    --!       returns the hyperbolic sine of the input angle.
  8483.    --!
  8484.    --!    Cosh
  8485.    --!       returns the hyperbolic cosine of the input angle.
  8486.    --!
  8487.    --!    Tanh
  8488.    --!       returns the hyperbolic tangent of the input angle.
  8489.    --!
  8490.    --!    Sind
  8491.    --!       returns the sine of the angle expressed in degrees.
  8492.    --!
  8493.    --!    Cosd
  8494.    --!       returns the cosine of the angle expressed in degrees.
  8495.    --!
  8496.    --!    Tand
  8497.    --!       returns the tangent of the angle expressed in degrees.
  8498.    --!
  8499.    --!    Asind
  8500.    --!       returns the arcsine in degrees of the value.
  8501.    --!
  8502.    --!    Acosd
  8503.    --!       returns the arccosine in degrees of the value.
  8504.    --!
  8505.    --!    Atand
  8506.    --!       returns the arctangent in degrees of the value.
  8507.    --!
  8508.    --!    Atan2d
  8509.    --!       returns the arctangent in degrees of the values.
  8510.    --!
  8511.    --! Exceptions:
  8512.    --!    Math_Error
  8513.    --!       is raised if the requested operation cannot be performed.
  8514.    --!
  8515.    --! Notes:
  8516.    --!    Not all operations are available from every math library.
  8517.    --!
  8518.    --! Contract:
  8519.    --!    Ada Tracking Package Using Kalman Filter Methods
  8520.    --!    Contract No. N66001-85-C-0044 (31 December 1984)
  8521.    --!
  8522.    --! Prepared for:
  8523.    --!    Naval Ocean Systems Center (WIS JPMO)
  8524.    --!    271 Catalina Blvd., Building A-33
  8525.    --!    San Diego, CA 92152
  8526.    --!
  8527.    --! Prepared by:
  8528.    --!    Software Systems Engineering
  8529.    --!    Federal Systems Group
  8530.    --!
  8531.    --!    Sanders Associates, Inc.
  8532.    --!    95 Canal Street
  8533.    --!    Nashua, NH 03061
  8534.    --!
  8535.    --! Author:
  8536.    --!    Daryl R. Winters
  8537.    --!
  8538.    --! Changes:
  8539.    --!    04-APR-1985
  8540.    --!       Changed Kalman_Math_Lib to Kalman_Trig_Lib because of 
  8541.    --!       TeleSoft file naming conflict with Kalman_Matrix.
  8542.    --!
  8543.    --!----------------------------------------------------------------
  8544.  
  8545.    -- Vendor name (of real Math library).
  8546.  
  8547.    type Vendor_Type is (Digital, Telesoft, Whitaker, Stub);
  8548.    Vendor: Vendor_Type := Whitaker;
  8549.  
  8550.    procedure Request_Vendor;
  8551.  
  8552.    -------------------------------------------------------------------
  8553.  
  8554.    function Sqrt  (A : Float) return Float;
  8555.    function Cbrt  (A : Float) return Float;
  8556.    function Log   (A : Float) return Float;
  8557.    function Log10 (A : Float) return Float;
  8558.    function Log2  (A : Float) return Float;
  8559.    function Exp   (A : Float) return Float;
  8560.  
  8561.    function "**"  (X, Y : Float) return Float;
  8562.  
  8563.    -------------------------------------------------------------------
  8564.  
  8565.    -- Sine, cosine, and tangent of an angle given in radians.
  8566.  
  8567.    function Sin (A : Float) return Float;
  8568.    function Cos (A : Float) return Float;
  8569.    function Tan (A : Float) return Float;
  8570.    function Cot (A : Float) return Float;
  8571.  
  8572.    -------------------------------------------------------------------
  8573.  
  8574.    -- Arc sine, arc cosine, and arc tangent - return an angle
  8575.    -- expressed in radians.
  8576.  
  8577.    function Asin (A : Float) return Float;
  8578.    function Acos (A : Float) return Float;
  8579.    function Atan (A : Float) return Float;
  8580.  
  8581.    -------------------------------------------------------------------
  8582.  
  8583.    -- Arc tangent with two parameters - Arc Tan (A1/A2) - returns
  8584.    -- an angle expressed in radians.
  8585.  
  8586.    function Atan2 (A1, A2 : Float) return Float;
  8587.  
  8588.    -------------------------------------------------------------------
  8589.  
  8590.    -- Hyperbolic sine, cosine, and tangent of an angle in radians.
  8591.  
  8592.    function Sinh (A : Float) return Float;
  8593.    function Cosh (A : Float) return Float;
  8594.    function Tanh (A : Float) return Float;
  8595.  
  8596.    -------------------------------------------------------------------
  8597.  
  8598.    -- Trigonometric functions for angles expressed in degrees.
  8599.  
  8600.    function Sind (A : Float) return Float;
  8601.    function Cosd (A : Float) return Float;
  8602.    function Tand (A : Float) return Float;
  8603.  
  8604.    function Asind (A : Float) return Float;
  8605.    function Acosd (A : Float) return Float;
  8606.    function Atand (A : Float) return Float;
  8607.  
  8608.    function Atan2D (A1, A2 : Float) return Float;
  8609.  
  8610.    -------------------------------------------------------------------
  8611.  
  8612.    Math_Error: exception;
  8613.  
  8614.    -- pragma Inline (Sqrt, Log, Log10, Log2, Exp, Sin, Cos, Tan, Cot,
  8615.    --                Asin, Acos, Atan, Atan2, Sinh, Cosh, Tanh,
  8616.    --                Sind, Cosd, Tand, Asind, Acosd, Atand, Atan2D);
  8617.  
  8618. end Kalman_Trig_Lib;
  8619. --::::::::::::::::::::::::::::
  8620. --KALMAN-TRIG-LIB-BODY.ADA
  8621. --::::::::::::::::::::::::::::
  8622.  
  8623. with Generic_Spelling_Io;
  8624.  
  8625. with Float_Math_Lib;      -- Digital
  8626. with Realfunc;            -- TeleSoft
  8627. with Core_Functions;      -- Whitaker
  8628. with Trig_Functions;      -- Whitaker
  8629.  
  8630. with Text_Io;
  8631. with Kalman_Options;
  8632.  
  8633. use Text_Io;
  8634. use Kalman_Options;
  8635.  
  8636. package body Kalman_Trig_Lib is
  8637.  
  8638.    --!----------------------------------------------------------------
  8639.    --!
  8640.    --! Name:
  8641.    --!    Kalman_Trig_Lib
  8642.    --!
  8643.    --! Purpose:
  8644.    --!    This package body provides a common interface to several
  8645.    --!    different mathematics libraries for the Ada Kalman Filter.
  8646.    --!
  8647.    --! Exceptions:
  8648.    --!    Math_Error
  8649.    --!       is raised if the requested operation cannot be performed.
  8650.    --!
  8651.    --! Notes:
  8652.    --!    Not all operations are available from every library.
  8653.    --!
  8654.    --! Contract:
  8655.    --!    Ada Tracking Package Using Kalman Filter Methods
  8656.    --!    Contract No. N66001-85-C-0044 (31 December 1984)
  8657.    --!
  8658.    --! Prepared for:
  8659.    --!    Naval Ocean Systems Center (WIS JPMO)
  8660.    --!    271 Catalina Blvd., Building A-33
  8661.    --!    San Diego, CA 92152
  8662.    --!
  8663.    --! Prepared by:
  8664.    --!    Software Systems Engineering
  8665.    --!    Federal Systems Group
  8666.    --!
  8667.    --!    Sanders Associates, Inc.
  8668.    --!    95 Canal Street
  8669.    --!    Nashua, NH 03061
  8670.    --!
  8671.    --! Author:
  8672.    --!    Daryl R. Winters
  8673.    --!
  8674.    --! Changes:
  8675.    --!    04-APR-1985
  8676.    --!       Changed Kalman_Math_Lib to Kalman_Trig_Lib because of 
  8677.    --!       TeleSoft file naming conflict with Kalman_Matrix.
  8678.    --!
  8679.    --!----------------------------------------------------------------
  8680.  
  8681.    package Vendor_Io is
  8682.       new Generic_Spelling_Io (Vendor_Type);
  8683.    use Vendor_Io;
  8684.  
  8685.    pragma Page;
  8686.    -------------------------------------------------------------------
  8687.  
  8688.    procedure Request_Vendor is
  8689.  
  8690.       --!-------------------------------------------------------------
  8691.       --!
  8692.       --! Name:
  8693.       --!    Request_Vendor
  8694.       --!
  8695.       --! Purpose:
  8696.       --!    This procedure sets the vendor name from user input.
  8697.       --!
  8698.       --! Parameters:
  8699.       --!    Not applicable.
  8700.       --!
  8701.       --! Exceptions:
  8702.       --!    Not applicable.
  8703.       --!
  8704.       --! Notes:
  8705.       --!    This routine should be called once to initialize
  8706.       --!    the choice of mathematics library.
  8707.       --!
  8708.       --!-------------------------------------------------------------
  8709.  
  8710.    begin
  8711.  
  8712.       Get (Vendor, Prompt => "%TRIG-P-MTHLIB, " &
  8713.                        "Math library? ");
  8714.  
  8715.    end Request_Vendor;
  8716.  
  8717.    pragma Page;
  8718.    -------------------------------------------------------------------
  8719.  
  8720.    function Sqrt (A : Float) return Float is
  8721.  
  8722.       --!-------------------------------------------------------------
  8723.       --!
  8724.       --! Name:
  8725.       --!    Sqrt
  8726.       --!
  8727.       --! Purpose:
  8728.       --!    This function returns the square root of the input value.
  8729.       --!
  8730.       --! Parameters:
  8731.       --!    A
  8732.       --!       is a float value.
  8733.       --!
  8734.       --! Exceptions:
  8735.       --!    Math_Error
  8736.       --!       is raised if any exception occurs.
  8737.       --!
  8738.       --! Notes:
  8739.       --!    Not applicable.
  8740.       --!
  8741.       --!-------------------------------------------------------------
  8742.  
  8743.    begin
  8744.       case Vendor is
  8745.          when Digital =>
  8746.             return Float_Math_Lib.Sqrt (A);
  8747.          when Telesoft =>
  8748.             return Realfunc.Sqrt (A);
  8749.          when Whitaker =>
  8750.             return Core_Functions.Sqrt (A);
  8751.          when others =>
  8752.             return 1.0;
  8753.       end case;
  8754.  
  8755.    exception
  8756.       when others =>
  8757.          raise Math_Error;
  8758.    end Sqrt;
  8759.  
  8760.    pragma Page;
  8761.    -------------------------------------------------------------------
  8762.  
  8763.    function Cbrt (A : Float) return Float is
  8764.  
  8765.       --!-------------------------------------------------------------
  8766.       --!
  8767.       --! Name:
  8768.       --!    Cbrt
  8769.       --!
  8770.       --! Purpose:
  8771.       --!    This function returns the cube root of the input value.
  8772.       --!
  8773.       --! Parameters:
  8774.       --!    A
  8775.       --!       is a float value.
  8776.       --!
  8777.       --! Exceptions:
  8778.       --!    Math_Error
  8779.       --!       is raised if any exception occurs.
  8780.       --!
  8781.       --! Notes:
  8782.       --!    Not applicable.
  8783.       --!
  8784.       --!-------------------------------------------------------------
  8785.  
  8786.    begin
  8787.       case Vendor is
  8788.          when Digital =>
  8789.             raise Math_Error;
  8790.          when Telesoft =>
  8791.             raise Math_Error;
  8792.          when Whitaker =>
  8793.             return Core_Functions.Cbrt (A);
  8794.          when others =>
  8795.             return 1.0;
  8796.       end case;
  8797.  
  8798.    exception
  8799.       when others =>
  8800.          raise Math_Error;
  8801.    end Cbrt;
  8802.  
  8803.    pragma Page;
  8804.    -------------------------------------------------------------------
  8805.  
  8806.    function Log (A : Float) return Float is
  8807.  
  8808.       --!-------------------------------------------------------------
  8809.       --!
  8810.       --! Name:
  8811.       --!    Log
  8812.       --!
  8813.       --! Purpose:
  8814.       --!    This function returns the natural logarithm of the
  8815.       --!    input value.
  8816.       --!
  8817.       --! Parameters:
  8818.       --!    A
  8819.       --!       is a float value.
  8820.       --!
  8821.       --! Exceptions:
  8822.       --!    Math_Error
  8823.       --!       is raised if any exception occurs.
  8824.       --!
  8825.       --! Notes:
  8826.       --!    Not applicable.
  8827.       --!
  8828.       --!-------------------------------------------------------------
  8829.  
  8830.    begin
  8831.       case Vendor is
  8832.          when Digital =>
  8833.             return Float_Math_Lib.Log (A);
  8834.          when Telesoft =>
  8835.             return Realfunc.Ln (A);
  8836.          when Whitaker =>
  8837.             return Core_Functions.Log (A);
  8838.          when others =>
  8839.             return 1.0;
  8840.       end case;
  8841.  
  8842.    exception
  8843.       when others =>
  8844.          raise Math_Error;
  8845.    end Log;
  8846.  
  8847.    pragma Page;
  8848.    -------------------------------------------------------------------
  8849.  
  8850.    function Log10 (A : Float) return Float is
  8851.  
  8852.       --!-------------------------------------------------------------
  8853.       --!
  8854.       --! Name:
  8855.       --!    Log10
  8856.       --!
  8857.       --! Purpose:
  8858.       --!    This function returns the base 10 logarithm of the
  8859.       --!    input value.
  8860.       --!
  8861.       --! Parameters:
  8862.       --!    A
  8863.       --!       is a float value.
  8864.       --!
  8865.       --! Exceptions:
  8866.       --!    Math_Error
  8867.       --!       is raised if any exception occurs.
  8868.       --!
  8869.       --! Notes:
  8870.       --!    Not applicable.
  8871.       --!
  8872.       --!-------------------------------------------------------------
  8873.  
  8874.    begin
  8875.       case Vendor is
  8876.          when Digital =>
  8877.             return Float_Math_Lib.Log10 (A);
  8878.          when Telesoft =>
  8879.             return Realfunc.Log (A);
  8880.          when Whitaker =>
  8881.             return Core_Functions.Log10 (A);
  8882.          when others =>
  8883.             return 1.0;
  8884.       end case;
  8885.  
  8886.    exception
  8887.       when others =>
  8888.          raise Math_Error;
  8889.    end Log10;
  8890.  
  8891.    pragma Page;
  8892.    -------------------------------------------------------------------
  8893.  
  8894.    function Log2 (A : Float) return Float is
  8895.  
  8896.       --!-------------------------------------------------------------
  8897.       --!
  8898.       --! Name:
  8899.       --!    Log2
  8900.       --!
  8901.       --! Purpose:
  8902.       --!    This function returns the base 2 logarithm of the 
  8903.       --!    input value.
  8904.       --!
  8905.       --! Parameters:
  8906.       --!    A
  8907.       --!       is a float value.
  8908.       --!
  8909.       --! Exceptions:
  8910.       --!    Math_Error
  8911.       --!       is raised if any exception occurs.
  8912.       --!
  8913.       --! Notes:
  8914.       --!    Not applicable.
  8915.       --!
  8916.       --!-------------------------------------------------------------
  8917.  
  8918.    begin
  8919.       case Vendor is
  8920.          when Digital =>
  8921.             return Float_Math_Lib.Log2 (A);
  8922.          when Telesoft =>
  8923.             raise Math_Error;
  8924.          when Whitaker =>
  8925.             raise Math_Error;
  8926.          when others =>
  8927.             return 1.0;
  8928.       end case;
  8929.  
  8930.    exception
  8931.       when others =>
  8932.          raise Math_Error;
  8933.    end Log2;
  8934.  
  8935.    pragma Page;
  8936.    -------------------------------------------------------------------
  8937.  
  8938.    function Exp (A : Float) return Float is
  8939.  
  8940.       --!-------------------------------------------------------------
  8941.       --!
  8942.       --! Name:
  8943.       --!    Exp
  8944.       --!
  8945.       --! Purpose:
  8946.       --!    This function returns "e" raised to the power of the
  8947.       --!    input value.
  8948.       --!
  8949.       --! Parameters:
  8950.       --!    A
  8951.       --!       is a float value.
  8952.       --!
  8953.       --! Exceptions:
  8954.       --!    Math_Error
  8955.       --!       is raised if any exception occurs.
  8956.       --!
  8957.       --! Notes:
  8958.       --!    Not applicable.
  8959.       --!
  8960.       --!-------------------------------------------------------------
  8961.  
  8962.    begin
  8963.       case Vendor is
  8964.          when Digital =>
  8965.             return Float_Math_Lib.Exp (A);
  8966.          when Telesoft =>
  8967.             return Realfunc.Exp (A);
  8968.          when Whitaker =>
  8969.             return Core_Functions.Exp (A);
  8970.          when others =>
  8971.             return 1.0;
  8972.       end case;
  8973.  
  8974.    exception
  8975.       when others =>
  8976.          raise Math_Error;
  8977.    end Exp;
  8978.  
  8979.    pragma Page;
  8980.    -------------------------------------------------------------------
  8981.  
  8982.    function "**" (X, Y : Float) return Float is
  8983.  
  8984.       --!-------------------------------------------------------------
  8985.       --!
  8986.       --! Name:
  8987.       --!    "**"
  8988.       --!
  8989.       --! Purpose:
  8990.       --!    This function returns the value X raised to the 
  8991.       --!    power Y.
  8992.       --!
  8993.       --! Parameters:
  8994.       --!    X
  8995.       --!       is the base value.
  8996.       --!    Y
  8997.       --!       is the power.
  8998.       --!
  8999.       --! Exceptions:
  9000.       --!    Math_Error
  9001.       --!       is raised if any exception occurs.
  9002.       --!
  9003.       --! Notes:
  9004.       --!    Not applicable.
  9005.       --!
  9006.       --!-------------------------------------------------------------
  9007.  
  9008.    begin
  9009.       case Vendor is
  9010.          when Digital =>
  9011.             raise Math_Error;
  9012.          when Telesoft =>
  9013.             raise Math_Error;
  9014.          when Whitaker =>
  9015.             return Core_Functions."**" (X, Y);
  9016.          when others =>
  9017.             return 1.0;
  9018.       end case;
  9019.  
  9020.    exception
  9021.       when others =>
  9022.          raise Math_Error;
  9023.    end "**";
  9024.  
  9025.    pragma Page;
  9026.    -------------------------------------------------------------------
  9027.  
  9028.    function Sin (A : Float) return Float is
  9029.  
  9030.       --!-------------------------------------------------------------
  9031.       --!
  9032.       --! Name:
  9033.       --!    Sin
  9034.       --!
  9035.       --! Purpose:
  9036.       --!    This function returns the sine of the input angle.
  9037.       --!
  9038.       --! Parameters:
  9039.       --!    A
  9040.       --!       is the angle expressed in radians.
  9041.       --!
  9042.       --! Exceptions:
  9043.       --!    Math_Error
  9044.       --!       is raised if any exception occurs.
  9045.       --!
  9046.       --! Notes:
  9047.       --!    Not applicable.
  9048.       --!
  9049.       --!-------------------------------------------------------------
  9050.  
  9051.    begin
  9052.       case Vendor is
  9053.          when Digital =>
  9054.             return Float_Math_Lib.Sin (A);
  9055.          when Telesoft =>
  9056.             return Realfunc.Sin (A);
  9057.          when Whitaker =>
  9058.             return Trig_Functions.Sin (A);
  9059.          when others =>
  9060.             return 1.0;
  9061.       end case;
  9062.  
  9063.    exception
  9064.       when others =>
  9065.          raise Math_Error;
  9066.    end Sin;
  9067.  
  9068.    pragma Page;
  9069.    -------------------------------------------------------------------
  9070.  
  9071.    function Cos (A : Float) return Float is
  9072.  
  9073.       --!-------------------------------------------------------------
  9074.       --!
  9075.       --! Name:
  9076.       --!    Cos
  9077.       --!
  9078.       --! Purpose:
  9079.       --!    This function returns the cosine of the input angle.
  9080.       --!
  9081.       --! Parameters:
  9082.       --!    A
  9083.       --!       is the angle expressed in radians.
  9084.       --!
  9085.       --! Exceptions:
  9086.       --!    Math_Error
  9087.       --!       is raised if any exception occurs.
  9088.       --!
  9089.       --! Notes:
  9090.       --!    Not applicable.
  9091.       --!
  9092.       --!-------------------------------------------------------------
  9093.  
  9094.    begin
  9095.       case Vendor is
  9096.          when Digital =>
  9097.             return Float_Math_Lib.Cos (A);
  9098.          when Telesoft =>
  9099.             return Realfunc.Cos (A);
  9100.          when Whitaker =>
  9101.             return Trig_Functions.Cos (A);
  9102.          when others =>
  9103.             return 1.0;
  9104.       end case;
  9105.  
  9106.    exception
  9107.       when others =>
  9108.          raise Math_Error;
  9109.    end Cos;
  9110.  
  9111.    pragma Page;
  9112.    -------------------------------------------------------------------
  9113.  
  9114.    function Tan (A : Float) return Float is
  9115.  
  9116.       --!-------------------------------------------------------------
  9117.       --!
  9118.       --! Name:
  9119.       --!    Tan
  9120.       --!
  9121.       --! Purpose:
  9122.       --!    This function returns the tangent of the input angle.
  9123.       --!
  9124.       --! Parameters:
  9125.       --!    A
  9126.       --!       is the angle expressed in radians.
  9127.       --!
  9128.       --! Exceptions:
  9129.       --!    Math_Error
  9130.       --!       is raised if any exception occurs.
  9131.       --!
  9132.       --! Notes:
  9133.       --!    Not applicable.
  9134.       --!
  9135.       --!-------------------------------------------------------------
  9136.  
  9137.    begin
  9138.       case Vendor is
  9139.          when Digital =>
  9140.             return Float_Math_Lib.Tan (A);
  9141.          when Telesoft =>
  9142.             raise Math_Error;
  9143.          when Whitaker =>
  9144.             return Trig_Functions.Tan (A);
  9145.          when others =>
  9146.             return 1.0;
  9147.       end case;
  9148.  
  9149.    exception
  9150.       when others =>
  9151.          raise Math_Error;
  9152.    end Tan;
  9153.  
  9154.    pragma Page;
  9155.    -------------------------------------------------------------------
  9156.  
  9157.    function Cot (A : Float) return Float is
  9158.  
  9159.       --!-------------------------------------------------------------
  9160.       --!
  9161.       --! Name:
  9162.       --!    Cot
  9163.       --!
  9164.       --! Purpose:
  9165.       --!    This function returns the cotangent of the input angle.
  9166.       --!
  9167.       --! Parameters:
  9168.       --!    A
  9169.       --!       is the angle expressed in radians.
  9170.       --!
  9171.       --! Exceptions:
  9172.       --!    Math_Error
  9173.       --!       is raised if any exception occurs.
  9174.       --!
  9175.       --! Notes:
  9176.       --!    Not applicable.
  9177.       --!
  9178.       --!-------------------------------------------------------------
  9179.  
  9180.    begin
  9181.       case Vendor is
  9182.          when Digital =>
  9183.             raise Math_Error;
  9184.          when Telesoft =>
  9185.             raise Math_Error;
  9186.          when Whitaker =>
  9187.             return Trig_Functions.Cot (A);
  9188.          when others =>
  9189.             return 1.0;
  9190.       end case;
  9191.  
  9192.    exception
  9193.       when others =>
  9194.          raise Math_Error;
  9195.    end Cot;
  9196.  
  9197.    pragma Page;
  9198.    -------------------------------------------------------------------
  9199.  
  9200.    function Asin (A : Float) return Float is
  9201.  
  9202.       --!-------------------------------------------------------------
  9203.       --!
  9204.       --! Name:
  9205.       --!    Asin
  9206.       --!
  9207.       --! Purpose:
  9208.       --!    This function returns the arcsine of the input value.
  9209.       --!
  9210.       --! Parameters:
  9211.       --!    A
  9212.       --!       is a float value.
  9213.       --!
  9214.       --! Exceptions:
  9215.       --!    Math_Error
  9216.       --!       is raised if any exception occurs.
  9217.       --!
  9218.       --! Notes:
  9219.       --!    Not applicable.
  9220.       --!
  9221.       --!-------------------------------------------------------------
  9222.  
  9223.    begin
  9224.       case Vendor is
  9225.          when Digital =>
  9226.             return Float_Math_Lib.Asin (A);
  9227.          when Telesoft =>
  9228.             raise Math_Error;
  9229.          when Whitaker =>
  9230.             return Trig_Functions.Asin (A);
  9231.          when others =>
  9232.             return 1.0;
  9233.       end case;
  9234.  
  9235.    exception
  9236.       when others =>
  9237.          raise Math_Error;
  9238.    end Asin;
  9239.  
  9240.    pragma Page;
  9241.    -------------------------------------------------------------------
  9242.  
  9243.    function Acos (A : Float) return Float is
  9244.  
  9245.       --!-------------------------------------------------------------
  9246.       --!
  9247.       --! Name:
  9248.       --!    Acos
  9249.       --!
  9250.       --! Purpose:
  9251.       --!    This function returns the arccosine of the input value.
  9252.       --!
  9253.       --! Parameters:
  9254.       --!    A
  9255.       --!       is a float value.
  9256.       --!
  9257.       --! Exceptions:
  9258.       --!    Math_Error
  9259.       --!       is raised if any exception occurs.
  9260.       --!
  9261.       --! Notes:
  9262.       --!    Not applicable.
  9263.       --!
  9264.       --!-------------------------------------------------------------
  9265.  
  9266.    begin
  9267.       case Vendor is
  9268.          when Digital =>
  9269.             return Float_Math_Lib.Acos (A);
  9270.          when Telesoft =>
  9271.             raise Math_Error;
  9272.          when Whitaker =>
  9273.             return Trig_Functions.Acos (A);
  9274.          when others =>
  9275.             return 1.0;
  9276.       end case;
  9277.  
  9278.    exception
  9279.       when others =>
  9280.          raise Math_Error;
  9281.    end Acos;
  9282.  
  9283.    pragma Page;
  9284.    -------------------------------------------------------------------
  9285.  
  9286.    function Atan (A : Float) return Float is
  9287.  
  9288.       --!-------------------------------------------------------------
  9289.       --!
  9290.       --! Name:
  9291.       --!    Atan
  9292.       --!
  9293.       --! Purpose:
  9294.       --!    This function returns the arctangent of the input value.
  9295.       --!
  9296.       --! Parameters:
  9297.       --!    A
  9298.       --!       is a float value.
  9299.       --!
  9300.       --! Exceptions:
  9301.       --!    Math_Error
  9302.       --!       is raised if any exception occurs.
  9303.       --!
  9304.       --! Notes:
  9305.       --!    Not applicable.
  9306.       --!
  9307.       --!-------------------------------------------------------------
  9308.  
  9309.    begin
  9310.       case Vendor is
  9311.          when Digital =>
  9312.             return Float_Math_Lib.Atan (A);
  9313.          when Telesoft =>
  9314.             return Realfunc.Arctan (A);
  9315.          when Whitaker =>
  9316.             return Trig_Functions.Atan (A);
  9317.          when others =>
  9318.             return 1.0;
  9319.       end case;
  9320.  
  9321.    exception
  9322.       when others =>
  9323.          raise Math_Error;
  9324.    end Atan;
  9325.  
  9326.    pragma Page;
  9327.    -------------------------------------------------------------------
  9328.  
  9329.    function Atan2 (A1, A2 : Float) return Float is
  9330.  
  9331.       --!-------------------------------------------------------------
  9332.       --!
  9333.       --! Name:
  9334.       --!    Atan2
  9335.       --!
  9336.       --! Purpose:
  9337.       --!    This function returns the arctangent of the input values.
  9338.       --!
  9339.       --! Parameters:
  9340.       --!    A1
  9341.       --!       is a float value.
  9342.       --!    A2 
  9343.       --!       is a float value.
  9344.       --!
  9345.       --! Exceptions:
  9346.       --!    Math_Error
  9347.       --!       is raised if any exception occurs.
  9348.       --!
  9349.       --! Notes:
  9350.       --!    Not applicable.
  9351.       --!
  9352.       --!-------------------------------------------------------------
  9353.  
  9354.    begin
  9355.       case Vendor is
  9356.          when Digital =>
  9357.             return Float_Math_Lib.Atan2 (A1, A2);
  9358.          when Telesoft =>
  9359.             raise Math_Error;
  9360.          when Whitaker =>
  9361.             return Trig_Functions.Atan2 (A1, A2);
  9362.          when others =>
  9363.             return 1.0;
  9364.       end case;
  9365.  
  9366.    exception
  9367.       when others =>
  9368.          raise Math_Error;
  9369.    end Atan2;
  9370.  
  9371.    pragma Page;
  9372.    -------------------------------------------------------------------
  9373.  
  9374.    function Sinh (A : Float) return Float is
  9375.  
  9376.       --!-------------------------------------------------------------
  9377.       --!
  9378.       --! Name:
  9379.       --!    Sinh
  9380.       --!
  9381.       --! Purpose:
  9382.       --!    This function returns the hyperbolic sine of the 
  9383.       --!    input angle.
  9384.       --!
  9385.       --! Parameters:
  9386.       --!    A
  9387.       --!       is a float value.
  9388.       --!
  9389.       --! Exceptions:
  9390.       --!    Math_Error
  9391.       --!       is raised if any exception occurs.
  9392.       --!
  9393.       --! Notes:
  9394.       --!    Not applicable.
  9395.       --!
  9396.       --!-------------------------------------------------------------
  9397.  
  9398.    begin
  9399.       case Vendor is
  9400.          when Digital =>
  9401.             return Float_Math_Lib.Sinh (A);
  9402.          when Telesoft =>
  9403.             raise Math_Error;
  9404.          when Whitaker =>
  9405.             return Trig_Functions.Sinh (A);
  9406.          when others =>
  9407.             return 1.0;
  9408.       end case;
  9409.  
  9410.    exception
  9411.       when others =>
  9412.          raise Math_Error;
  9413.    end Sinh;
  9414.  
  9415.    pragma Page;
  9416.    -------------------------------------------------------------------
  9417.  
  9418.    function Cosh (A : Float) return Float is
  9419.  
  9420.       --!-------------------------------------------------------------
  9421.       --!
  9422.       --! Name:
  9423.       --!    Cosh
  9424.       --!
  9425.       --! Purpose:
  9426.       --!    This function returns the hyperbolic cosine of the 
  9427.       --!    input angle.
  9428.       --!
  9429.       --! Parameters:
  9430.       --!    A
  9431.       --!       is a float value.
  9432.       --!
  9433.       --! Exceptions:
  9434.       --!    Math_Error
  9435.       --!       is raised if any exception occurs.
  9436.       --!
  9437.       --! Notes:
  9438.       --!    Not applicable.
  9439.       --!
  9440.       --!-------------------------------------------------------------
  9441.  
  9442.    begin
  9443.       case Vendor is
  9444.          when Digital =>
  9445.             return Float_Math_Lib.Cosh (A);
  9446.          when Telesoft =>
  9447.             raise Math_Error;
  9448.          when Whitaker =>
  9449.             return Trig_Functions.Cosh (A);
  9450.          when others =>
  9451.             return 1.0;
  9452.       end case;
  9453.  
  9454.    exception
  9455.       when others =>
  9456.          raise Math_Error;
  9457.    end Cosh;
  9458.  
  9459.    pragma Page;
  9460.    -------------------------------------------------------------------
  9461.  
  9462.    function Tanh (A : Float) return Float is
  9463.  
  9464.       --!-------------------------------------------------------------
  9465.       --!
  9466.       --! Name:
  9467.       --!    Tanh
  9468.       --!
  9469.       --! Purpose:
  9470.       --!    This function returns the hyperbolic tangent of the 
  9471.       --!    input angle.
  9472.       --!
  9473.       --! Parameters:
  9474.       --!    A
  9475.       --!       is a float value.
  9476.       --!
  9477.       --! Exceptions:
  9478.       --!    Math_Error
  9479.       --!       is raised if any exception occurs.
  9480.       --!
  9481.       --! Notes:
  9482.       --!    Not applicable.
  9483.       --!
  9484.       --!-------------------------------------------------------------
  9485.  
  9486.    begin
  9487.       case Vendor is
  9488.          when Digital =>
  9489.             return Float_Math_Lib.Tanh (A);
  9490.          when Telesoft =>
  9491.             raise Math_Error;
  9492.          when Whitaker =>
  9493.             return Trig_Functions.Tanh (A);
  9494.          when others =>
  9495.             return 1.0;
  9496.       end case;
  9497.  
  9498.    exception
  9499.       when others =>
  9500.          raise Math_Error;
  9501.    end Tanh;
  9502.  
  9503.    pragma Page;
  9504.    -------------------------------------------------------------------
  9505.  
  9506.    function Sind (A : Float) return Float is
  9507.  
  9508.       --!-------------------------------------------------------------
  9509.       --!
  9510.       --! Name:
  9511.       --!    Sind
  9512.       --!
  9513.       --! Purpose:
  9514.       --!    This function returns the sine of the input angle
  9515.       --!    which is expressed in degrees.
  9516.       --!
  9517.       --! Parameters:
  9518.       --!    A
  9519.       --!       is a float value.
  9520.       --!
  9521.       --! Exceptions:
  9522.       --!    Math_Error
  9523.       --!       is raised if any exception occurs.
  9524.       --!
  9525.       --! Notes:
  9526.       --!    Not applicable.
  9527.       --!
  9528.       --!-------------------------------------------------------------
  9529.  
  9530.    begin
  9531.       case Vendor is
  9532.          when Digital =>
  9533.             return Float_Math_Lib.Sind (A);
  9534.          when Telesoft =>
  9535.             raise Math_Error;
  9536.          when Whitaker =>
  9537.             raise Math_Error;
  9538.          when others =>
  9539.             return 1.0;
  9540.       end case;
  9541.  
  9542.    exception
  9543.       when others =>
  9544.          raise Math_Error;
  9545.    end Sind;
  9546.  
  9547.    pragma Page;
  9548.    -------------------------------------------------------------------
  9549.  
  9550.    function Cosd (A : Float) return Float is
  9551.  
  9552.       --!-------------------------------------------------------------
  9553.       --!
  9554.       --! Name:
  9555.       --!    Cosd
  9556.       --!
  9557.       --! Purpose:
  9558.       --!    This function returns the cosine of the input angle
  9559.       --!    which is expressed in degrees.
  9560.       --!
  9561.       --! Parameters:
  9562.       --!    A
  9563.       --!       is a float value.
  9564.       --!
  9565.       --! Exceptions:
  9566.       --!    Math_Error
  9567.       --!       is raised if any exception occurs.
  9568.       --!
  9569.       --! Notes:
  9570.       --!    Not applicable.
  9571.       --!
  9572.       --!-------------------------------------------------------------
  9573.  
  9574.    begin
  9575.       case Vendor is
  9576.          when Digital =>
  9577.             return Float_Math_Lib.Cosd (A);
  9578.          when Telesoft =>
  9579.             raise Math_Error;
  9580.          when Whitaker =>
  9581.             raise Math_Error;
  9582.          when others =>
  9583.             return 1.0;
  9584.       end case;
  9585.  
  9586.    exception
  9587.       when others =>
  9588.          raise Math_Error;
  9589.    end Cosd;
  9590.  
  9591.    pragma Page;
  9592.    -------------------------------------------------------------------
  9593.  
  9594.    function Tand (A : Float) return Float is
  9595.  
  9596.       --!-------------------------------------------------------------
  9597.       --!
  9598.       --! Name:
  9599.       --!    Tand
  9600.       --!
  9601.       --! Purpose:
  9602.       --!    This function returns the tangent of the input angle
  9603.       --!    which is expressed in degrees.
  9604.       --!
  9605.       --! Parameters:
  9606.       --!    A
  9607.       --!       is a float value.
  9608.       --!
  9609.       --! Exceptions:
  9610.       --!    Math_Error
  9611.       --!       is raised if any exception occurs.
  9612.       --!
  9613.       --! Notes:
  9614.       --!    Not applicable.
  9615.       --!
  9616.       --!-------------------------------------------------------------
  9617.  
  9618.    begin
  9619.       case Vendor is
  9620.          when Digital =>
  9621.             return Float_Math_Lib.Tand (A);
  9622.          when Telesoft =>
  9623.             raise Math_Error;
  9624.          when Whitaker =>
  9625.             raise Math_Error;
  9626.          when others =>
  9627.             return 1.0;
  9628.       end case;
  9629.  
  9630.    exception
  9631.       when others =>
  9632.          raise Math_Error;
  9633.    end Tand;
  9634.  
  9635.    pragma Page;
  9636.    -------------------------------------------------------------------
  9637.  
  9638.    function Asind (A : Float) return Float is
  9639.  
  9640.       --!-------------------------------------------------------------
  9641.       --!
  9642.       --! Name:
  9643.       --!    Asind
  9644.       --!
  9645.       --! Purpose:
  9646.       --!    This function returns an angle expressed in degrees
  9647.       --!    which is the arcsine of the input value.
  9648.       --!
  9649.       --! Parameters:
  9650.       --!    A
  9651.       --!       is a float value.
  9652.       --!
  9653.       --! Exceptions:
  9654.       --!    Math_Error
  9655.       --!       is raised if any exception occurs.
  9656.       --!
  9657.       --! Notes:
  9658.       --!    Not applicable.
  9659.       --!
  9660.       --!-------------------------------------------------------------
  9661.  
  9662.    begin
  9663.       case Vendor is
  9664.          when Digital =>
  9665.             return Float_Math_Lib.Asind (A);
  9666.          when Telesoft =>
  9667.             raise Math_Error;
  9668.          when Whitaker =>
  9669.             raise Math_Error;
  9670.          when others =>
  9671.             return 1.0;
  9672.       end case;
  9673.  
  9674.    exception
  9675.       when others =>
  9676.          raise Math_Error;
  9677.    end Asind;
  9678.  
  9679.    pragma Page;
  9680.    -------------------------------------------------------------------
  9681.  
  9682.    function Acosd (A : Float) return Float is
  9683.  
  9684.       --!-------------------------------------------------------------
  9685.       --!
  9686.       --! Name:
  9687.       --!    Acosd
  9688.       --!
  9689.       --! Purpose:
  9690.       --!    This function returns an angle expressed in degrees
  9691.       --!    which is the arccosine of the input value.
  9692.       --!
  9693.       --! Parameters:
  9694.       --!    A
  9695.       --!       is a float value.
  9696.       --!
  9697.       --! Exceptions:
  9698.       --!    Math_Error
  9699.       --!       is raised if any exception occurs.
  9700.       --!
  9701.       --! Notes:
  9702.       --!    Not applicable.
  9703.       --!
  9704.       --!-------------------------------------------------------------
  9705.  
  9706.    begin
  9707.       case Vendor is
  9708.          when Digital =>
  9709.             return Float_Math_Lib.Acosd (A);
  9710.          when Telesoft =>
  9711.             raise Math_Error;
  9712.          when Whitaker =>
  9713.             raise Math_Error;
  9714.          when others =>
  9715.             return 1.0;
  9716.       end case;
  9717.  
  9718.    exception
  9719.       when others =>
  9720.          raise Math_Error;
  9721.    end Acosd;
  9722.  
  9723.    pragma Page;
  9724.    -------------------------------------------------------------------
  9725.  
  9726.    function Atand (A : Float) return Float is
  9727.  
  9728.       --!-------------------------------------------------------------
  9729.       --!
  9730.       --! Name:
  9731.       --!    Atand
  9732.       --!
  9733.       --! Purpose:
  9734.       --!    This function returns an angle expressed in degrees
  9735.       --!    which is the arctangent of the input value.
  9736.       --!
  9737.       --! Parameters:
  9738.       --!    A
  9739.       --!       is a float value.
  9740.       --!
  9741.       --! Exceptions:
  9742.       --!    Math_Error
  9743.       --!       is raised if any exception occurs.
  9744.       --!
  9745.       --! Notes:
  9746.       --!    Not applicable.
  9747.       --!
  9748.       --!-------------------------------------------------------------
  9749.  
  9750.    begin
  9751.       case Vendor is
  9752.          when Digital =>
  9753.             return Float_Math_Lib.Atand (A);
  9754.          when Telesoft =>
  9755.             raise Math_Error;
  9756.          when Whitaker =>
  9757.             raise Math_Error;
  9758.          when others =>
  9759.             return 1.0;
  9760.       end case;
  9761.  
  9762.    exception
  9763.       when others =>
  9764.          raise Math_Error;
  9765.    end Atand;
  9766.  
  9767.    pragma Page;
  9768.    -------------------------------------------------------------------
  9769.  
  9770.    function Atan2D (A1, A2 : Float) return Float is
  9771.  
  9772.       --!-------------------------------------------------------------
  9773.       --!
  9774.       --! Name:
  9775.       --!    Atan2D
  9776.       --!
  9777.       --! Purpose:
  9778.       --!    This function returns an angle expressed in degrees
  9779.       --!    which is the arctangent of the input values.
  9780.       --!
  9781.       --! Parameters:
  9782.       --!    A1
  9783.       --!       is a float value.
  9784.       --!    A2
  9785.       --!       is a float value.
  9786.       --!
  9787.       --! Exceptions:
  9788.       --!    Math_Error
  9789.       --!       is raised if any exception occurs.
  9790.       --!
  9791.       --! Notes:
  9792.       --!    Not applicable.
  9793.       --!
  9794.       --!-------------------------------------------------------------
  9795.  
  9796.    begin
  9797.       case Vendor is
  9798.          when Digital =>
  9799.             return Float_Math_Lib.Atan2D (A1, A2);
  9800.          when Telesoft =>
  9801.             raise Math_Error;
  9802.          when Whitaker =>
  9803.             raise Math_Error;
  9804.          when others =>
  9805.             return 1.0;
  9806.       end case;
  9807.  
  9808.    exception
  9809.       when others =>
  9810.          raise Math_Error;
  9811.    end Atan2D;
  9812.  
  9813.    pragma Page;
  9814.    -------------------------------------------------------------------
  9815.  
  9816. begin
  9817.  
  9818.    if (Prompt_For_Math_Library) then
  9819.       Request_Vendor;
  9820.    end if;
  9821.  
  9822. end Kalman_Trig_Lib;
  9823. --::::::::::::::::::::::::::::
  9824. --KALMAN-UTILITIES-BODY.ADA
  9825. --::::::::::::::::::::::::::::
  9826.  
  9827. with Kalman_Trig_Lib;
  9828. with Kalman_Matrix_Lib;
  9829.  
  9830. use Kalman_Trig_Lib;
  9831. use Kalman_Matrix_Lib;
  9832.  
  9833. package body Kalman_Utilities is
  9834.  
  9835.    --!----------------------------------------------------------------
  9836.    --!
  9837.    --! Name:
  9838.    --!    Kalman_Utilities
  9839.    --!
  9840.    --! Purpose:
  9841.    --!    This package body provides a set of utilities necessary for
  9842.    --!    and specific to the Ada Kalman Filter.
  9843.    --!
  9844.    --! Exceptions:
  9845.    --!    Not applicable.
  9846.    --!
  9847.    --! Notes:
  9848.    --!    
  9849.    --!
  9850.    --! Contract:
  9851.    --!    Ada Tracking Package Using Kalman Filter Methods
  9852.    --!    Contract No. N66001-85-C-0044 (31 December 1984)
  9853.    --!
  9854.    --! Prepared for:
  9855.    --!    Naval Ocean Systems Center (WIS JPMO)
  9856.    --!    271 Catalina Blvd., Building A-33
  9857.    --!    San Diego, CA 92152
  9858.    --!
  9859.    --! Prepared by:
  9860.    --!    Software Systems Engineering
  9861.    --!    Federal Systems Group
  9862.    --!
  9863.    --!    Sanders Associates, Inc.
  9864.    --!    95 Canal Street
  9865.    --!    Nashua, NH 03061
  9866.    --!
  9867.    --! Author:
  9868.    --!    Jeffrey G. Smith
  9869.    --!
  9870.    --! Changes:
  9871.    --!    04-APR-1985
  9872.    --!       Changed Kalman_Math_Lib to Kalman_Trig_Lib because of 
  9873.    --!       TeleSoft file naming conflict with Kalman_Matrix.
  9874.    --!
  9875.    --!----------------------------------------------------------------
  9876.  
  9877.    pragma Page;
  9878.    -------------------------------------------------------------------
  9879.  
  9880.    function Convert (From : Polar_Position)
  9881.       return Cartesian_Position is
  9882.  
  9883.       --!-------------------------------------------------------------
  9884.       --!
  9885.       --! Name:
  9886.       --!    Convert
  9887.       --!
  9888.       --! Purpose:
  9889.       --!    This function converts a position expressed in Polar
  9890.       --!    coordinates (R, Theta, and Height) to a position
  9891.       --!    expressed in Cartesian coordinates (X, Y, and Z).
  9892.       --!
  9893.       --! Parameters:
  9894.       --!    From
  9895.       --!       is the Polar position (R, Theta, and Height).
  9896.       --!
  9897.       --! Exceptions:
  9898.       --!    Not applicable.
  9899.       --!
  9900.       --! Notes:
  9901.       --!    The range is assumed to be the range along the ground
  9902.       --!    and not the slant range.
  9903.       --!
  9904.       --!-------------------------------------------------------------
  9905.  
  9906.    begin
  9907.  
  9908.       return (X => From.R * Cos (From.Theta),
  9909.               Y => From.R * Sin (From.Theta),
  9910.               Z => From.Height);
  9911.  
  9912.    end Convert;
  9913.  
  9914.    pragma Page;
  9915.    -------------------------------------------------------------------
  9916.  
  9917.    function Distance
  9918.       (From : in Cartesian_Position;
  9919.        To   : in Cartesian_Position) return Float is
  9920.  
  9921.       --!-------------------------------------------------------------
  9922.       --!
  9923.       --! Name:
  9924.       --!    Distance
  9925.       --!
  9926.       --! Purpose:
  9927.       --!    This function computes the distance between two points
  9928.       --!    expressed in Cartesian coordinates.
  9929.       --!
  9930.       --! Parameters:
  9931.       --!    From
  9932.       --!       is a point expressed in Cartesian coordinates
  9933.       --!    To
  9934.       --!       is a point expressed in Cartesian coordinates
  9935.       --!
  9936.       --! Exceptions:
  9937.       --!    Not applicable.
  9938.       --!
  9939.       --! Notes:
  9940.       --!    The units of the points are assumed to be nautical miles
  9941.       --!    for X and Y components and feet for the Z component. 
  9942.       --!    Therefore, the Z value must be divided by the number of
  9943.       --!    feet per nautical mile before the distance (expressed in
  9944.       --!    nautical miles) can be computed.
  9945.       --!
  9946.       --!-------------------------------------------------------------
  9947.  
  9948.       Diff_In_X_Squared,
  9949.       Diff_In_Y_Squared,
  9950.       Diff_In_Z_Squared : Float;
  9951.  
  9952.    begin
  9953.  
  9954.       Diff_In_X_Squared := (From.X - To.X) ** 2;
  9955.       Diff_In_Y_Squared := (From.Y - To.Y) ** 2;
  9956.       Diff_In_Z_Squared := ((From.Z - To.Z) / Feet_Per_Nautical_Mile)
  9957.                             ** 2;
  9958.  
  9959.       return Sqrt (Diff_In_X_Squared +
  9960.                    Diff_In_Y_Squared +
  9961.                    Diff_In_Z_Squared);
  9962.  
  9963.    end Distance;
  9964.  
  9965.    pragma Page;
  9966.    -------------------------------------------------------------------
  9967.  
  9968.    function Distance
  9969.       (From : in Polar_Position;
  9970.        To   : in Polar_Position) return Float is
  9971.  
  9972.       --!-------------------------------------------------------------
  9973.       --!
  9974.       --! Name:
  9975.       --!    Distance
  9976.       --!
  9977.       --! Purpose:
  9978.       --!    This function computes the distance between two points
  9979.       --!    expressed in Polar coordinates.
  9980.       --!
  9981.       --! Parameters:
  9982.       --!    From
  9983.       --!       is a point expressed in Polar coordinates
  9984.       --!    To
  9985.       --!       is a point expressed in Polar coordinates
  9986.       --!
  9987.       --! Exceptions:
  9988.       --!    Not applicable.
  9989.       --!
  9990.       --! Notes:
  9991.       --!    The units of the points are assumed to be nautical miles
  9992.       --!    for R, radians for Theta, and feet for Height. Both 
  9993.       --!    points are converted to Cartesian coordinates and the
  9994.       --!    distance between them is computed by the function for
  9995.       --!    use with Cartesian coordinates.
  9996.       --!
  9997.       --!-------------------------------------------------------------
  9998.  
  9999.    begin
  10000.  
  10001.       return Distance (Convert (From), Convert (To));
  10002.  
  10003.    end Distance;
  10004.  
  10005.    pragma Page;
  10006.    -------------------------------------------------------------------
  10007.  
  10008.    function Distance
  10009.       (From : in Polar_Position;
  10010.        To   : in Cartesian_Position) return Float is
  10011.  
  10012.       --!-------------------------------------------------------------
  10013.       --!
  10014.       --! Name:
  10015.       --!    Distance
  10016.       --!
  10017.       --! Purpose:
  10018.       --!    This function computes the distance between two points
  10019.       --!    the first expressed in Polar coordinates, the latter 
  10020.       --!    expressed in Cartesian coordinates.
  10021.       --!
  10022.       --! Parameters:
  10023.       --!    From
  10024.       --!       is a point expressed in Polar coordinates
  10025.       --!    To
  10026.       --!       is a point expressed in Cartesian coordinates
  10027.       --!
  10028.       --! Exceptions:
  10029.       --!    Not applicable.
  10030.       --!
  10031.       --! Notes:
  10032.       --!    The units of the first point are assumed to be nautical 
  10033.       --!    miles for R, radians for Theta, and feet for Height. 
  10034.       --!    The units of the second point are assumed to be nautical 
  10035.       --!    miles for X and Y components and feet for the Z 
  10036.       --!    component. The first point is converted to Cartesian
  10037.       --!    coordinates and the distance is then computed by
  10038.       --!    function for use with Cartesian coordinates.
  10039.       --!
  10040.       --!-------------------------------------------------------------
  10041.  
  10042.    begin
  10043.  
  10044.       return Distance (Convert (From), To);
  10045.  
  10046.    end Distance;
  10047.  
  10048.    pragma Page;
  10049.    -------------------------------------------------------------------
  10050.  
  10051.    function Distance
  10052.       (From : in Cartesian_Position;
  10053.        To   : in Polar_Position) return Float is
  10054.  
  10055.       --!-------------------------------------------------------------
  10056.       --!
  10057.       --! Name:
  10058.       --!    Distance
  10059.       --!
  10060.       --! Purpose:
  10061.       --!    This function computes the distance between two points
  10062.       --!    the first expressed in Cartesian coordinates, the latter
  10063.       --!    expressed in Polar coordinates.
  10064.       --!
  10065.       --! Parameters:
  10066.       --!    From
  10067.       --!       is a point expressed in Cartesian coordinates
  10068.       --!    To
  10069.       --!       is a point expressed in Polar coordinates
  10070.       --!
  10071.       --! Exceptions:
  10072.       --!    Not applicable.
  10073.       --!
  10074.       --! Notes:
  10075.       --!    The units of the second point are assumed to be nautical 
  10076.       --!    miles for R, radians for Theta, and feet for Height. 
  10077.       --!    The units of the first point are assumed to be nautical 
  10078.       --!    miles for X and Y components and feet for the Z 
  10079.       --!    component. The second point is converted to Cartesian
  10080.       --!    coordinates and the distance is then computed by
  10081.       --!    function for use with Cartesian coordinates.
  10082.       --!
  10083.       --!-------------------------------------------------------------
  10084.  
  10085.    begin
  10086.  
  10087.       return Distance (From, Convert (To));
  10088.  
  10089.    end Distance;
  10090.  
  10091.    pragma Page;
  10092.    -------------------------------------------------------------------
  10093.  
  10094.    function Is_Active (Track : in Single_Track) return Boolean is
  10095.  
  10096.       --!-------------------------------------------------------------
  10097.       --!
  10098.       --! Name:
  10099.       --!    Is_Active
  10100.       --!
  10101.       --! Purpose:
  10102.       --!    This function determines whether the track stored in
  10103.       --!    the specified track record is active or not.
  10104.       --!
  10105.       --! Parameters:
  10106.       --!    Track
  10107.       --!       is a track record
  10108.       --!
  10109.       --! Exceptions:
  10110.       --!    Not applicable.
  10111.       --!
  10112.       --! Notes:
  10113.       --!    Not applicable.
  10114.       --!
  10115.       --!-------------------------------------------------------------
  10116.  
  10117.    begin
  10118.  
  10119.       if Track.State = Active then
  10120.          return True;
  10121.       else
  10122.          return False;
  10123.       end if;
  10124.  
  10125.    end Is_Active;
  10126.  
  10127.    pragma Page;
  10128.    -------------------------------------------------------------------
  10129.  
  10130.    function Make_Phi
  10131.       (Delta_Time  : in Duration)
  10132.       return State_Transition_Matrix is
  10133.  
  10134.       --!-------------------------------------------------------------
  10135.       --!
  10136.       --! Name:
  10137.       --!    Make_Phi
  10138.       --!
  10139.       --! Purpose:
  10140.       --!    This function determines a state transition matrix from
  10141.       --!    the time between two observations of a single track.
  10142.       --!
  10143.       --! Parameters:
  10144.       --!    Delta_Time
  10145.       --!       is the time between observations.
  10146.       --!
  10147.       --! Exceptions:
  10148.       --!    Not applicable.
  10149.       --!
  10150.       --! Notes:
  10151.       --!    Velocity is assumed to be constant over the
  10152.       --!    period between observations. The state vectors
  10153.       --!    are assumed to have nine components, three of position,
  10154.       --!    three of velocity, and three of acceleration.
  10155.       --!
  10156.       --!-------------------------------------------------------------
  10157.  
  10158.       Phi                   : State_Transition_Matrix;
  10159.       Delta_T               : Float := Float(Delta_Time);
  10160.       Delta_T_Squared_Div_2 : Float := (Delta_T * Delta_T) / 2.0;
  10161.  
  10162.    begin
  10163.  
  10164.       Phi := Identity (Phi);
  10165.  
  10166.       -- Using the fact that PHI is a square matrix
  10167.  
  10168.       for Index in State_Transition_Matrix'range loop
  10169.  
  10170.          if (Integer(Index) rem 3) = 1 then
  10171.  
  10172.             Phi (Index, Index + 1) := Delta_T;
  10173.  
  10174.          end if;
  10175.       end loop;
  10176.  
  10177.       return Phi;
  10178.  
  10179.    end Make_Phi;
  10180.  
  10181.    pragma Page;
  10182.    -------------------------------------------------------------------
  10183.  
  10184.    function Make_Psi
  10185.       (Location : in Polar_Location)
  10186.       return Position_Vector is
  10187.  
  10188.       --!-------------------------------------------------------------
  10189.       --!
  10190.       --! Name:
  10191.       --!    Make_Psi
  10192.       --!
  10193.       --! Purpose:
  10194.       --!    This function returns the position components of
  10195.       --!    location where location is defined to be position,
  10196.       --!    velocity, and acceleration.
  10197.       --!
  10198.       --! Parameters:
  10199.       --!    Location
  10200.       --!       is the location of the track in Polar coordinates.
  10201.       --!
  10202.       --! Exceptions:
  10203.       --!    Not applicable.
  10204.       --!
  10205.       --! Notes:
  10206.       --!    Not applicable.
  10207.       --!
  10208.       --!-------------------------------------------------------------
  10209.  
  10210.    begin
  10211.  
  10212.       return Vector'(Location.Position.R * Feet_Per_Nautical_Mile,
  10213.                      Location.Position.Theta,
  10214.                      Location.Position.Height);
  10215.  
  10216.    end Make_Psi;
  10217.  
  10218.    pragma Page;
  10219.    -------------------------------------------------------------------
  10220.  
  10221.    function Make_Psi
  10222.       (Location : in Cartesian_Location)
  10223.       return Position_Vector is
  10224.  
  10225.       --!-------------------------------------------------------------
  10226.       --!
  10227.       --! Name:
  10228.       --!    Make_Psi
  10229.       --!
  10230.       --! Purpose:
  10231.       --!    This function returns the position components of
  10232.       --!    location where location is defined to be position,
  10233.       --!    velocity, and acceleration.
  10234.       --!
  10235.       --! Parameters:
  10236.       --!    Location
  10237.       --!       is the location of the track in Cartesian coordinates.
  10238.       --!
  10239.       --! Exceptions:
  10240.       --!    Not applicable.
  10241.       --!
  10242.       --! Notes:
  10243.       --!    Not applicable.
  10244.       --!
  10245.       --!-------------------------------------------------------------
  10246.  
  10247.    begin
  10248.  
  10249.       return Vector'(Location.Position.X * Feet_Per_Nautical_Mile,
  10250.                      Location.Position.Y * Feet_Per_Nautical_Mile,
  10251.                      Location.Position.Z);
  10252.  
  10253.    end Make_Psi;
  10254.  
  10255.    pragma Page;
  10256.    -------------------------------------------------------------------
  10257.  
  10258.    function Make_Polar_Error_Covariance
  10259.       (Delta_Time : in Duration)
  10260.       return Covariance_Matrix is
  10261.  
  10262.       --!-------------------------------------------------------------
  10263.       --!
  10264.       --! Name:
  10265.       --!    Make_Polar_Error_Covariance
  10266.       --!
  10267.       --! Purpose:
  10268.       --!    This function determines the initial error covariance
  10269.       --!    matrix from the measurement covariance matrix and the
  10270.       --!    time between observations.
  10271.       --!
  10272.       --! Parameters:
  10273.       --!    Delta_Time
  10274.       --!       is the time between observations.
  10275.       --!
  10276.       --! Exceptions:
  10277.       --!    Not applicable.
  10278.       --!
  10279.       --! Notes:
  10280.       --!    The measurement covariance matrix is defined in
  10281.       --!    package Kalman_Definitions. The formula for
  10282.       --!    initial error covariance is taken from
  10283.       --!
  10284.       --!      Singer, "Estimating Optimal Tracking Filter Performance
  10285.       --!      for Manned Maneuvering Targets," IEEE Transactions
  10286.       --!      on Aerospace and Electronic Systems, Vol AES-6, No. 4,
  10287.       --!      July 1970, pages 473-483.
  10288.       --!
  10289.       --!-------------------------------------------------------------
  10290.  
  10291.       Error_Covariance : Covariance_Matrix;
  10292.       R11 : Float renames Polar_Measurement_Covariance (1,1);
  10293.       R22 : Float renames Polar_Measurement_Covariance (2,2);
  10294.       R33 : Float renames Polar_Measurement_Covariance (3,3);
  10295.  
  10296.    begin
  10297.  
  10298.       Error_Covariance := Zero (Error_Covariance);
  10299.  
  10300.       Error_Covariance (1,1) := R11;
  10301.       Error_Covariance (1,2) := R11 / Float (Delta_Time);
  10302.       Error_Covariance (2,1) := Error_Covariance (1,2);
  10303.       Error_Covariance (2,2) := 2.0 * R11 / (Float (Delta_Time) ** 2);
  10304.  
  10305.       Error_Covariance (4,4) := R22;
  10306.       Error_Covariance (4,5) := R22 / Float (Delta_Time);
  10307.       Error_Covariance (5,4) := Error_Covariance (4,5);
  10308.       Error_Covariance (5,5) := 2.0 * R22 / (Float (Delta_Time) ** 2);
  10309.  
  10310.       Error_Covariance (7,7) := R33;
  10311.       Error_Covariance (7,8) := R33 / Float (Delta_Time);
  10312.       Error_Covariance (8,7) := Error_Covariance (7,8);
  10313.       Error_Covariance (8,8) := 2.0 * R33 / (Float (Delta_Time) ** 2);
  10314.  
  10315.       return Error_Covariance;
  10316.  
  10317.    end Make_Polar_Error_Covariance;
  10318.  
  10319.    pragma Page;
  10320.    -------------------------------------------------------------------
  10321.  
  10322.    function Make_Xyz_Error_Covariance
  10323.       (Delta_Time : in Duration)
  10324.       return Covariance_Matrix is
  10325.  
  10326.       --!-------------------------------------------------------------
  10327.       --!
  10328.       --! Name:
  10329.       --!    Make_XYZ_Error_Covariance
  10330.       --!
  10331.       --! Purpose:
  10332.       --!    This function determines the initial error covariance
  10333.       --!    matrix from the measurement covariance matrix and the
  10334.       --!    time between observations.
  10335.       --!
  10336.       --! Parameters:
  10337.       --!    Delta_Time
  10338.       --!       is the time between observations.
  10339.       --!
  10340.       --! Exceptions:
  10341.       --!    Not applicable.
  10342.       --!
  10343.       --! Notes:
  10344.       --!    The measurement covariance matrix is defined in
  10345.       --!    package Kalman_Definitions. The formula for
  10346.       --!    initial error covariance is taken from
  10347.       --!
  10348.       --!      Singer, "Estimating Optimal Tracking Filter Performance
  10349.       --!      for Manned Maneuvering Targets," IEEE Transactions
  10350.       --!      on Aerospace and Electronic Systems, Vol AES-6, No. 4,
  10351.       --!      July 1970, pages 473-483.
  10352.       --!
  10353.       --!-------------------------------------------------------------
  10354.  
  10355.       Error_Covariance : Covariance_Matrix;
  10356.       R11 : Float renames Cartesian_Measurement_Covariance (1,1);
  10357.       R22 : Float renames Cartesian_Measurement_Covariance (2,2);
  10358.       R33 : Float renames Cartesian_Measurement_Covariance (3,3);
  10359.  
  10360.    begin
  10361.  
  10362.       Error_Covariance := Zero (Error_Covariance);
  10363.  
  10364.       Error_Covariance (1,1) := R11;
  10365.       Error_Covariance (1,2) := R11 / Float (Delta_Time);
  10366.       Error_Covariance (2,1) := Error_Covariance (1,2);
  10367.       Error_Covariance (2,2) := 2.0 * R11 / (Float (Delta_Time) ** 2);
  10368.  
  10369.       Error_Covariance (4,4) := R22;
  10370.       Error_Covariance (4,5) := R22 / Float (Delta_Time);
  10371.       Error_Covariance (5,4) := Error_Covariance (4,5);
  10372.       Error_Covariance (5,5) := 2.0 * R22 / (Float (Delta_Time) ** 2);
  10373.  
  10374.       Error_Covariance (7,7) := R33;
  10375.       Error_Covariance (7,8) := R33 / Float (Delta_Time);
  10376.       Error_Covariance (8,7) := Error_Covariance (7,8);
  10377.       Error_Covariance (8,8) := 2.0 * R33 / (Float (Delta_Time) ** 2);
  10378.  
  10379.       return Error_Covariance;
  10380.  
  10381.    end Make_Xyz_Error_Covariance;
  10382.  
  10383. end Kalman_Utilities;
  10384. --::::::::::::::::::::::::::::
  10385. --KALMAN-FUNCTIONS-SPEC.ADA
  10386. --::::::::::::::::::::::::::::
  10387.  
  10388. with Calendar;
  10389. with Kalman_Definitions;
  10390.  
  10391. use Calendar;
  10392. use Kalman_Definitions;
  10393.  
  10394. package Kalman_Functions is
  10395.  
  10396.    --!----------------------------------------------------------------
  10397.    --!
  10398.    --! Name:
  10399.    --!   Kalman_Functions
  10400.    --!
  10401.    --! Purpose:
  10402.    --!   This package implements the basic Kalman Filter functions
  10403.    --!   of Initiate, Update, and Filter.
  10404.    --!
  10405.    --! Interfaces:
  10406.    --!    Initiate
  10407.    --!       initializes the Smoothed location from the
  10408.    --!       observed Location.
  10409.    --!
  10410.    --!    Update
  10411.    --!       initializes the Smoothed location, Error_Covariance,
  10412.    --!       and Maneuver_Detector constant from the previous
  10413.    --!       Smoothed location and the observed Location.
  10414.    --!
  10415.    --!    Filter
  10416.    --!       determines the best estimate of the current position
  10417.    --!       of the track based on the observed Location and
  10418.    --!       the previous Smoothed position and Error_Covariance.
  10419.    --!
  10420.    --! Exceptions:
  10421.    --!    Not applicable.
  10422.    --!
  10423.    --! Notes:
  10424.    --!    The Kalman Filter functions should be called in the
  10425.    --!    following order for any given track:
  10426.    --!       Initiate, Update, Filter, Filter, ...
  10427.    --!
  10428.    --! Contract:
  10429.    --!    Ada Tracking Package Using Kalman Filter Methods
  10430.    --!    Contract No. N66001-85-C-0044 (31 December 1984)
  10431.    --!
  10432.    --! Prepared for:
  10433.    --!    Naval Ocean Systems Center (WIS JPMO)
  10434.    --!    271 Catalina Blvd., Building A-33
  10435.    --!    San Diego, CA 92152
  10436.    --!
  10437.    --! Prepared by:
  10438.    --!    Software Systems Engineering
  10439.    --!    Federal Systems Group
  10440.    --!
  10441.    --!    Sanders Associates, Inc.
  10442.    --!    95 Canal Street
  10443.    --!    Nashua, NH 03061
  10444.    --!
  10445.    --! Author:
  10446.    --!    Jeffrey G. Smith
  10447.    --!
  10448.    --!----------------------------------------------------------------
  10449.  
  10450.    procedure Initiate
  10451.       (Location           : in     Cartesian_Location;
  10452.        Observed_Time      : in     Time;
  10453.        Smoothed           : in out Location_Vector;
  10454.        Last_Observed_Time :    out Time;
  10455.        Predicted          :    out Location_Vector);
  10456.  
  10457.    procedure Initiate
  10458.       (Location           : in     Polar_Location;
  10459.        Observed_Time      : in     Time;
  10460.        Smoothed           : in out Location_Vector;
  10461.        Last_Observed_Time :    out Time;
  10462.        Predicted          :    out Location_Vector);
  10463.  
  10464.    -------------------------------------------------------------------
  10465.  
  10466.    procedure Update
  10467.       (Location           : in     Cartesian_Location;
  10468.        Observed_Time      : in     Time;
  10469.        Smoothed           : in out Location_Vector;
  10470.        Last_Observed_Time : in out Time;
  10471.        Error_Covariance   : in out Covariance_Matrix;
  10472.        Predicted          : in out Location_Vector;
  10473.        Maneuver_Detector  : in out Float);
  10474.  
  10475.    procedure Update
  10476.       (Location           : in     Polar_Location;
  10477.        Observed_Time      : in     Time;
  10478.        Smoothed           : in out Location_Vector;
  10479.        Last_Observed_Time : in out Time;
  10480.        Error_Covariance   : in out Covariance_Matrix;
  10481.        Predicted          : in out Location_Vector;
  10482.        Maneuver_Detector  : in out Float);
  10483.  
  10484.    -------------------------------------------------------------------
  10485.  
  10486.    procedure Filter
  10487.       (Location           : in     Cartesian_Location;
  10488.        Observed_Time      : in     Time;
  10489.        Maneuver_Detector  : in     Float;
  10490.        Smoothed           : in out Location_Vector;
  10491.        Last_Observed_Time : in out Time;
  10492.        Error_Covariance   : in out Covariance_Matrix;
  10493.        Predicted          : in out Location_Vector;
  10494.        Maneuver_Indicator : in out Float);
  10495.  
  10496.    procedure Filter
  10497.       (Location           : in     Polar_Location;
  10498.        Observed_Time      : in     Time;
  10499.        Maneuver_Detector  : in     Float;
  10500.        Smoothed           : in out Location_Vector;
  10501.        Last_Observed_Time : in out Time;
  10502.        Error_Covariance   : in out Covariance_Matrix;
  10503.        Predicted          : in out Location_Vector;
  10504.        Maneuver_Indicator : in out Float);
  10505.  
  10506.    -------------------------------------------------------------------
  10507.  
  10508.    procedure Filter
  10509.       (Location           : in     Cartesian_Location;
  10510.        Observed_Time      : in     Time;
  10511.        Maneuver_Detector  : in     Float;
  10512.        Smoothed           : in out Location_Vector;
  10513.        Last_Observed_Time : in out Time;
  10514.        Error_Covariance   : in out Covariance_Matrix;
  10515.        Predicted          : in out Location_Vector;
  10516.        Maneuver_Indicator : in out Float;
  10517.        Cpu_Time           :    out Duration;
  10518.        Real_Time          :    out Duration);
  10519.  
  10520.    procedure Filter
  10521.       (Location           : in     Polar_Location;
  10522.        Observed_Time      : in     Time;
  10523.        Maneuver_Detector  : in     Float;
  10524.        Smoothed           : in out Location_Vector;
  10525.        Last_Observed_Time : in out Time;
  10526.        Error_Covariance   : in out Covariance_Matrix;
  10527.        Predicted          : in out Location_Vector;
  10528.        Maneuver_Indicator : in out Float;
  10529.        Cpu_Time           :    out Duration;
  10530.        Real_Time          :    out Duration);
  10531.  
  10532. end Kalman_Functions;
  10533. --::::::::::::::::::::::::::::
  10534. --KALMAN-FUNCTIONS-BODY.ADA
  10535. --::::::::::::::::::::::::::::
  10536.  
  10537. with Kalman_Options;
  10538. with Kalman_Definitions;
  10539. with Kalman_Status;
  10540. with Kalman_Threshold;
  10541. with Kalman_Matrix_Lib;
  10542. with Kalman_Utilities;
  10543. with Kalman_Time;
  10544.  
  10545. use Kalman_Options;
  10546. use Kalman_Definitions;
  10547. use Kalman_Status;
  10548. use Kalman_Threshold;
  10549. use Kalman_Matrix_Lib;
  10550. use Kalman_Utilities;
  10551. use Kalman_Time;
  10552.  
  10553. package body Kalman_Functions is
  10554.  
  10555.    --!----------------------------------------------------------------
  10556.    --!
  10557.    --! Name:
  10558.    --!    Kalman_Functions
  10559.    --!
  10560.    --! Purpose:
  10561.    --!    This package body implements the basic Kalman Filter
  10562.    --!    functions of Initiate, Update, and Filter.
  10563.    --!
  10564.    --! Exceptions:
  10565.    --!    Not applicable.
  10566.    --!
  10567.    --! Notes:
  10568.    --!    The Kalman Filter functions should be called in the
  10569.    --!    following order for any given track:
  10570.    --!       Initiate, Update, Filter, Filter, ...
  10571.    --!
  10572.    --!    The Kalman Filter functions are overloaded to accept
  10573.    --!    input in either Polar or Cartesian coordinates. The 
  10574.    --!    Filter function is further overloaded to provide performance
  10575.    --!    information.
  10576.    --!
  10577.    --! Contract:
  10578.    --!    Ada Tracking Package Using Kalman Filter Methods
  10579.    --!    Contract No. N66001-85-C-0044 (31 December 1984)
  10580.    --!
  10581.    --! Prepared for:
  10582.    --!    Naval Ocean Systems Center (WIS JPMO)
  10583.    --!    271 Catalina Blvd., Building A-33
  10584.    --!    San Diego, CA 92152
  10585.    --!
  10586.    --! Prepared by:
  10587.    --!    Software Systems Engineering
  10588.    --!    Federal Systems Group
  10589.    --!
  10590.    --!    Sanders Associates, Inc.
  10591.    --!    95 Canal Street
  10592.    --!    Nashua, NH 03061
  10593.    --!
  10594.    --! Author:
  10595.    --!    Jeffrey G. Smith
  10596.    --!
  10597.    --! Changes:
  10598.    --!    04-APR-1985
  10599.    --!       Changed Kalman_Trace to Kalman_Threshold because of 
  10600.    --!       TeleSoft file naming conflict with Kalman_Track.
  10601.    --!
  10602.    --!    23-APR-1985
  10603.    --!       Scale white noise matrix Q for Theta by R ** 2
  10604.    --!
  10605.    --!    24-APR-1985
  10606.    --!       Add "Execute_Debug_Code" flag around status call
  10607.    --!       in fix of 23-APR-1985.
  10608.    --!
  10609.    --!    29-APR-1985
  10610.    --!       Changed debug threshold on Status call in package
  10611.    --!       initialization to "Nothing".
  10612.    --!
  10613.    --!----------------------------------------------------------------
  10614.  
  10615.    Pid : Package_Id;
  10616.  
  10617.    procedure Initiate
  10618.       (Location           : in     Cartesian_Location;
  10619.        Observed_Time      : in     Time;
  10620.        Smoothed           : in out Location_Vector;
  10621.        Last_Observed_Time :    out Time;
  10622.        Predicted          :    out Location_Vector) is
  10623.  
  10624.       --!-------------------------------------------------------------
  10625.       --!
  10626.       --! Name:
  10627.       --!    Initiate
  10628.       --!
  10629.       --! Purpose:
  10630.       --!    This procedure initializes the Smoothed location from
  10631.       --!    the observed Location.
  10632.       --!
  10633.       --! Parameters:
  10634.       --!    Location
  10635.       --!       is the observed Location expressed in Cartesian
  10636.       --!       coordinates (X in nautical miles, Y in nautical miles,
  10637.       --!       Z in feet).
  10638.       --!    Observed_Time
  10639.       --!       is the time at which the hit was recorded. 
  10640.       --!    Smoothed
  10641.       --!       is the initial position of the track in Cartesian
  10642.       --!       coordinates (X, Y, Z in feet, velocity in feet per 
  10643.       --!       second, acceleration in feet per second squared).
  10644.       --!    Last_Observed_Time
  10645.       --!       is the time at which the hit was recorded.
  10646.       --!    Predicted
  10647.       --!       is the initial position of the track in Cartesian
  10648.       --!       coordinates (X, Y, Z in feet, velocity in feet per 
  10649.       --!       second, acceleration in feet per second squared).
  10650.       --!
  10651.       --! Exceptions:
  10652.       --!    Not applicable.
  10653.       --!
  10654.       --! Notes:
  10655.       --!    The Smoothed location is simply the observed Location
  10656.       --!    with nautical miles converted to feet. The Predicted 
  10657.       --!    location is the same as the Smoothed location. The
  10658.       --!    Last_Observed_Time is the same as the Observed_Time.
  10659.       --!    The Initiate procedure should be called when a 
  10660.       --!    correlation algorithm has determined that the observed
  10661.       --!    Location does not correspond to any existing track.
  10662.       --!
  10663.       --!-------------------------------------------------------------
  10664.  
  10665.    begin
  10666.  
  10667.       if (Execute_Debug_Code) then
  10668.          Status (Pid, Entry_Exit,
  10669.                  "--> Entry to procedure " &
  10670.                  "Kalman_Functions.Initiate (Cartesian)");
  10671.       end if;
  10672.  
  10673.       Smoothed := Vector' (Location.Position.X *
  10674.                            Feet_Per_Nautical_Mile,
  10675.                            Location.Velocity.X *
  10676.                            Feet_Per_Nautical_Mile /
  10677.                            Seconds_Per_Hour,
  10678.                            Location.Acceleration.X *
  10679.                            Feet_Per_Nautical_Mile /
  10680.                            (Seconds_Per_Hour ** 2),
  10681.  
  10682.                            Location.Position.Y *
  10683.                            Feet_Per_Nautical_Mile,
  10684.                            Location.Velocity.Y *
  10685.                            Feet_Per_Nautical_Mile /
  10686.                            Seconds_Per_Hour,
  10687.                            Location.Acceleration.Y *
  10688.                            Feet_Per_Nautical_Mile /
  10689.                            (Seconds_Per_Hour ** 2),
  10690.  
  10691.                            Location.Position.Z,
  10692.                            Location.Velocity.Z,
  10693.                            Location.Acceleration.Z);
  10694.  
  10695.       Last_Observed_Time := Observed_Time;
  10696.  
  10697.       Predicted := Smoothed;
  10698.  
  10699.       if (Execute_Debug_Code) then
  10700.          Status (Pid, Parameters,
  10701.                  "At exit, Smoothed Location ",
  10702.                  Smoothed);
  10703.          Status (Pid, Entry_Exit,
  10704.                  "<-- Exit from procedure " &
  10705.                  "Kalman_Functions.Initiate (Cartesian)");
  10706.       end if;
  10707.  
  10708.    end Initiate;
  10709.  
  10710.    pragma Page;
  10711.    -------------------------------------------------------------------
  10712.  
  10713.    procedure Initiate
  10714.       (Location           : in     Polar_Location;
  10715.        Observed_Time      : in     Time;
  10716.        Smoothed           : in out Location_Vector;
  10717.        Last_Observed_Time :    out Time;
  10718.        Predicted          :    out Location_Vector) is
  10719.  
  10720.       --!-------------------------------------------------------------
  10721.       --!
  10722.       --! Name:
  10723.       --!    Initiate
  10724.       --!
  10725.       --! Purpose:
  10726.       --!    This procedure initializes the Smoothed location from
  10727.       --!    the observed Location.
  10728.       --!
  10729.       --! Parameters:
  10730.       --!    Location
  10731.       --!       is the observed Location expressed in Polar
  10732.       --!       coordinates (R in nautical miles, Theta in radians,
  10733.       --!       Height in feet).
  10734.       --!    Observed_Time
  10735.       --!       is the time at which the hit was recorded. 
  10736.       --!    Smoothed
  10737.       --!       is the initial position of the track in Polar
  10738.       --!       coordinates (R, Height in feet, velocity in feet per 
  10739.       --!       second, acceleration in feet per second squared,
  10740.       --!       Theta in radians, velocity in radians per second,
  10741.       --!       acceleration in radians per second squared).
  10742.       --!    Last_Observed_Time
  10743.       --!       is the time at which the hit was recorded.
  10744.       --!    Predicted
  10745.       --!       is the initial position of the track in Polar
  10746.       --!       coordinates (R, Height in feet, velocity in feet per 
  10747.       --!       second, acceleration in feet per second squared,
  10748.       --!       Theta in radians, velocity in radians per second,
  10749.       --!       acceleration in radians per second squared).
  10750.       --!
  10751.       --! Exceptions:
  10752.       --!    Not applicable.
  10753.       --!
  10754.       --! Notes:
  10755.       --!    The Smoothed location is simply the observed Location
  10756.       --!    with nautical miles converted to feet. The Predicted 
  10757.       --!    location is the same as the Smoothed location. The
  10758.       --!    Last_Observed_Time is the same as the Observed_Time.
  10759.       --!    The Initiate procedure should be called when a 
  10760.       --!    correlation algorithm has determined that the observed
  10761.       --!    Location does not correspond to any existing track.
  10762.       --!
  10763.       --!-------------------------------------------------------------
  10764.  
  10765.    begin
  10766.  
  10767.       if (Execute_Debug_Code) then
  10768.          Status (Pid, Entry_Exit,
  10769.                  "--> Entry to procedure " &
  10770.                  "Kalman_Functions.Initiate (Polar)");
  10771.       end if;
  10772.  
  10773.       Smoothed := Vector' (Location.Position.R *
  10774.                            Feet_Per_Nautical_Mile,
  10775.                            Location.Velocity.R *
  10776.                            Feet_Per_Nautical_Mile /
  10777.                            Seconds_Per_Hour,
  10778.                            Location.Acceleration.R *
  10779.                            Feet_Per_Nautical_Mile /
  10780.                            (Seconds_Per_Hour ** 2),
  10781.  
  10782.                            Location.Position.Theta,
  10783.                            Location.Velocity.Theta,
  10784.                            Location.Acceleration.Theta,
  10785.  
  10786.                            Location.Position.Height,
  10787.                            Location.Velocity.Height,
  10788.                            Location.Acceleration.Height);
  10789.  
  10790.       Last_Observed_Time := Observed_Time;
  10791.  
  10792.       Predicted := Smoothed;
  10793.  
  10794.       if (Execute_Debug_Code) then
  10795.          Status (Pid, Parameters,
  10796.                  "At exit, Smoothed Location ",
  10797.                  Smoothed);
  10798.          Status (Pid, Entry_Exit,
  10799.                  "<-- Exit from procedure " &
  10800.                  "Kalman_Functions.Initiate (Polar)");
  10801.       end if;
  10802.  
  10803.    end Initiate;
  10804.  
  10805.    pragma Page;
  10806.    -------------------------------------------------------------------
  10807.  
  10808.    procedure Update
  10809.       (Location           : in     Cartesian_Location;
  10810.        Observed_Time      : in     Time;
  10811.        Smoothed           : in out Location_Vector;
  10812.        Last_Observed_Time : in out Time;
  10813.        Error_Covariance   : in out Covariance_Matrix;
  10814.        Predicted          : in out Location_Vector;
  10815.        Maneuver_Detector  : in out Float) is
  10816.  
  10817.       --!-------------------------------------------------------------
  10818.       --!
  10819.       --! Name:
  10820.       --!    Update
  10821.       --!
  10822.       --! Purpose:
  10823.       --!    This procedure initializes the Smoothed location,
  10824.       --!    Error_Covariance, and Maneuver_Detector from the
  10825.       --!    previous Smoothed location and the observed Location.
  10826.       --!
  10827.       --! Parameters:
  10828.       --!    Location
  10829.       --!       is the observed Location expressed in Cartesian
  10830.       --!       coordinates (X in nautical miles, Y in nautical miles,
  10831.       --!       Z in feet).
  10832.       --!    Observed_Time
  10833.       --!       is the time at which the hit was recorded. 
  10834.       --!    Smoothed (on input)
  10835.       --!       is the previous position of the track in Cartesian
  10836.       --!       coordinates (X, Y, Z in feet, velocity in feet per 
  10837.       --!       second, acceleration in feet per second squared).
  10838.       --!    Smoothed (on output)
  10839.       --!       is the updated position of the track in Cartesian
  10840.       --!       coordinates (X, Y, Z in feet, velocity in feet per 
  10841.       --!       second, acceleration in feet per second squared).
  10842.       --!    Last_Observed_Time (on input)
  10843.       --!       is the time at which the previous hit was recorded.
  10844.       --!    Last_Observed_Time (on output)
  10845.       --!       is the time at which the hit was recorded.
  10846.       --!    Error Covariance
  10847.       --!       is the initial error covariance matrix which is
  10848.       --!       based on the measurement covariance and the delta
  10849.       --!       time.
  10850.       --!    Predicted
  10851.       --!       is the initial position of the track in Cartesian
  10852.       --!       coordinates (X, Y, Z in feet, velocity in feet per 
  10853.       --!       second, acceleration in feet per second squared).
  10854.       --!    Maneuver_Detector
  10855.       --!       is the initial white noise matrix constant which
  10856.       --!       is used by the Filter function to determine the amount
  10857.       --!       of credibility in the observed Location.
  10858.       --!
  10859.       --! Exceptions:
  10860.       --!    Not applicable.
  10861.       --!
  10862.       --! Notes:
  10863.       --!    The velocity is computed by the Update function unless
  10864.       --!    it was included in the observed Location passed to the
  10865.       --!    Initiate function.
  10866.       --!
  10867.       --!-------------------------------------------------------------
  10868.  
  10869.       Delta_Time  : Duration;
  10870.       Phi         : State_Transition_Matrix;
  10871.  
  10872.    begin
  10873.  
  10874.       if (Execute_Debug_Code) then
  10875.          Status (Pid, Entry_Exit,
  10876.                  "--> Entry to procedure " &
  10877.                  "Kalman_Functions.Update (Cartesian)");
  10878.          Status (Pid, Parameters,
  10879.                  "At entry, Smoothed Location ",
  10880.                  Smoothed);
  10881.       end if;
  10882.  
  10883.       -- Compute the time between observations.
  10884.  
  10885.       Delta_Time := Observed_Time - Last_Observed_Time;
  10886.       if (Execute_Debug_Code) then
  10887.          Status (Pid, Internals,
  10888.                  "Delta Time ", Float(Delta_Time));
  10889.       end if;
  10890.  
  10891.       -- Compute the state transition matrix.
  10892.  
  10893.       Phi := Make_Phi (Delta_Time);
  10894.  
  10895.       if (Execute_Debug_Code) then
  10896.          Status (Pid, Internals,
  10897.                  "State Transition matrix ", Phi);
  10898.       end if;
  10899.  
  10900.       --                                 P          S
  10901.       -- Compute the predicted location X  = PHI * X   .
  10902.       --                                            k-1
  10903.  
  10904.       if (Use_Fast_Matrix_Operations) then
  10905.          Predicted (1) := Smoothed (1) +
  10906.                           (Float (Delta_Time) * Smoothed (2));
  10907.          Predicted (2) := Smoothed (2);
  10908.          Predicted (3) := Smoothed (3);
  10909.          Predicted (4) := Smoothed (4) +
  10910.                           (Float (Delta_Time) * Smoothed (5));
  10911.          Predicted (5) := Smoothed (5);
  10912.          Predicted (6) := Smoothed (6);
  10913.          Predicted (7) := Smoothed (7) +
  10914.                           (Float (Delta_Time) * Smoothed (8));
  10915.          Predicted (8) := Smoothed (8);
  10916.          Predicted (9) := Smoothed (9);
  10917.       else
  10918.          Predicted := To_Vector (Phi * Smoothed);
  10919.       end if;
  10920.  
  10921.       -- Initialize the maneuver detector constant and
  10922.       --   the error covariance matrix.
  10923.  
  10924.       Maneuver_Detector := Initial_Cartesian_Maneuver_Detector;
  10925.       Error_Covariance 
  10926.          := Make_Xyz_Error_Covariance (Delta_Time);
  10927.  
  10928.       -- Update the last observation time.
  10929.  
  10930.       Last_Observed_Time := Observed_Time;
  10931.  
  10932.       -- Compute the smoothed location:
  10933.       --   initialize position components 
  10934.       --   to observed position components,
  10935.       --   compute initial velocity,
  10936.       --   initialize acceleration components 
  10937.       --   to observed acceleration components,
  10938.  
  10939.       if Location.Velocity = Null_Cartesian_Velocity then
  10940.  
  10941.          Smoothed 
  10942.             := Vector'
  10943.                (Location.Position.X * Feet_Per_Nautical_Mile,
  10944.                 ((Location.Position.X * Feet_Per_Nautical_Mile)
  10945.                  - Smoothed (1)) / Float(Delta_Time),
  10946.                 Location.Acceleration.X,
  10947.  
  10948.                 Location.Position.Y * Feet_Per_Nautical_Mile,
  10949.                 ((Location.Position.Y * Feet_Per_Nautical_Mile)
  10950.                  - Smoothed (4)) / Float(Delta_Time),
  10951.                 Location.Acceleration.Y,
  10952.  
  10953.                 Location.Position.Z,
  10954.                 (Location.Position.Z - Smoothed (7)) /
  10955.                 Float(Delta_Time),
  10956.                 Location.Acceleration.Z);
  10957.       else
  10958.          Smoothed 
  10959.             := Vector'
  10960.                (Location.Position.X * Feet_Per_Nautical_Mile,
  10961.                 Location.Velocity.X * Feet_Per_Nautical_Mile /
  10962.                 Seconds_Per_Hour,
  10963.                 Location.Acceleration.X *
  10964.                 Feet_Per_Nautical_Mile /
  10965.                 (Seconds_Per_Hour ** 2),
  10966.  
  10967.                 Location.Position.Y * Feet_Per_Nautical_Mile,
  10968.                 Location.Velocity.Y * Feet_Per_Nautical_Mile /
  10969.                 Seconds_Per_Hour,
  10970.                 Location.Acceleration.Y *
  10971.                 Feet_Per_Nautical_Mile /
  10972.                 (Seconds_Per_Hour ** 2),
  10973.  
  10974.                 Location.Position.Z,
  10975.                 Location.Velocity.Z,
  10976.                 Location.Acceleration.Z);
  10977.       end if;
  10978.  
  10979.       if (Execute_Debug_Code) then
  10980.          Status (Pid, Parameters,
  10981.                  "At exit, Smoothed Location ",
  10982.                  Smoothed);
  10983.          Status (Pid, Parameters,
  10984.                  "Predicted Location ", Predicted);
  10985.          Status (Pid, Parameters,
  10986.                  "Error Covariance ", Error_Covariance);
  10987.          Status (Pid, Parameters,
  10988.                  "Maneuver Detector ", Maneuver_Detector);
  10989.          Status (Pid, Entry_Exit,
  10990.                  "<-- Exit from procedure " &
  10991.                  "Kalman_Functions.Update (Cartesian)");
  10992.       end if;
  10993.  
  10994.    end Update;
  10995.  
  10996.    pragma Page;
  10997.    -------------------------------------------------------------------
  10998.  
  10999.    procedure Update
  11000.       (Location           : in     Polar_Location;
  11001.        Observed_Time      : in     Time;
  11002.        Smoothed           : in out Location_Vector;
  11003.        Last_Observed_Time : in out Time;
  11004.        Error_Covariance   : in out Covariance_Matrix;
  11005.        Predicted          : in out Location_Vector;
  11006.        Maneuver_Detector  : in out Float) is
  11007.  
  11008.       --!-------------------------------------------------------------
  11009.       --!
  11010.       --! Name:
  11011.       --!    Update
  11012.       --!
  11013.       --! Purpose:
  11014.       --!    This procedure initializes the Smoothed location,
  11015.       --!    Error_Covariance, and Maneuver_Detector from the
  11016.       --!    previous Smoothed location and the observed Location.
  11017.       --!
  11018.       --! Parameters:
  11019.       --!    Location
  11020.       --!       is the observed Location expressed in Polar
  11021.       --!       coordinates (R in nautical miles, Theta in radians,
  11022.       --!       Height in feet).
  11023.       --!    Observed_Time
  11024.       --!       is the time at which the hit was recorded. 
  11025.       --!    Smoothed (on input)
  11026.       --!       is the previous position of the track in Polar
  11027.       --!       coordinates (R, and Height in feet, velocity in feet 
  11028.       --!       per second, acceleration in feet per second squared,
  11029.       --!       Theta in radians, velocity in radians per second,
  11030.       --!       acceleration in radians per second squared).
  11031.       --!    Smoothed (on output)
  11032.       --!       is the current position of the track in Polar
  11033.       --!       coordinates (R, and Height in feet, velocity in feet 
  11034.       --!       per second, acceleration in feet per second squared,
  11035.       --!       Theta in radians, velocity in radians per second,
  11036.       --!       acceleration in radians per second squared).
  11037.       --!    Last_Observed_Time (on input)
  11038.       --!       is the time at which the previous hit was recorded.
  11039.       --!    Last_Observed_Time (on output)
  11040.       --!       is the time at which the hit was recorded.
  11041.       --!    Error Covariance
  11042.       --!       is the initial error covariance matrix which is
  11043.       --!       based on the measurement covariance and the delta
  11044.       --!       time.
  11045.       --!    Predicted
  11046.       --!       is the predicted position of the track in Polar
  11047.       --!       coordinates (R, and Height in feet, velocity in feet 
  11048.       --!       per second, acceleration in feet per second squared,
  11049.       --!       Theta in radians, velocity in radians per second,
  11050.       --!       acceleration in radians per second squared).
  11051.       --!    Maneuver_Detector
  11052.       --!       is the initial white noise matrix constant which
  11053.       --!       is used by the Filter function to determine the amount
  11054.       --!       of credibility in the observed Location.
  11055.       --!
  11056.       --! Exceptions:
  11057.       --!    Not applicable.
  11058.       --!
  11059.       --! Notes:
  11060.       --!    The velocity is computed by the Update function unless
  11061.       --!    it was included in the observed Location passed to the
  11062.       --!    Initiate function.
  11063.       --!
  11064.       --!-------------------------------------------------------------
  11065.  
  11066.       Delta_Time  : Duration;
  11067.       Phi         : State_Transition_Matrix;
  11068.  
  11069.    begin
  11070.  
  11071.       if (Execute_Debug_Code) then
  11072.          Status (Pid, Entry_Exit,
  11073.                  "--> Entry to procedure " &
  11074.                  "Kalman_Functions.Update (Polar)");
  11075.          Status (Pid, Parameters,
  11076.                  "At entry, Smoothed Location ",
  11077.                  Smoothed);
  11078.       end if;
  11079.  
  11080.       -- Compute the time between observations.
  11081.  
  11082.       Delta_Time := Observed_Time - Last_Observed_Time;
  11083.  
  11084.       if (Execute_Debug_Code) then
  11085.          Status (Pid, Internals,
  11086.                  "Delta Time ", Float(Delta_Time));
  11087.       end if;
  11088.  
  11089.       -- Compute the state transition matrix.
  11090.  
  11091.       Phi := Make_Phi (Delta_Time);
  11092.  
  11093.       if (Execute_Debug_Code) then
  11094.          Status (Pid, Internals,
  11095.                  "State Transition matrix ", Phi);
  11096.       end if;
  11097.  
  11098.       --                                 P          S
  11099.       -- Compute the predicted location X  = PHI * X   .
  11100.       --                                            k-1
  11101.  
  11102.       if (Use_Fast_Matrix_Operations) then
  11103.          Predicted (1) := Smoothed (1) +
  11104.                           (Float (Delta_Time) * Smoothed (2));
  11105.          Predicted (2) := Smoothed (2);
  11106.          Predicted (3) := Smoothed (3);
  11107.          Predicted (4) := Smoothed (4) +
  11108.                           (Float (Delta_Time) * Smoothed (5));
  11109.          Predicted (5) := Smoothed (5);
  11110.          Predicted (6) := Smoothed (6);
  11111.          Predicted (7) := Smoothed (7) +
  11112.                           (Float (Delta_Time) * Smoothed (8));
  11113.          Predicted (8) := Smoothed (8);
  11114.          Predicted (9) := Smoothed (9);
  11115.       else
  11116.          Predicted := To_Vector (Phi * Smoothed);
  11117.       end if;
  11118.  
  11119.       -- Initialize the maneuver detector constant and
  11120.       --   the error covariance matrix.
  11121.  
  11122.       Maneuver_Detector := Initial_Polar_Maneuver_Detector;
  11123.       Error_Covariance  := Make_Polar_Error_Covariance (Delta_Time);
  11124.  
  11125.       -- Update the last observation time.
  11126.  
  11127.       Last_Observed_Time := Observed_Time;
  11128.  
  11129.       -- Compute the smoothed location:
  11130.       --   initialize position components 
  11131.       --   to observed position components,
  11132.       --   compute initial velocity,
  11133.       --   initialize acceleration components 
  11134.       --   to observed acceleration components.
  11135.  
  11136.       if Location.Velocity = Null_Polar_Velocity then
  11137.  
  11138.          Smoothed 
  11139.             := Vector'
  11140.                (Location.Position.R * Feet_Per_Nautical_Mile,
  11141.                 ((Location.Position.R * Feet_Per_Nautical_Mile)
  11142.                  - Smoothed (1)) / Float(Delta_Time),
  11143.                 Location.Acceleration.R,
  11144.  
  11145.                 Location.Position.Theta,
  11146.                 (Location.Position.Theta - Smoothed (4)) /
  11147.                 Float(Delta_Time),
  11148.                 Location.Acceleration.Theta,
  11149.  
  11150.                 Location.Position.Height,
  11151.                 (Location.Position.Height - Smoothed (7)) /
  11152.                 Float(Delta_Time),
  11153.                 Location.Acceleration.Height);
  11154.       else
  11155.          Smoothed 
  11156.             := Vector'
  11157.                (Location.Position.R * Feet_Per_Nautical_Mile,
  11158.                 Location.Velocity.R * Feet_Per_Nautical_Mile /
  11159.                 Seconds_Per_Hour,
  11160.                 Location.Acceleration.R *
  11161.                 Feet_Per_Nautical_Mile /
  11162.                 (Seconds_Per_Hour ** 2),
  11163.  
  11164.                 Location.Position.Theta,
  11165.                 Location.Velocity.Theta,
  11166.                 Location.Acceleration.Theta,
  11167.  
  11168.                 Location.Position.Height,
  11169.                 Location.Velocity.Height,
  11170.                 Location.Acceleration.Height);
  11171.  
  11172.       end if;
  11173.  
  11174.       if (Execute_Debug_Code) then
  11175.          Status (Pid, Parameters,
  11176.                  "At exit, Smoothed Location ",
  11177.                  Smoothed);
  11178.          Status (Pid, Parameters,
  11179.                  "Predicted Location ", Predicted);
  11180.          Status (Pid, Parameters,
  11181.                  "Error Covariance ", Error_Covariance);
  11182.          Status (Pid, Parameters,
  11183.                  "Maneuver Detector ", Maneuver_Detector);
  11184.          Status (Pid, Entry_Exit,
  11185.                  "<-- Exit from procedure " &
  11186.                  "Kalman_Functions.Update (Polar)");
  11187.       end if;
  11188.  
  11189.    end Update;
  11190.  
  11191.    pragma Page;
  11192.    -------------------------------------------------------------------
  11193.  
  11194.    generic
  11195.       type Coordinate_Location is private;
  11196.       Measurement_Covariance : in Measurement_Covariance_Matrix;
  11197.       System                 : in Coordinate_System;
  11198.  
  11199.       with function Make_Psi
  11200.          (Location : Coordinate_Location)
  11201.          return Position_Vector is <>;
  11202.  
  11203.    procedure Generic_Filter
  11204.       (Location           : in     Coordinate_Location;
  11205.        Observed_Time      : in     Time;
  11206.        Maneuver_Detector  : in     Float;
  11207.        Smoothed           : in out Location_Vector;
  11208.        Last_Observed_Time : in out Time;
  11209.        Error_Covariance   : in out Covariance_Matrix;
  11210.        Predicted          : in out Location_Vector;
  11211.        Maneuver_Indicator : in out Float);
  11212.  
  11213.    pragma Page;
  11214.    -------------------------------------------------------------------
  11215.  
  11216.    procedure Generic_Filter
  11217.       (Location           : in     Coordinate_Location;
  11218.        Observed_Time      : in     Time;
  11219.        Maneuver_Detector  : in     Float;
  11220.        Smoothed           : in out Location_Vector;
  11221.        Last_Observed_Time : in out Time;
  11222.        Error_Covariance   : in out Covariance_Matrix;
  11223.        Predicted          : in out Location_Vector;
  11224.        Maneuver_Indicator : in out Float) is
  11225.  
  11226.       --!-------------------------------------------------------------
  11227.       --!
  11228.       --! Name:
  11229.       --!    Generic_Filter
  11230.       --!
  11231.       --! Purpose:
  11232.       --!    This procedure determines the best estimate of the
  11233.       --!    current position of a tracked object using the observed
  11234.       --!    Location, the previous Smoothed location, and the 
  11235.       --!    previous Error_Covariance. 
  11236.       --!
  11237.       --! Parameters:
  11238.       --!    Location
  11239.       --!       is the observed Location.
  11240.       --!    Observed_Time
  11241.       --!       is the time at which the hit was recorded. 
  11242.       --!    Maneuver_Detector
  11243.       --!       is the white noise matrix constant which determines
  11244.       --!       the amount of credibility in the observed Location.
  11245.       --!    Smoothed (on input)
  11246.       --!       is the previous position of the track.
  11247.       --!    Smoothed (on output)
  11248.       --!       is the current position of the track.
  11249.       --!    Last_Observed_Time (on input)
  11250.       --!       is the time at which the previous hit was recorded.
  11251.       --!    Last_Observed_Time (on output)
  11252.       --!       is the time at which the hit was recorded.
  11253.       --!    Error Covariance (on input)
  11254.       --!       is the previous error covariance matrix.
  11255.       --!    Error Covariance (on output)
  11256.       --!       is the current error covariance matrix.
  11257.       --!    Predicted
  11258.       --!       is the predicted position of the track.
  11259.       --!    Maneuver_Indicator
  11260.       --!       is the sum of squares of errors. 
  11261.       --!
  11262.       --! Exceptions:
  11263.       --!    Not applicable.
  11264.       --!
  11265.       --! Notes:
  11266.       --!    Generic_Filter is a template for filter functions which
  11267.       --!    may be instantiated in specified coordinate systems.
  11268.       --!
  11269.       --!    The maneuver detector is used to tune the filter
  11270.       --!    calculations. As the value is increased, the filter
  11271.       --!    places less importance on the predicted position and
  11272.       --!    more on the observation when determining the best
  11273.       --!    estimate of the current position.
  11274.       --! 
  11275.       --!    The maneuver indicator tells whether the filter
  11276.       --!    believes that the tracked object is in a maneuver.
  11277.       --!    When a maneuver is in progress, increase the maneuver
  11278.       --!    detector to lessen the reliance on the track history.
  11279.       --!
  11280.       --!-------------------------------------------------------------
  11281.  
  11282.       subtype Element_Matrix is Matrix (1 .. 1, 1 .. 1);
  11283.  
  11284.       Delta_Time                 : Duration;
  11285.       Phi                        : State_Transition_Matrix;
  11286.       Temporary_Error_Covariance : Covariance_Matrix;
  11287.       Filter_Gain                : Filter_Gain_Matrix;
  11288.       White_Noise                : White_Noise_Matrix;
  11289.       Observed_Position          : Position_Vector;
  11290.       Sum_Of_Squares_Of_Errors   : Element_Matrix;
  11291.  
  11292.       P   : Covariance_Matrix
  11293.             renames Temporary_Error_Covariance;
  11294.       Q   : White_Noise_Matrix
  11295.             renames White_Noise;
  11296.       H   : Position_Extractor_Matrix
  11297.             renames Position_Extractor;
  11298.       R   : Measurement_Covariance_Matrix
  11299.             renames Measurement_Covariance;
  11300.       K   : Filter_Gain_Matrix
  11301.             renames Filter_Gain;
  11302.       Psi : Position_Vector
  11303.             renames Observed_Position;
  11304.  
  11305.    begin
  11306.  
  11307.       if (Execute_Debug_Code) then
  11308.          Status (Pid, Entry_Exit,
  11309.                  "--> Entry to procedure Kalman_Functions." &
  11310.                  "Generic_Filter");
  11311.          Status (Pid, Parameters,
  11312.                  "At entry, Smoothed Location ", Smoothed);
  11313.          Status (Pid, Parameters,
  11314.                  "Maneuver Detector ", Maneuver_Detector);
  11315.          Status (Pid, Parameters,
  11316.                  "Error Covariance ", Error_Covariance);
  11317.       end if;
  11318.  
  11319.       -- Compute the time between observations.
  11320.  
  11321.       Delta_Time := Observed_Time - Last_Observed_Time;
  11322.  
  11323.       if (Execute_Debug_Code) then
  11324.          Status (Pid, Internals,
  11325.                  "Delta Time ", Float(Delta_Time));
  11326.       end if;
  11327.  
  11328.       -- Compute the state transition matrix.
  11329.  
  11330.       Phi := Make_Phi (Delta_Time);
  11331.  
  11332.       if (Execute_Debug_Code) then
  11333.          Status (Pid, Internals,
  11334.                  "State Transition Matrix ", Phi);
  11335.       end if;
  11336.  
  11337.       --                                 P          S
  11338.       -- Compute the predicted location X  = PHI * X   .
  11339.       --                                            k-1
  11340.  
  11341.       if (Use_Fast_Matrix_Operations) then
  11342.          Predicted (1) := Smoothed (1) +
  11343.                           (Float (Delta_Time) * Smoothed (2));
  11344.          Predicted (2) := Smoothed (2);
  11345.          Predicted (3) := Smoothed (3);
  11346.          Predicted (4) := Smoothed (4) +
  11347.                           (Float (Delta_Time) * Smoothed (5));
  11348.          Predicted (5) := Smoothed (5);
  11349.          Predicted (6) := Smoothed (6);
  11350.          Predicted (7) := Smoothed (7) +
  11351.                           (Float (Delta_Time) * Smoothed (8));
  11352.          Predicted (8) := Smoothed (8);
  11353.          Predicted (9) := Smoothed (9);
  11354.       else
  11355.          Predicted := To_Vector (Phi * Smoothed);
  11356.       end if;
  11357.  
  11358.       declare
  11359.  
  11360.          T : Float := Float (Delta_Time);
  11361.          R11 : Float renames R (1,1);
  11362.          R22 : Float renames R (2,2);
  11363.          R33 : Float renames R (3,3);
  11364.  
  11365.       begin
  11366.  
  11367.          --
  11368.          -- Compute the white noise matrix. 
  11369.          --
  11370.          -- Q = C  * Q
  11371.          --      k    0
  11372.          --
  11373.  
  11374.          Q := Zero (Q);
  11375.  
  11376.          if (Use_Fast_Matrix_Operations) then
  11377.  
  11378.             Q (1,1) := (T ** 5) * Maneuver_Detector / 20.0;
  11379.             Q (4,4) := Q (1,1);
  11380.             Q (7,7) := Q (1,1);
  11381.  
  11382.             Q (1,2) := (T ** 4) * Maneuver_Detector / 8.0;
  11383.             Q (2,1) := Q (1,2);
  11384.             Q (4,5) := Q (1,2);
  11385.             Q (5,4) := Q (1,2);
  11386.             Q (7,8) := Q (1,2);
  11387.             Q (8,7) := Q (1,2);
  11388.  
  11389.             Q (1,3) := (T ** 3) * Maneuver_Detector / 6.0;
  11390.             Q (3,1) := Q (1,3);
  11391.             Q (4,6) := Q (1,3);
  11392.             Q (6,4) := Q (1,3);
  11393.             Q (7,9) := Q (1,3);
  11394.             Q (9,7) := Q (1,3);
  11395.  
  11396.             Q (2,2) := (T ** 3) * Maneuver_Detector / 3.0;
  11397.             Q (5,5) := Q (2,2);
  11398.             Q (8,8) := Q (2,2);
  11399.  
  11400.             Q (2,3) := (T * T) * Maneuver_Detector / 2.0;
  11401.             Q (3,2) := Q (2,3);
  11402.             Q (5,6) := Q (2,3);
  11403.             Q (6,5) := Q (2,3);
  11404.             Q (8,9) := Q (2,3);
  11405.             Q (9,8) := Q (2,3);
  11406.  
  11407.             Q (3,3) := T * Maneuver_Detector;
  11408.             Q (6,6) := Q (3,3);
  11409.             Q (9,9) := Q (3,3);
  11410.  
  11411.          else
  11412.  
  11413.             Q (1,1) := (T ** 5) / 20.0;
  11414.             Q (4,4) := Q (1,1);
  11415.             Q (7,7) := Q (1,1);
  11416.  
  11417.             Q (1,2) := (T ** 4) / 8.0;
  11418.             Q (2,1) := Q (1,2);
  11419.             Q (4,5) := Q (1,2);
  11420.             Q (5,4) := Q (1,2);
  11421.             Q (7,8) := Q (1,2);
  11422.             Q (8,7) := Q (1,2);
  11423.  
  11424.             Q (1,3) := (T ** 3) / 6.0;
  11425.             Q (3,1) := Q (1,3);
  11426.             Q (4,6) := Q (1,3);
  11427.             Q (6,4) := Q (1,3);
  11428.             Q (7,9) := Q (1,3);
  11429.             Q (9,7) := Q (1,3);
  11430.  
  11431.             Q (2,2) := (T ** 3) / 3.0;
  11432.             Q (5,5) := Q (2,2);
  11433.             Q (8,8) := Q (2,2);
  11434.  
  11435.             Q (2,3) := (T * T) / 2.0;
  11436.             Q (3,2) := Q (2,3);
  11437.             Q (5,6) := Q (2,3);
  11438.             Q (6,5) := Q (2,3);
  11439.             Q (8,9) := Q (2,3);
  11440.             Q (9,8) := Q (2,3);
  11441.  
  11442.             Q (3,3) := T;
  11443.             Q (6,6) := T;
  11444.             Q (9,9) := T;
  11445.  
  11446.             Q := Maneuver_Detector * Q;
  11447.  
  11448.          end if;
  11449.  
  11450.          if System = Polar_System and abs (Smoothed (1)) > 1.0 then
  11451.  
  11452.             if (Execute_Debug_Code) then
  11453.  
  11454.                Status (Pid, Internals,
  11455.                        "Scaling White Noise in Theta");
  11456.  
  11457.             end if;
  11458.  
  11459.             for Row in 4 .. 6 loop
  11460.                for Column in 4 .. 6 loop
  11461.                   Q (Row, Column) := Q (Row, Column) /
  11462.                                      (Smoothed (1) * Smoothed (1));
  11463.                end loop;
  11464.             end loop;
  11465.          end if;
  11466.  
  11467.          if (Execute_Debug_Code) then
  11468.             Status (Pid, Internals, "White Noise ", Q);
  11469.          end if;
  11470.  
  11471.          --
  11472.          -- Compute the error covariance matrix from the 
  11473.          --   previous error covariance
  11474.          --   and the white noise matrix.
  11475.          --
  11476.          --                                  T
  11477.          -- P = (Phi * Error_Covariance * Phi ) + Q
  11478.          --
  11479.  
  11480.          if (Use_Fast_Matrix_Operations) then
  11481.             P := Error_Covariance;
  11482.             for Index in P'range (2) loop
  11483.                P (1, Index) := P (1, Index) +
  11484.                                (Float (Delta_Time) * P (2, Index));
  11485.                P (4, Index) := P (4, Index) +
  11486.                                (Float (Delta_Time) * P (5, Index));
  11487.                P (7, Index) := P (7, Index) +
  11488.                                (Float (Delta_Time) * P (8, Index));
  11489.             end loop;
  11490.             for Index in P'range (1) loop
  11491.                P (Index, 1) := P (Index, 1) +
  11492.                                (Float (Delta_Time) * P (Index, 2));
  11493.                P (Index, 4) := P (Index, 4) +
  11494.                                (Float (Delta_Time) * P (Index, 5));
  11495.                P (Index, 7) := P (Index, 7) +
  11496.                                (Float (Delta_Time) * P (Index, 8));
  11497.             end loop;
  11498.  
  11499.             declare
  11500.  
  11501.                R1,
  11502.                R2,
  11503.                C1,
  11504.                C2 : Integer;
  11505.  
  11506.             begin
  11507.  
  11508.                for Row in 1 .. 3 loop
  11509.                   R1 := Row + 3;
  11510.                   R2 := Row + 6;
  11511.                   for Column in 1 .. 3 loop
  11512.                      C1 := Column + 3;
  11513.                      C2 := Column + 6;
  11514.                      P (Row, Column) := P (Row, Column)
  11515.                                         + Q (Row, Column);
  11516.                      P (R1, C1) := P (R1, C1) + Q (R1, C1);
  11517.                      P (R2, C2) := P (R2, C2) + Q (R2, C2);
  11518.                   end loop;
  11519.                end loop;
  11520.             end;
  11521.          else
  11522.             P := Phi * Error_Covariance * Transpose (Phi) + Q;
  11523.          end if;
  11524.  
  11525.          if (Execute_Debug_Code) then
  11526.             Status (Pid, Internals,
  11527.                     "Temporary Error Covariance ", P);
  11528.          end if;
  11529.  
  11530.       end;
  11531.  
  11532.       --
  11533.       -- Compute the filter gain matrix from the 
  11534.       --   error covariance matrix (P),
  11535.       --   the measurement covariance matrix (R), 
  11536.       --   and the matrix (H) which
  11537.       --   extracts the position component from 
  11538.       --   location (position, velocity,
  11539.       --   and acceleration).
  11540.       --
  11541.       --
  11542.       --          T             T     -1
  11543.       -- K = P * H  * (H * P * H  + R)
  11544.       --
  11545.  
  11546.       begin
  11547.  
  11548.          if (Use_Fast_Matrix_Operations) then
  11549.  
  11550.             declare
  11551.  
  11552.                Temp_Mc : Measurement_Covariance_Matrix;
  11553.                Temp_Fg : Filter_Gain_Matrix;
  11554.  
  11555.             begin
  11556.  
  11557.                Temp_Mc (1,1) := R (1,1) + P (1,1);
  11558.                Temp_Mc (1,2) := R (1,2) + P (1,4);
  11559.                Temp_Mc (1,3) := R (1,3) + P (1,7);
  11560.                Temp_Mc (2,1) := R (2,1) + P (4,1);
  11561.                Temp_Mc (2,2) := R (2,2) + P (4,4);
  11562.                Temp_Mc (2,3) := R (2,3) + P (4,7);
  11563.                Temp_Mc (3,1) := R (3,1) + P (7,1);
  11564.                Temp_Mc (3,2) := R (3,2) + P (7,4);
  11565.                Temp_Mc (3,3) := R (3,3) + P (7,7);
  11566.  
  11567.                Temp_Mc := Inverse (Temp_Mc);
  11568.  
  11569.                for Row in Temp_Fg'range (1) loop
  11570.                   Temp_Fg (Row, 1) := P (Row, 1);
  11571.                   Temp_Fg (Row, 2) := P (Row, 4);
  11572.                   Temp_Fg (Row, 3) := P (Row, 7);
  11573.                end loop;
  11574.  
  11575.                K := Temp_Fg * Temp_Mc;
  11576.  
  11577.             end;
  11578.  
  11579.          else
  11580.             K := P * Transpose (H) *
  11581.                  Inverse (H * P * Transpose (H) + R);
  11582.          end if;
  11583.  
  11584.       exception
  11585.  
  11586.          when Inverse_Error =>
  11587.             K := ((1.0, 0.0, 0.0),
  11588.                   (0.0, 0.0, 0.0),
  11589.                   (0.0, 0.0, 0.0),
  11590.                   (0.0, 1.0, 0.0),
  11591.                   (0.0, 0.0, 0.0),
  11592.                   (0.0, 0.0, 0.0),
  11593.                   (0.0, 0.0, 1.0),
  11594.                   (0.0, 0.0, 0.0),
  11595.                   (0.0, 0.0, 0.0));
  11596.  
  11597.       end;
  11598.  
  11599.       if (Execute_Debug_Code) then
  11600.          Status (Pid, Internals,
  11601.                  "Filter Gain Matrix ", K);
  11602.       end if;
  11603.  
  11604.       --
  11605.       -- Compute the smoothed location using the predicted location,
  11606.       --   the filter gain matrix, the observed position, 
  11607.       --   and the predicted
  11608.       --   position.
  11609.       --
  11610.       --  S        P                   P
  11611.       -- X      = X  + K * (PSI - H * X )
  11612.       --  k + 1
  11613.  
  11614.       Psi := Make_Psi (Location);
  11615.  
  11616.       if (Execute_Debug_Code) then
  11617.          Status (Pid, Internals, "Determine Smoothed");
  11618.       end if;
  11619.  
  11620.       if (Use_Fast_Matrix_Operations) then
  11621.          declare
  11622.  
  11623.             Pos : Position_Vector;
  11624.  
  11625.          begin
  11626.  
  11627.             Pos (1) := Psi (1) - Predicted (1);
  11628.             Pos (2) := Psi (2) - Predicted (4);
  11629.             Pos (3) := Psi (3) - Predicted (7);
  11630.  
  11631.             Smoothed := To_Vector
  11632.                         (Predicted + (K * Pos));
  11633.  
  11634.          end;
  11635.  
  11636.       else
  11637.          Smoothed := To_Vector
  11638.                      (Predicted + (K * (Psi - (H * Predicted))));
  11639.       end if;
  11640.  
  11641.       --
  11642.       -- Update the error covariance matrix.
  11643.       --
  11644.       --  S
  11645.       -- P      = (I - K * H) * P
  11646.       --  k + 1
  11647.       --
  11648.  
  11649.       if (Execute_Debug_Code) then
  11650.          Status (Pid, Internals, "Determine P");
  11651.       end if;
  11652.  
  11653.       if (Use_Fast_Matrix_Operations) then
  11654.  
  11655.          declare
  11656.  
  11657.             Temp1,
  11658.             Temp2 : Covariance_Matrix;
  11659.  
  11660.          begin
  11661.  
  11662.             if (Execute_Debug_Code) then
  11663.                Status (Pid, Internals, "Determine Temp1");
  11664.             end if;
  11665.  
  11666.             Temp1 := Zero (Temp1);
  11667.  
  11668.             for Row in Temp1'range (1) loop
  11669.                Temp1 (Row, 1) := K (Row, 1);
  11670.                Temp1 (Row, 4) := K (Row, 2);
  11671.                Temp1 (Row, 7) := K (Row, 3);
  11672.             end loop;
  11673.  
  11674.             if (Execute_Debug_Code) then
  11675.                Status (Pid, Internals, "Determine Temp2");
  11676.             end if;
  11677.  
  11678.             Temp2 := Identity (Error_Covariance);
  11679.  
  11680.             for Row in Temp1'range (1) loop
  11681.                Temp2 (Row, 1) := Temp2 (Row, 1) - Temp1 (Row, 1);
  11682.                Temp2 (Row, 4) := Temp2 (Row, 4) - Temp1 (Row, 4);
  11683.                Temp2 (Row, 7) := Temp2 (Row, 7) - Temp1 (Row, 7);
  11684.             end loop;
  11685.  
  11686.             if (Execute_Debug_Code) then
  11687.                Status (Pid, Internals, "Determine Temp2 * P");
  11688.             end if;
  11689.  
  11690.             Error_Covariance := Temp2 * P;
  11691.  
  11692.          end;
  11693.  
  11694.       else
  11695.          Error_Covariance := (Identity (Error_Covariance) 
  11696.                               - (K * H)) * P;
  11697.       end if;
  11698.  
  11699.       --
  11700.       -- Compute the sum of squares of errors.
  11701.       --
  11702.       --                  P T            T -1             P
  11703.       --  SSE = (Psi - H X ) * (H * P * H )   * (Psi - H X )
  11704.       --
  11705.  
  11706.       if (Use_Fast_Matrix_Operations) then
  11707.  
  11708.          declare
  11709.  
  11710.             Temp_Mc : Measurement_Covariance_Matrix;
  11711.             Temp_P  : Position_Vector;
  11712.  
  11713.          begin
  11714.  
  11715.             Temp_P (1) := Psi (1) - Predicted (1);
  11716.             Temp_P (2) := Psi (2) - Predicted (4);
  11717.             Temp_P (3) := Psi (3) - Predicted (7);
  11718.  
  11719.             Temp_Mc (1,1) := P (1,1);
  11720.             Temp_Mc (1,2) := P (1,4);
  11721.             Temp_Mc (1,3) := P (1,7);
  11722.             Temp_Mc (2,1) := P (4,1);
  11723.             Temp_Mc (2,2) := P (4,4);
  11724.             Temp_Mc (2,3) := P (4,7);
  11725.             Temp_Mc (3,1) := P (7,1);
  11726.             Temp_Mc (3,2) := P (7,4);
  11727.             Temp_Mc (3,3) := P (7,7);
  11728.  
  11729.             begin
  11730.  
  11731.                if (Execute_Debug_Code) then
  11732.                   Status (Pid, Internals, "Invert Temp_Mc");
  11733.                end if;
  11734.  
  11735.                Temp_Mc := Inverse (Temp_Mc);
  11736.  
  11737.             exception
  11738.  
  11739.                when Inverse_Error =>
  11740.                   Temp_Mc := Identity (Temp_Mc);
  11741.  
  11742.             end;
  11743.  
  11744.             if (Execute_Debug_Code) then
  11745.                Status (Pid, Internals, "Temp_P * Temp_Mc * " &
  11746.                                        "Temp_P");
  11747.             end if;
  11748.  
  11749.             Sum_Of_Squares_Of_Errors := Temp_P * Temp_Mc * Temp_P;
  11750.          end;
  11751.  
  11752.       else
  11753.          begin
  11754.  
  11755.             Sum_Of_Squares_Of_Errors := Transpose (Psi - (H
  11756.                                                           * Predicted)) *
  11757.                                         Inverse (H * (P
  11758.                                                       * Transpose (H))) *
  11759.                                         (Psi - (H * Predicted));
  11760.          exception
  11761.  
  11762.             when Inverse_Error =>
  11763.  
  11764.                Sum_Of_Squares_Of_Errors := Transpose (Psi - (H
  11765.                                                              * Predicted)) *
  11766.                                            (Psi - (H * Predicted));
  11767.  
  11768.          end;
  11769.  
  11770.       end if;
  11771.  
  11772.       Maneuver_Indicator := Sum_Of_Squares_Of_Errors (1,1);
  11773.  
  11774.       --
  11775.       -- Update the last observation time.
  11776.       --
  11777.  
  11778.       Last_Observed_Time := Observed_Time;
  11779.  
  11780.       if (Execute_Debug_Code) then
  11781.          Status (Pid, Parameters,
  11782.                  "Upon exit, Smoothed Location ", Smoothed);
  11783.          Status (Pid, Parameters,
  11784.                  "Predicted Location ", Predicted);
  11785.          Status (Pid, Parameters,
  11786.                  "Error Covariance ", Error_Covariance);
  11787.          Status (Pid, Parameters,
  11788.                  "Maneuver Indicator ", Maneuver_Indicator);
  11789.          Status (Pid, Entry_Exit,
  11790.                  "<-- Exit from procedure Kalman_Functions." &
  11791.                  "Generic_Filter");
  11792.       end if;
  11793.  
  11794.    end Generic_Filter;
  11795.  
  11796.    pragma Page;
  11797.    -------------------------------------------------------------------
  11798.  
  11799.    procedure Cartesian_Filter is
  11800.       new Generic_Filter
  11801.           (Coordinate_Location    => Cartesian_Location,
  11802.            Measurement_Covariance => Cartesian_Measurement_Covariance,
  11803.            System                 => Cartesian_System);
  11804.  
  11805.    procedure Polar_Filter is
  11806.       new Generic_Filter
  11807.           (Coordinate_Location    => Polar_Location,
  11808.            Measurement_Covariance => Polar_Measurement_Covariance,
  11809.            System                 => Polar_System);
  11810.  
  11811.    pragma Page;
  11812.    -------------------------------------------------------------------
  11813.  
  11814.    procedure Filter
  11815.       (Location           : in     Cartesian_Location;
  11816.        Observed_Time      : in     Time;
  11817.        Maneuver_Detector  : in     Float;
  11818.        Smoothed           : in out Location_Vector;
  11819.        Last_Observed_Time : in out Time;
  11820.        Error_Covariance   : in out Covariance_Matrix;
  11821.        Predicted          : in out Location_Vector;
  11822.        Maneuver_Indicator : in out Float) is
  11823.  
  11824.       --!-------------------------------------------------------------
  11825.       --!
  11826.       --! Name:
  11827.       --!    Filter
  11828.       --!
  11829.       --! Purpose:
  11830.       --!    This procedure executes the Kalman Filter equations
  11831.       --!    for a Location expressed in Cartesian coordinates.
  11832.       --!
  11833.       --! Parameters:
  11834.       --!    Location
  11835.       --!       is the observed Location in Cartesian coordinates
  11836.       --!       (X and Y in nautical miles, Z in feet).
  11837.       --!    Observed_Time
  11838.       --!       is the time at which the hit was recorded. 
  11839.       --!    Maneuver_Detector
  11840.       --!       is the white noise matrix constant which determines
  11841.       --!       the amount of credibility in the observed Location.
  11842.       --!    Smoothed (on input)
  11843.       --!       is the previous position of the track.
  11844.       --!    Smoothed (on output)
  11845.       --!       is the current position of the track.
  11846.       --!    Last_Observed_Time (on input)
  11847.       --!       is the time at which the previous hit was recorded.
  11848.       --!    Last_Observed_Time (on output)
  11849.       --!       is the time at which the hit was recorded.
  11850.       --!    Error Covariance (on input)
  11851.       --!       is the previous error covariance matrix.
  11852.       --!    Error Covariance (on output)
  11853.       --!       is the current error covariance matrix.
  11854.       --!    Predicted
  11855.       --!       is the predicted position of the track.
  11856.       --!    Maneuver_Indicator
  11857.       --!       is the sum of squares of errors. 
  11858.       --!
  11859.       --! Exceptions:
  11860.       --!    Not applicable.
  11861.       --!
  11862.       --! Notes:
  11863.       --!    Refer to the procedure header of Generic_Filter.
  11864.       --!
  11865.       --!-------------------------------------------------------------
  11866.  
  11867.    begin
  11868.  
  11869.       if (Execute_Debug_Code) then
  11870.          Status (Pid, Entry_Exit,
  11871.                  "--> Entry to procedure " &
  11872.                  "Kalman_Filter.Filter (Cartesian)");
  11873.       end if;
  11874.  
  11875.       Cartesian_Filter (Location,
  11876.                         Observed_Time,
  11877.                         Maneuver_Detector,
  11878.                         Smoothed,
  11879.                         Last_Observed_Time,
  11880.                         Error_Covariance,
  11881.                         Predicted,
  11882.                         Maneuver_Indicator);
  11883.  
  11884.       if (Execute_Debug_Code) then
  11885.          Status (Pid, Entry_Exit,
  11886.                  "<-- Exit from procedure " &
  11887.                  "Kalman_Functions.Filter (Cartesian)");
  11888.       end if;
  11889.  
  11890.    end Filter;
  11891.  
  11892.    pragma Page;
  11893.    -------------------------------------------------------------------
  11894.  
  11895.    procedure Filter
  11896.       (Location           : in     Polar_Location;
  11897.        Observed_Time      : in     Time;
  11898.        Maneuver_Detector  : in     Float;
  11899.        Smoothed           : in out Location_Vector;
  11900.        Last_Observed_Time : in out Time;
  11901.        Error_Covariance   : in out Covariance_Matrix;
  11902.        Predicted          : in out Location_Vector;
  11903.        Maneuver_Indicator : in out Float) is
  11904.  
  11905.       --!-------------------------------------------------------------
  11906.       --!
  11907.       --! Name:
  11908.       --!    Filter
  11909.       --!
  11910.       --! Purpose:
  11911.       --!    This procedure executes the Kalman Filter equations for
  11912.       --!    a Location expressed in Polar coordinates.
  11913.       --!
  11914.       --! Parameters:
  11915.       --!    Location
  11916.       --!       is the observed Location in Polar coordinates
  11917.       --!       (R in nautical miles, Theta in radians, Height in 
  11918.       --!       feet).
  11919.       --!    Observed_Time
  11920.       --!       is the time at which the hit was recorded. 
  11921.       --!    Maneuver_Detector
  11922.       --!       is the white noise matrix constant which determines
  11923.       --!       the amount of credibility in the observed Location.
  11924.       --!    Smoothed (on input)
  11925.       --!       is the previous position of the track.
  11926.       --!    Smoothed (on output)
  11927.       --!       is the current position of the track.
  11928.       --!    Last_Observed_Time (on input)
  11929.       --!       is the time at which the previous hit was recorded.
  11930.       --!    Last_Observed_Time (on output)
  11931.       --!       is the time at which the hit was recorded.
  11932.       --!    Error Covariance (on input)
  11933.       --!       is the previous error covariance matrix.
  11934.       --!    Error Covariance (on output)
  11935.       --!       is the current error covariance matrix.
  11936.       --!    Predicted
  11937.       --!       is the predicted position of the track.
  11938.       --!    Maneuver_Indicator
  11939.       --!       is the sum of squares of errors. 
  11940.       --!
  11941.       --! Exceptions:
  11942.       --!    Not applicable.
  11943.       --!
  11944.       --! Notes:
  11945.       --!    Refer to the procedure header for Generic_Filter.
  11946.       --!
  11947.       --!-------------------------------------------------------------
  11948.  
  11949.    begin
  11950.  
  11951.       if (Execute_Debug_Code) then
  11952.          Status (Pid, Entry_Exit,
  11953.                  "--> Entry to procedure " &
  11954.                  "Kalman_Functions.Filter (Polar)");
  11955.       end if;
  11956.  
  11957.       Polar_Filter (Location,
  11958.                     Observed_Time,
  11959.                     Maneuver_Detector,
  11960.                     Smoothed,
  11961.                     Last_Observed_Time,
  11962.                     Error_Covariance,
  11963.                     Predicted,
  11964.                     Maneuver_Indicator);
  11965.  
  11966.       if (Execute_Debug_Code) then
  11967.          Status (Pid, Entry_Exit,
  11968.                  "<-- Exit from procedure " &
  11969.                  "Kalman_Functions.Filter (Polar)");
  11970.       end if;
  11971.  
  11972.    end Filter;
  11973.  
  11974.    pragma Page;
  11975.    -------------------------------------------------------------------
  11976.  
  11977.    procedure Filter
  11978.       (Location           : in     Cartesian_Location;
  11979.        Observed_Time      : in     Time;
  11980.        Maneuver_Detector  : in     Float;
  11981.        Smoothed           : in out Location_Vector;
  11982.        Last_Observed_Time : in out Time;
  11983.        Error_Covariance   : in out Covariance_Matrix;
  11984.        Predicted          : in out Location_Vector;
  11985.        Maneuver_Indicator : in out Float;
  11986.        Cpu_Time           :    out Duration;
  11987.        Real_Time          :    out Duration) is
  11988.  
  11989.       --!-------------------------------------------------------------
  11990.       --!
  11991.       --! Name:
  11992.       --!    Filter
  11993.       --!
  11994.       --! Purpose:
  11995.       --!    This procedure executes the Kalman Filter equations for
  11996.       --!    a Location expressed in Cartesian coordinates. It also
  11997.       --!    supplies timing information to assist in determining
  11998.       --!    the efficiency (or lack of efficiency) of the Ada Kalman
  11999.       --!    Filter.
  12000.       --!
  12001.       --! Parameters:
  12002.       --!    Location
  12003.       --!       is the observed Location in Cartesian coordinates
  12004.       --!       (X and Y in nautical miles, Z in feet).
  12005.       --!    Observed_Time
  12006.       --!       is the time at which the hit was recorded. 
  12007.       --!    Maneuver_Detector
  12008.       --!       is the white noise matrix constant which determines
  12009.       --!       the amount of credibility in the observed Location.
  12010.       --!    Smoothed (on input)
  12011.       --!       is the previous position of the track.
  12012.       --!    Smoothed (on output)
  12013.       --!       is the current position of the track.
  12014.       --!    Last_Observed_Time (on input)
  12015.       --!       is the time at which the previous hit was recorded.
  12016.       --!    Last_Observed_Time (on output)
  12017.       --!       is the time at which the hit was recorded.
  12018.       --!    Error Covariance (on input)
  12019.       --!       is the previous error covariance matrix.
  12020.       --!    Error Covariance (on output)
  12021.       --!       is the current error covariance matrix.
  12022.       --!    Predicted
  12023.       --!       is the predicted position of the track.
  12024.       --!    Maneuver_Indicator
  12025.       --!       is the sum of squares of errors. 
  12026.       --!    Cpu_Time 
  12027.       --!       is the amount of CPU Time used in the single call
  12028.       --!       to the Cartesian_Filter procedure.
  12029.       --!    Real_Time
  12030.       --!       is the amount of running time used in the single call
  12031.       --!       to the Cartesian_Filter procedure.
  12032.       --!
  12033.       --! Exceptions:
  12034.       --!    Not applicable.
  12035.       --!
  12036.       --! Notes:
  12037.       --!    Refer to the procedure header for Generic_Filter.
  12038.       --!
  12039.       --!-------------------------------------------------------------
  12040.  
  12041.       Cpu_Start,
  12042.       Real_Start,
  12043.       Cpu_Stop,
  12044.       Real_Stop : Duration;
  12045.  
  12046.    begin
  12047.  
  12048.       if (Execute_Debug_Code) then
  12049.          Status (Pid, Entry_Exit,
  12050.                  "--> Entry to procedure " &
  12051.                  "Kalman_Filter.Filter (Cartesian)");
  12052.       end if;
  12053.  
  12054.       Get_Time (Cpu_Start, Real_Start);
  12055.  
  12056.       Cartesian_Filter (Location,
  12057.                         Observed_Time,
  12058.                         Maneuver_Detector,
  12059.                         Smoothed,
  12060.                         Last_Observed_Time,
  12061.                         Error_Covariance,
  12062.                         Predicted,
  12063.                         Maneuver_Indicator);
  12064.  
  12065.       Get_Time (Cpu_Stop, Real_Stop);
  12066.  
  12067.       Cpu_Time  := Cpu_Stop  - Cpu_Start;
  12068.       Real_Time := Real_Stop - Real_Start;
  12069.  
  12070.       if (Execute_Debug_Code) then
  12071.          Status (Pid, Entry_Exit,
  12072.                  "<-- Exit from procedure " &
  12073.                  "Kalman_Functions.Filter (Cartesian)");
  12074.       end if;
  12075.  
  12076.    end Filter;
  12077.  
  12078.    pragma Page;
  12079.    -------------------------------------------------------------------
  12080.  
  12081.    procedure Filter
  12082.       (Location           : in     Polar_Location;
  12083.        Observed_Time      : in     Time;
  12084.        Maneuver_Detector  : in     Float;
  12085.        Smoothed           : in out Location_Vector;
  12086.        Last_Observed_Time : in out Time;
  12087.        Error_Covariance   : in out Covariance_Matrix;
  12088.        Predicted          : in out Location_Vector;
  12089.        Maneuver_Indicator : in out Float;
  12090.        Cpu_Time           :    out Duration;
  12091.        Real_Time          :    out Duration) is
  12092.  
  12093.       --!-------------------------------------------------------------
  12094.       --!
  12095.       --! Name:
  12096.       --!    Filter
  12097.       --!
  12098.       --! Purpose:
  12099.       --!    This procedure executes the Kalman Filter equations for
  12100.       --!    a Location expressed in Polar coordinates. It also
  12101.       --!    supplies timing information to assist in determining
  12102.       --!    the efficiency (or lack of efficiency) of the Ada Kalman
  12103.       --!    Filter.
  12104.       --!
  12105.       --! Parameters:
  12106.       --!    Location
  12107.       --!       is the observed Location in Polar coordinates
  12108.       --!       (R in nautical miles, Theta in radians,
  12109.       --!       Height in feet).
  12110.       --!    Observed_Time
  12111.       --!       is the time at which the hit was recorded. 
  12112.       --!    Maneuver_Detector
  12113.       --!       is the white noise matrix constant which determines
  12114.       --!       the amount of credibility in the observed Location.
  12115.       --!    Smoothed (on input)
  12116.       --!       is the previous position of the track.
  12117.       --!    Smoothed (on output)
  12118.       --!       is the current position of the track.
  12119.       --!    Last_Observed_Time (on input)
  12120.       --!       is the time at which the previous hit was recorded.
  12121.       --!    Last_Observed_Time (on output)
  12122.       --!       is the time at which the hit was recorded.
  12123.       --!    Error Covariance (on input)
  12124.       --!       is the previous error covariance matrix.
  12125.       --!    Error Covariance (on output)
  12126.       --!       is the current error covariance matrix.
  12127.       --!    Predicted
  12128.       --!       is the predicted position of the track.
  12129.       --!    Maneuver_Indicator
  12130.       --!       is the sum of squares of errors. 
  12131.       --!    Cpu_Time 
  12132.       --!       is the amount of CPU Time used in the single call
  12133.       --!       to the Polar_Filter procedure.
  12134.       --!    Real_Time
  12135.       --!       is the amount of running time used in the single call
  12136.       --!       to the Polar_Filter procedure.
  12137.       --!
  12138.       --! Exceptions:
  12139.       --!    Not applicable.
  12140.       --!
  12141.       --! Notes:
  12142.       --!    Refer to the procedure header for Generic_Filter.
  12143.       --!
  12144.       --!-------------------------------------------------------------
  12145.  
  12146.       Cpu_Start,
  12147.       Real_Start,
  12148.       Cpu_Stop,
  12149.       Real_Stop : Duration;
  12150.  
  12151.    begin
  12152.  
  12153.       if (Execute_Debug_Code) then
  12154.          Status (Pid, Entry_Exit,
  12155.                  "--> Entry to procedure " &
  12156.                  "Kalman_Functions.Filter (Polar)");
  12157.       end if;
  12158.  
  12159.       Get_Time (Cpu_Start, Real_Start);
  12160.  
  12161.       Polar_Filter (Location,
  12162.                     Observed_Time,
  12163.                     Maneuver_Detector,
  12164.                     Smoothed,
  12165.                     Last_Observed_Time,
  12166.                     Error_Covariance,
  12167.                     Predicted,
  12168.                     Maneuver_Indicator);
  12169.  
  12170.       Get_Time (Cpu_Stop, Real_Stop);
  12171.  
  12172.       Cpu_Time  := Cpu_Stop  - Cpu_Start;
  12173.       Real_Time := Real_Stop - Real_Start;
  12174.  
  12175.       if (Execute_Debug_Code) then
  12176.          Status (Pid, Entry_Exit,
  12177.                  "<-- Exit from procedure " &
  12178.                  "Kalman_Functions.Filter (Polar)");
  12179.       end if;
  12180.  
  12181.    end Filter;
  12182.  
  12183. begin -- Package Initialization
  12184.  
  12185.    if (Execute_Debug_Code) then
  12186.       Pid := New_Package_Id;
  12187.       Status (Pid, Nothing,
  12188.               "Kalman_Functions Package Initialization");
  12189.    end if;
  12190.  
  12191. end Kalman_Functions;
  12192. --::::::::::::::::::::::::::::
  12193. --KALMAN-TRACK-SPEC.ADA
  12194. --::::::::::::::::::::::::::::
  12195.  
  12196. with Calendar;
  12197. with Kalman_Definitions;
  12198.  
  12199. use Calendar;
  12200. use Kalman_Definitions;
  12201.  
  12202. package Kalman_Track is
  12203.  
  12204.    --!----------------------------------------------------------------
  12205.    --!
  12206.    --! Name:
  12207.    --!   Kalman_Track
  12208.    --!
  12209.    --! Purpose:
  12210.    --!   This package acts as a stand-alone tracking package
  12211.    --!   using Kalman_Filter techniques. It correlates specified
  12212.    --!   "hits" with existing tracks or initiates new tracks. 
  12213.    --!   Kalman Filter operations are then performed on the track.
  12214.    --!   Tracks which have not been correlated with "hits" for 
  12215.    --!   one full sensor device scan time are "coasted" to their
  12216.    --!   presumed new position. Tracks which have been coasted beyond
  12217.    --!   a maximum coast count are suspended.
  12218.    --!
  12219.    --! Interfaces:
  12220.    --!    Track
  12221.    --!       correlates the observed Location with an existing
  12222.    --!       track or initiates a new track, then performs Kalman
  12223.    --!       Filter operations on the track.
  12224.    --!
  12225.    --! Exceptions:
  12226.    --!    Mismatched_Coordinate_System
  12227.    --!       is raised if an Observed Location is correlated to a
  12228.    --!       track whose matrices are stored in the other
  12229.    --!       coordinate system.
  12230.    --!
  12231.    --!    No_More_Tracks_Available
  12232.    --!       is raised if a new track should be initiated when
  12233.    --!       no room exists in the TRACK_DATA for a new track.
  12234.    --!
  12235.    --! Notes:
  12236.    --!    The Track procedure may be invoked with Locations
  12237.    --!    expressed in either Cartesian or Polar coordinates.
  12238.    --!    Timing information is also available if desired.
  12239.    --!
  12240.    --! Contract:
  12241.    --!    Ada Tracking Package Using Kalman Filter Methods
  12242.    --!    Contract No. N66001-85-C-0044 (31 December 1984)
  12243.    --!
  12244.    --! Prepared for:
  12245.    --!    Naval Ocean Systems Center (WIS JPMO)
  12246.    --!    271 Catalina Blvd., Building A-33
  12247.    --!    San Diego, CA 92152
  12248.    --!
  12249.    --! Prepared by:
  12250.    --!    Software Systems Engineering
  12251.    --!    Federal Systems Group
  12252.    --!
  12253.    --!    Sanders Associates, Inc.
  12254.    --!    95 Canal Street
  12255.    --!    Nashua, NH 03061
  12256.    --!
  12257.    --! Author:
  12258.    --!    Jeffrey G. Smith
  12259.    --!
  12260.    --!----------------------------------------------------------------
  12261.  
  12262.    Mismatched_Coordinate_System : exception;
  12263.  
  12264.    No_More_Tracks_Available : exception;
  12265.  
  12266.    procedure Track
  12267.       (Location      : in     Cartesian_Location;
  12268.        Observed_Time : in     Time;
  12269.        Cycle_Time    : in     Duration;
  12270.        Track         : in out Track_Data;
  12271.        Track_Id      : in out Integer;
  12272.        Object_Id     : in     Object_Identification := Null_Object);
  12273.  
  12274.    procedure Track
  12275.       (Location      : in     Polar_Location;
  12276.        Observed_Time : in     Time;
  12277.        Cycle_Time    : in     Duration;
  12278.        Track         : in out Track_Data;
  12279.        Track_Id      : in out Integer;
  12280.        Object_Id     : in     Object_Identification := Null_Object);
  12281.  
  12282.    -------------------------------------------------------------------
  12283.  
  12284.    procedure Track
  12285.       (Location      : in     Cartesian_Location;
  12286.        Observed_Time : in     Time;
  12287.        Cycle_Time    : in     Duration;
  12288.        Track         : in out Track_Data;
  12289.        Track_Id      : in out Integer;
  12290.        Cpu_Time      :    out Duration;
  12291.        Real_Time     :    out Duration;
  12292.        Object_Id     : in     Object_Identification := Null_Object);
  12293.  
  12294.    procedure Track
  12295.       (Location      : in     Polar_Location;
  12296.        Observed_Time : in     Time;
  12297.        Cycle_Time    : in     Duration;
  12298.        Track         : in out Track_Data;
  12299.        Track_Id      : in out Integer;
  12300.        Cpu_Time      :    out Duration;
  12301.        Real_Time     :    out Duration;
  12302.        Object_Id     : in     Object_Identification := Null_Object);
  12303.  
  12304. end Kalman_Track;
  12305. --::::::::::::::::::::::::::::
  12306. --KALMAN-TRACK-BODY.ADA
  12307. --::::::::::::::::::::::::::::
  12308.  
  12309. with Calendar;
  12310. with Kalman_Options;
  12311. with Kalman_Definitions;
  12312. with Kalman_Matrix_Lib;
  12313. with Kalman_Functions;
  12314. with Kalman_Utilities;
  12315. with Kalman_Status;
  12316. with Kalman_Threshold;
  12317. with Kalman_Time;
  12318.  
  12319. use Calendar;
  12320. use Kalman_Options;
  12321. use Kalman_Definitions;
  12322. use Kalman_Matrix_Lib;
  12323. use Kalman_Functions;
  12324. use Kalman_Utilities;
  12325. use Kalman_Status;
  12326. use Kalman_Threshold;
  12327. use Kalman_Time;
  12328.  
  12329. package body Kalman_Track is
  12330.  
  12331.    --!----------------------------------------------------------------
  12332.    --!
  12333.    --! Name:
  12334.    --!    Kalman_Track
  12335.    --!
  12336.    --! Purpose:
  12337.    --!    This package body acts as a stand-alone tracking package
  12338.    --!    using Kalman Filter techniques. It correlates specified
  12339.    --!    "hits" with existing tracks or initiates new tracks.
  12340.    --!    Kalman Filter operations are then performed on the track.
  12341.    --!    Tracks which have not been correlated with "hits" for
  12342.    --!    one full sensor device scan time are "coasted" to their
  12343.    --!    presumed new location. Tracks which have been "coasted"
  12344.    --!    beyond a maximum coast count are suspended.
  12345.    --!
  12346.    --! Exceptions:
  12347.    --!    Mismatched_Coordinate_System
  12348.    --!       is raised if an observed Location is correlated to a
  12349.    --!       track whose matrices are stored in the other 
  12350.    --!       coordinate system.
  12351.    --!
  12352.    --!    No_More_Tracks_Available
  12353.    --!       is raised if a new track should be initiated when
  12354.    --!       no room exists in the TRACK_DATA for a new track.
  12355.    --!
  12356.    --! Notes:
  12357.    --!    The correlation procedure contained in Kalman_Track
  12358.    --!    is used to determine which if any of the active tracks
  12359.    --!    should be correlated with the observation. It simply
  12360.    --!    determines the closest track of those within a maximum
  12361.    --!    correlation distance and adjudges it the correlated
  12362.    --!    track. This procedure leaves much room for improvement
  12363.    --!    and would be an appropriate candidate for a separate
  12364.    --!    package.
  12365.    --!
  12366.    --! Contract:
  12367.    --!    Ada Tracking Package Using Kalman Filter Methods
  12368.    --!    Contract No. N66001-85-C-0044 (31 December 1984)
  12369.    --!
  12370.    --! Prepared for:
  12371.    --!    Naval Ocean Systems Center (WIS JPMO)
  12372.    --!    271 Catalina Blvd., Building A-33
  12373.    --!    San Diego, CA 92152
  12374.    --!
  12375.    --! Prepared by:
  12376.    --!    Software Systems Engineering
  12377.    --!    Federal Systems Group
  12378.    --!
  12379.    --!    Sanders Associates, Inc.
  12380.    --!    95 Canal Street
  12381.    --!    Nashua, NH 03061
  12382.    --!
  12383.    --! Author:
  12384.    --!    Jeffrey G. Smith
  12385.    --!
  12386.    --! Changes:
  12387.    --!    04-APR-1985
  12388.    --!       Changed Kalman_Trace to Kalman_Threshold because of 
  12389.    --!       TeleSoft file naming conflict with Kalman_Track.
  12390.    --!
  12391.    --!    24-APR-1985
  12392.    --!       Added code to Generic_Track to handle theta crossover
  12393.    --!       problem discovered during testing of MULTI_POLAR
  12394.    --!       scenario.
  12395.    --!
  12396.    --!    29-APR-1985
  12397.    --!       Changed debug threshold on Status call in package
  12398.    --!       initialization to "Nothing".
  12399.    --!
  12400.    --!----------------------------------------------------------------
  12401.  
  12402.    Pid : Package_Id;
  12403.  
  12404.    procedure Suspend
  12405.       (Track : in out Single_Track);
  12406.  
  12407.    procedure Coast
  12408.       (Observed_Time : in     Time;
  12409.        Cycle_Time    : in     Duration;
  12410.        Track         : in out Track_Data);
  12411.  
  12412.    function Aggregate
  12413.       (C1, C2, C3 : Float) return Cartesian_Position;
  12414.  
  12415.    function Aggregate
  12416.       (C1, C2, C3 : Float) return Polar_Position;
  12417.  
  12418.    function Position_Component_Of (Location : in Cartesian_Location)
  12419.       return Cartesian_Position;
  12420.  
  12421.    function Position_Component_Of (Location : in Polar_Location)
  12422.       return Polar_Position;
  12423.  
  12424.    function Range_Component_Of (Position : in Polar_Position)
  12425.       return Float;
  12426.  
  12427.    function Range_Component_Of (Position : in Cartesian_Position)
  12428.       return Float;
  12429.  
  12430.    function Theta_Component_Of (Position : in Polar_Position)
  12431.       return Float;
  12432.  
  12433.    function Theta_Component_Of (Position : in Cartesian_Position)
  12434.       return Float;
  12435.  
  12436.    function Original_Units_Of (Position : Polar_Position)
  12437.       return Polar_Position;
  12438.  
  12439.    function Original_Units_Of (Position : Cartesian_Position)
  12440.       return Cartesian_Position;
  12441.  
  12442.    pragma Page;
  12443.    -------------------------------------------------------------------
  12444.  
  12445.    generic
  12446.       type Coordinate_Position is private;
  12447.       type Other_Coordinate_Position  is private;
  12448.       Other_Coordinate_System : in Coordinate_System;
  12449.  
  12450.       with function Distance
  12451.          (From : Other_Coordinate_Position;
  12452.           To   : Coordinate_Position)
  12453.          return Float is <>;
  12454.  
  12455.       with function Distance
  12456.          (From : Coordinate_Position;
  12457.           To   : Coordinate_Position)
  12458.          return Float is <>;
  12459.  
  12460.       with function Aggregate
  12461.          (C1, C2, C3 : Float)
  12462.          return Coordinate_Position is <>;
  12463.  
  12464.       with function Aggregate
  12465.          (C1, C2, C3 : Float)
  12466.          return Other_Coordinate_Position is <>;
  12467.  
  12468.       with function Original_Units_Of
  12469.          (Position : Coordinate_Position)
  12470.          return Coordinate_Position is <>;
  12471.  
  12472.       with function Original_Units_Of
  12473.          (Position : Other_Coordinate_Position)
  12474.          return Other_Coordinate_Position is <>;
  12475.  
  12476.    function Generic_Correlation
  12477.       (Position      : in Coordinate_Position;
  12478.        Observed_Time : in Time;
  12479.        Object_Id     : in Object_Identification;
  12480.        Track         : in Track_Data) return Integer;
  12481.  
  12482.    Uncorrelated_Plot : exception;
  12483.  
  12484.    pragma Page;
  12485.    -------------------------------------------------------------------
  12486.  
  12487.    generic
  12488.       type Coordinate_Location is private;
  12489.       Input_Coordinate_System : in Coordinate_System;
  12490.  
  12491.       with procedure Initiate
  12492.          (Location           : in     Coordinate_Location;
  12493.           Observed_Time      : in     Time;
  12494.           Smoothed           : in out Location_Vector;
  12495.           Last_Observed_Time :    out Time;
  12496.           Predicted          :    out Location_Vector) is <>;
  12497.  
  12498.    procedure Generic_Initiate_Track
  12499.       (Location        : in     Coordinate_Location;
  12500.        Observed_Time   : in     Time;
  12501.        Object_Id       : in     Object_Identification;
  12502.        Track           : in out Track_Data;
  12503.        Track_Id        : in out Integer);
  12504.  
  12505.    pragma Page;
  12506.    -------------------------------------------------------------------
  12507.  
  12508.    generic
  12509.       type Coordinate_Location is private;
  12510.  
  12511.       with procedure Filter
  12512.          (Location           : in     Coordinate_Location;
  12513.           Observed_Time      : in     Time;
  12514.           Maneuver_Detector  : in     Float;
  12515.           Smoothed           : in out Location_Vector;
  12516.           Last_Observed_Time : in out Time;
  12517.           Error_Covariance   : in out Covariance_Matrix;
  12518.           Predicted          : in out Location_Vector;
  12519.           Maneuver_Indicator : in out Float) is <>;
  12520.  
  12521.       with procedure Update
  12522.          (Location           : in     Coordinate_Location;
  12523.           Observed_Time      : in     Time;
  12524.           Smoothed           : in out Location_Vector;
  12525.           Last_Observed_Time : in out Time;
  12526.           Error_Covariance   : in out Covariance_Matrix;
  12527.           Predicted          : in out Location_Vector;
  12528.           Maneuver_Detector  : in out Float) is <>;
  12529.  
  12530.    procedure Generic_Update_Or_Filter
  12531.       (Location        : in     Coordinate_Location;
  12532.        Observed_Time   : in     Time;
  12533.        Track_Id        : in     Integer;
  12534.        Track           : in out Track_Data);
  12535.  
  12536.    pragma Page;
  12537.    -------------------------------------------------------------------
  12538.  
  12539.    generic
  12540.       type Coordinate_Location is private;
  12541.       type Coordinate_Position is private;
  12542.       type Other_Location      is private;
  12543.       Other_Coordinate_System : Coordinate_System;
  12544.  
  12545.       with function Correlation
  12546.          (Position      : in     Coordinate_Position;
  12547.           Observed_Time : in     Time;
  12548.           Object_Id     : in     Object_Identification;
  12549.           Track         : in     Track_Data)
  12550.          return Integer is <>;
  12551.  
  12552.       with procedure Initiate_Track
  12553.          (Location      : in     Coordinate_Location;
  12554.           Observed_Time : in     Time;
  12555.           Object_Id     : in     Object_Identification;
  12556.           Track         : in out Track_Data;
  12557.           Track_Id      : in out Integer) is <>;
  12558.  
  12559.       with procedure Update_Or_Filter
  12560.          (Location      : in     Coordinate_Location;
  12561.           Observed_Time : in     Time;
  12562.           Track_Id      : in     Integer;
  12563.           Track         : in out Track_Data) is <>;
  12564.  
  12565.       with function Position_Component_Of
  12566.          (Location      : in     Coordinate_Location)
  12567.          return Coordinate_Position is <>;
  12568.  
  12569.       with function Range_Component_Of
  12570.          (Position      : in     Coordinate_Position)
  12571.          return Float is <>;
  12572.  
  12573.       with function Theta_Component_Of
  12574.          (Position      : in     Coordinate_Position)
  12575.          return Float is <>;
  12576.  
  12577.       with procedure Initiate
  12578.          (Location           : in     Coordinate_Location;
  12579.           Observed_Time      : in     Time;
  12580.           Smoothed           : in out Location_Vector;
  12581.           Last_Observed_Time :    out Time;
  12582.           Predicted          :    out Location_Vector) is <>;
  12583.  
  12584.    procedure Generic_Track
  12585.       (Location        : in     Coordinate_Location;
  12586.        Observed_Time   : in     Time;
  12587.        Object_Id       : in     Object_Identification;
  12588.        Cycle_Time      : in     Duration;
  12589.        Track           : in out Track_Data;
  12590.        Track_Id        : in out Integer);
  12591.  
  12592.    pragma Page;
  12593.    -------------------------------------------------------------------
  12594.  
  12595.    procedure Suspend
  12596.       (Track : in out Single_Track) is
  12597.  
  12598.       --!-------------------------------------------------------------
  12599.       --!
  12600.       --! Name:
  12601.       --!    Suspend
  12602.       --!
  12603.       --! Purpose:
  12604.       --!    This procedure sets the state of the specified track
  12605.       --!    to suspended.
  12606.       --!
  12607.       --! Parameters:
  12608.       --!    Track
  12609.       --!       is the track which is being suspended.
  12610.       --!
  12611.       --! Exceptions:
  12612.       --!    Not applicable.
  12613.       --!
  12614.       --! Notes:
  12615.       --!    Suspend merely sets the state to suspended, not
  12616.       --!    checking to see whether the specified track was
  12617.       --!    active in the first place.
  12618.       --!
  12619.       --!-------------------------------------------------------------
  12620.  
  12621.    begin
  12622.       if (Execute_Debug_Code) then
  12623.          Status (Pid, Entry_Exit,
  12624.                  "--> Entry to procedure Kalman_Track.Suspend");
  12625.       end if;
  12626.  
  12627.       Track := Single_Track'(State => Suspended);
  12628.  
  12629.       if (Execute_Debug_Code) then
  12630.          Status (Pid, Entry_Exit,
  12631.                  "<-- Exit from procedure Kalman_Track.Suspend");
  12632.       end if;
  12633.    end Suspend;
  12634.  
  12635.    pragma Page;
  12636.    -------------------------------------------------------------------
  12637.  
  12638.    procedure Coast
  12639.       (Observed_Time : in     Time;
  12640.        Cycle_Time    : in     Duration;
  12641.        Track         : in out Track_Data) is
  12642.  
  12643.       --!-------------------------------------------------------------
  12644.       --!
  12645.       --! Name:
  12646.       --!    Coast
  12647.       --!
  12648.       --! Purpose:
  12649.       --!    This procedure determines whether any "active" tracks
  12650.       --!    have not been correlated with any "hits" for a period
  12651.       --!    of time greater than one sensor device scan time.  If
  12652.       --!    so, the procedure adds the number of times the sensor
  12653.       --!    device has scanned without recording a "hit" for this
  12654.       --!    track to the coast count in the TRACK_DATA.
  12655.       --!
  12656.       --! Parameters:
  12657.       --!    Observed_Time 
  12658.       --!       is the time at which a "hit" was most recently 
  12659.       --!       recorded.
  12660.       --!    Cycle_Time
  12661.       --!       is the time it takes the sensor device to make one 
  12662.       --!       full pass
  12663.       --!    Track
  12664.       --!       is the array of track records.
  12665.       --!
  12666.       --! Exceptions:
  12667.       --!    Not applicable.
  12668.       --!
  12669.       --! Notes:
  12670.       --!    The Coast procedure knows that a track has been 
  12671.       --!    "coasted" beyond the maximum coast count when the
  12672.       --!    addition of the current coast count and the number
  12673.       --!    cycle times passed causes an exception. It then
  12674.       --!    suspends the offending track.
  12675.       --!
  12676.       --!-------------------------------------------------------------
  12677.  
  12678.       Cycles_Since_Last_Update : Natural;
  12679.  
  12680.    begin
  12681.       if (Execute_Debug_Code) then
  12682.          Status (Pid, Entry_Exit,
  12683.                  "--> Entry to procedure Kalman_Track.Coast");
  12684.       end if;
  12685.  
  12686.       for Index in Track'range loop
  12687.  
  12688.          if Is_Active (Track(Index)) then
  12689.             begin
  12690.                if (Execute_Debug_Code) then
  12691.                   Status (Pid, Internals,
  12692.                           "Checking Track ",
  12693.                           Integer(Index));
  12694.                end if;
  12695.  
  12696.                Cycles_Since_Last_Update 
  12697.                   := Integer (Observed_Time -
  12698.                               Track(Index).Updated_Time) /
  12699.                      Integer (Cycle_Time);
  12700.  
  12701.                if (Execute_Debug_Code) then
  12702.                   Status (Pid, Internals,
  12703.                           "Current Coast Count ",
  12704.                           Integer(Track(Index).Coast_Counter));
  12705.                   Status (Pid, Internals,
  12706.                           "Cycles since last update ",
  12707.                           Integer(Cycles_Since_Last_Update));
  12708.                end if;
  12709.  
  12710.                Track(Index).Coast_Counter 
  12711.                   := Track(Index).Coast_Counter +
  12712.                      Cycles_Since_Last_Update;
  12713.  
  12714.                Track(Index).Updated_Time 
  12715.                   := Track(Index).Updated_Time +
  12716.                      Duration(Cycles_Since_Last_Update *
  12717.                               Integer(Cycle_Time));
  12718.  
  12719.             exception
  12720.                when Constraint_Error =>
  12721.                   if (Execute_Debug_Code) then
  12722.                      Status (Pid, Internals,
  12723.                              "Suspending Track");
  12724.                   end if;
  12725.  
  12726.                   Suspend (Track (Index));
  12727.             end;
  12728.          end if;
  12729.       end loop;
  12730.  
  12731.       if (Execute_Debug_Code) then
  12732.          Status (Pid, Entry_Exit,
  12733.                  "<-- Exit from procedure Kalman_Track.Coast");
  12734.       end if;
  12735.    end Coast;
  12736.  
  12737.    pragma Page;
  12738.    -------------------------------------------------------------------
  12739.  
  12740.    function Aggregate (C1, C2, C3 : Float)
  12741.       return Cartesian_Position is
  12742.  
  12743.       --!-------------------------------------------------------------
  12744.       --!
  12745.       --! Name:
  12746.       --!    Aggregate
  12747.       --!
  12748.       --! Purpose:
  12749.       --!    This function returns the Cartesian_Position
  12750.       --!    value with C1, C2, and C3 in the place of
  12751.       --!    X, Y, and Z.
  12752.       --!
  12753.       --! Parameters:
  12754.       --!    C1
  12755.       --!       is the first (X) component.
  12756.       --!    C2
  12757.       --!       is the second (Y) component.
  12758.       --!    C3
  12759.       --!       is the third (Z) component.
  12760.       --!
  12761.       --! Exceptions:
  12762.       --!    Not applicable.
  12763.       --!
  12764.       --! Notes:
  12765.       --!    Not applicable.
  12766.       --!
  12767.       --!-------------------------------------------------------------
  12768.  
  12769.    begin
  12770.  
  12771.       return Cartesian_Position'(C1, C2, C3);
  12772.  
  12773.    end Aggregate;
  12774.  
  12775.    pragma Page;
  12776.    -------------------------------------------------------------------
  12777.  
  12778.    function Aggregate (C1, C2, C3 : Float)
  12779.       return Polar_Position is
  12780.  
  12781.       --!-------------------------------------------------------------
  12782.       --!
  12783.       --! Name:
  12784.       --!    Aggregate
  12785.       --!
  12786.       --! Purpose:
  12787.       --!    This function returns the Polar_Position
  12788.       --!    value with C1, C2, and C3 in the place of
  12789.       --!    R, Theta, and Height.
  12790.       --!
  12791.       --! Parameters:
  12792.       --!    C1
  12793.       --!       is the first (R) component.
  12794.       --!    C2
  12795.       --!       is the second (Theta) component.
  12796.       --!    C3
  12797.       --!       is the third (Height) component.
  12798.       --!
  12799.       --! Exceptions:
  12800.       --!    Not applicable.
  12801.       --!
  12802.       --! Notes:
  12803.       --!    Not applicable.
  12804.       --!
  12805.       --!-------------------------------------------------------------
  12806.  
  12807.    begin
  12808.  
  12809.       return Polar_Position'(C1, C2, C3);
  12810.  
  12811.    end Aggregate;
  12812.  
  12813.    pragma Page;
  12814.    -------------------------------------------------------------------
  12815.  
  12816.    function Position_Component_Of (Location : in Cartesian_Location)
  12817.       return Cartesian_Position is
  12818.  
  12819.       --!-------------------------------------------------------------
  12820.       --!
  12821.       --! Name:
  12822.       --!    Position_Component_of
  12823.       --!
  12824.       --! Purpose:
  12825.       --!    This function returns the Cartesian_Position
  12826.       --!    component of the specified Location.
  12827.       --!
  12828.       --! Parameters:
  12829.       --!    Location
  12830.       --!       is the location of the object with
  12831.       --!       position, velocity, and acceleration components.
  12832.       --!
  12833.       --! Exceptions:
  12834.       --!    Not applicable.
  12835.       --!
  12836.       --! Notes:
  12837.       --!    Not applicable.
  12838.       --!
  12839.       --!-------------------------------------------------------------
  12840.  
  12841.    begin
  12842.  
  12843.       return Location.Position;
  12844.  
  12845.    end Position_Component_Of;
  12846.  
  12847.    pragma Page;
  12848.    -------------------------------------------------------------------
  12849.  
  12850.    function Position_Component_Of (Location : in Polar_Location)
  12851.       return Polar_Position is
  12852.  
  12853.       --!-------------------------------------------------------------
  12854.       --!
  12855.       --! Name:
  12856.       --!    Position_Component_of
  12857.       --!
  12858.       --! Purpose:
  12859.       --!    This function returns the Polar_Position
  12860.       --!    component of the specified Location.
  12861.       --!
  12862.       --! Parameters:
  12863.       --!    Location
  12864.       --!       is the location of the object with
  12865.       --!       position, velocity, and acceleration components.
  12866.       --!
  12867.       --! Exceptions:
  12868.       --!    Not applicable.
  12869.       --!
  12870.       --! Notes:
  12871.       --!    Not applicable.
  12872.       --!
  12873.       --!-------------------------------------------------------------
  12874.  
  12875.    begin
  12876.  
  12877.       return Location.Position;
  12878.  
  12879.    end Position_Component_Of;
  12880.  
  12881.    pragma Page;
  12882.    -------------------------------------------------------------------
  12883.  
  12884.    function Range_Component_Of (Position : in Cartesian_Position)
  12885.       return Float is
  12886.  
  12887.       --!-------------------------------------------------------------
  12888.       --!
  12889.       --! Name:
  12890.       --!    Range_Component_of
  12891.       --!
  12892.       --! Purpose:
  12893.       --!    This function satisfies the Ada compiler
  12894.       --!    with respect to generic instantiations of
  12895.       --!    Generic_Track.
  12896.       --!
  12897.       --! Parameters:
  12898.       --!    Position
  12899.       --!       is the position of the object with
  12900.       --!       X, Y, and Z components.
  12901.       --!
  12902.       --! Exceptions:
  12903.       --!    Not applicable.
  12904.       --!
  12905.       --! Notes:
  12906.       --!    Not applicable.
  12907.       --!
  12908.       --!-------------------------------------------------------------
  12909.  
  12910.    begin
  12911.  
  12912.       return 0.0;
  12913.  
  12914.    end Range_Component_Of;
  12915.  
  12916.    pragma Page;
  12917.    -------------------------------------------------------------------
  12918.  
  12919.    function Range_Component_Of (Position : in Polar_Position)
  12920.       return Float is
  12921.  
  12922.       --!-------------------------------------------------------------
  12923.       --!
  12924.       --! Name:
  12925.       --!    Range_Component_of
  12926.       --!
  12927.       --! Purpose:
  12928.       --!    This function returns the range component of
  12929.       --!    the position expressed in Range, Theta, and Height.
  12930.       --!
  12931.       --! Parameters:
  12932.       --!    Position
  12933.       --!       is the position of the object with
  12934.       --!       R, Theta, and Height components.
  12935.       --!
  12936.       --! Exceptions:
  12937.       --!    Not applicable.
  12938.       --!
  12939.       --! Notes:
  12940.       --!    Not applicable.
  12941.       --!
  12942.       --!-------------------------------------------------------------
  12943.  
  12944.    begin
  12945.  
  12946.       return Position.R;
  12947.  
  12948.    end Range_Component_Of;
  12949.  
  12950.    pragma Page;
  12951.    -------------------------------------------------------------------
  12952.  
  12953.    function Theta_Component_Of (Position : in Polar_Position)
  12954.       return Float is
  12955.  
  12956.       --!-------------------------------------------------------------
  12957.       --!
  12958.       --! Name:
  12959.       --!    Theta_Component_of
  12960.       --!
  12961.       --! Purpose:
  12962.       --!    This function returns the theta component of
  12963.       --!    the position expressed in Range, Theta, and Height.
  12964.       --!
  12965.       --! Parameters:
  12966.       --!    Position
  12967.       --!       is the position of the object with
  12968.       --!       R, Theta, and Height components.
  12969.       --!
  12970.       --! Exceptions:
  12971.       --!    Not applicable.
  12972.       --!
  12973.       --! Notes:
  12974.       --!    Not applicable.
  12975.       --!
  12976.       --!-------------------------------------------------------------
  12977.  
  12978.    begin
  12979.  
  12980.       return Position.Theta;
  12981.  
  12982.    end Theta_Component_Of;
  12983.  
  12984.    pragma Page;
  12985.    -------------------------------------------------------------------
  12986.  
  12987.    function Theta_Component_Of (Position : in Cartesian_Position)
  12988.       return Float is
  12989.  
  12990.       --!-------------------------------------------------------------
  12991.       --!
  12992.       --! Name:
  12993.       --!    Theta_Component_of
  12994.       --!
  12995.       --! Purpose:
  12996.       --!    This function satisfies the Ada compiler
  12997.       --!    with respect to generic instantiations of
  12998.       --!    Generic_Track.
  12999.       --!
  13000.       --! Parameters:
  13001.       --!    Position
  13002.       --!       is the position of the object with
  13003.       --!       R, Theta, and Height components.
  13004.       --!
  13005.       --! Exceptions:
  13006.       --!    Not applicable.
  13007.       --!
  13008.       --! Notes:
  13009.       --!    Not applicable.
  13010.       --!
  13011.       --!-------------------------------------------------------------
  13012.  
  13013.    begin
  13014.  
  13015.       return 0.0;
  13016.  
  13017.    end Theta_Component_Of;
  13018.  
  13019.    pragma Page;
  13020.    -------------------------------------------------------------------
  13021.  
  13022.    function Original_Units_Of (Position : Polar_Position)
  13023.       return Polar_Position is
  13024.  
  13025.       --!-------------------------------------------------------------
  13026.       --!
  13027.       --! Name:
  13028.       --!    Original_Units_of
  13029.       --!
  13030.       --! Purpose:
  13031.       --!    This function returns the original units of the
  13032.       --!    specified Polar_Position.
  13033.       --!
  13034.       --! Parameters:
  13035.       --!    Position
  13036.       --!       is the position in internal units.
  13037.       --!
  13038.       --! Exceptions:
  13039.       --!    Not applicable.
  13040.       --!
  13041.       --! Notes:
  13042.       --!    The value of the range component R is converted from
  13043.       --!    feet to nautical miles.
  13044.       --!
  13045.       --!-------------------------------------------------------------
  13046.  
  13047.    begin
  13048.  
  13049.       return (Position.R / Feet_Per_Nautical_Mile,
  13050.               Position.Theta,
  13051.               Position.Height);
  13052.  
  13053.    end Original_Units_Of;
  13054.  
  13055.    pragma Page;
  13056.    -------------------------------------------------------------------
  13057.  
  13058.    function Original_Units_Of (Position : Cartesian_Position)
  13059.       return Cartesian_Position is
  13060.  
  13061.       --!-------------------------------------------------------------
  13062.       --!
  13063.       --! Name:
  13064.       --!    Original_Units_of
  13065.       --!
  13066.       --! Purpose:
  13067.       --!    This function returns the original units of the
  13068.       --!    specified Cartesian_Position.
  13069.       --!
  13070.       --! Parameters:
  13071.       --!    Position
  13072.       --!       is the position in internal units.
  13073.       --!
  13074.       --! Exceptions:
  13075.       --!    Not applicable.
  13076.       --!
  13077.       --! Notes:
  13078.       --!    The value of the X and Y components are converted from
  13079.       --!    feet to nautical miles.
  13080.       --!
  13081.       --!-------------------------------------------------------------
  13082.  
  13083.    begin
  13084.  
  13085.       return (Position.X / Feet_Per_Nautical_Mile,
  13086.               Position.Y / Feet_Per_Nautical_Mile,
  13087.               Position.Z);
  13088.  
  13089.    end Original_Units_Of;
  13090.  
  13091.    pragma Page;
  13092.    -------------------------------------------------------------------
  13093.  
  13094.    function Generic_Correlation
  13095.       (Position      : in Coordinate_Position;
  13096.        Observed_Time : in Time;
  13097.        Object_Id     : in Object_Identification;
  13098.        Track         : in Track_Data) return Integer is
  13099.  
  13100.       --!-------------------------------------------------------------
  13101.       --!
  13102.       --! Name:
  13103.       --!    Generic_Correlation
  13104.       --!
  13105.       --! Purpose:
  13106.       --!    This generic function determines which if any of the
  13107.       --!    existing active tracks should be correlated with the
  13108.       --!    "hit" recorded by the sensor device. If none correlate,
  13109.       --!    then Generic_Correlation raises the Uncorrelated_Plot
  13110.       --!    exception to signal that a new track should be initiated.
  13111.       --!    Generic_Correlation returns the track number of the
  13112.       --!    correlated track.
  13113.       --!
  13114.       --! Parameters:
  13115.       --!    Position
  13116.       --!       is position components of the observed "hit."
  13117.       --!    Observed_Time
  13118.       --!       is the time at which the "hit" occurred.
  13119.       --!    Object_Id
  13120.       --!       is the object identification (beacon) information
  13121.       --!       received along with the "hit" information.
  13122.       --!    Track
  13123.       --!       is the array of track records.
  13124.       --!
  13125.       --! Exceptions:
  13126.       --!    Uncorrelated_Plot
  13127.       --!       is raised if the "hit" can not be correlated to
  13128.       --!       any existing active track.
  13129.       --!
  13130.       --! Notes:
  13131.       --!    The correlation algorithm first attempts to match the
  13132.       --!    Object_Id with the object ID of any existing track.
  13133.       --!    If none match, then the track whose predicted position
  13134.       --!    at time equal to Observed_Time is closest to Position
  13135.       --!    and lies within the Maximum_Correlation_Distance is
  13136.       --!    correlated.
  13137.       --!
  13138.       --!-------------------------------------------------------------
  13139.  
  13140.       Delta_Time               : Duration;
  13141.       Phi                      : State_Transition_Matrix;
  13142.       Predicted                : Location_Vector;
  13143.       Same_Position            : Coordinate_Position;
  13144.       Other_Position           : Other_Coordinate_Position;
  13145.       Minimum_Distance         : Float;
  13146.       Distance_From_Hit        : Float;
  13147.       No_Tracks_In_Range       : Boolean := True;
  13148.       Track_Id                 : Integer;
  13149.  
  13150.    begin
  13151.       if (Execute_Debug_Code) then
  13152.          Status (Pid, Entry_Exit,
  13153.                  "--> Entry to function Kalman_Track.Correlation");
  13154.          Status (Pid, Parameters,
  13155.                  "Object Identification ", Object_Id);
  13156.       end if;
  13157.  
  13158.       Minimum_Distance := Maximum_Correlation_Distance + 1.0;
  13159.  
  13160.       -- Attempt to correlate based on the object id.
  13161.  
  13162.       if Object_Id /= Null_Object then
  13163.  
  13164.          if (Execute_Debug_Code) then
  13165.             Status (Pid, Internals,
  13166.                     "Correlation based on Object Id");
  13167.          end if;
  13168.  
  13169.          for Index in Track'range loop
  13170.  
  13171.             if Is_Active (Track (Index)) then
  13172.  
  13173.                if Object_Id = Track(Index).Object_Id.all then
  13174.                   if (Execute_Debug_Code) then
  13175.                      Status (Pid, Parameters,
  13176.                              "Based on Object Id, "&
  13177.                              "correlating to Track ",
  13178.                              Integer (Index));
  13179.                      Status (Pid, Entry_Exit,
  13180.                              "<-- Exit from function " &
  13181.                              "Kalman_Track.Correlation");
  13182.                   end if;
  13183.  
  13184.                   return Index;
  13185.                end if;
  13186.             end if;
  13187.          end loop;
  13188.       end if;
  13189.  
  13190.       -- Determine all tracks whose predicted location lies within
  13191.       --  the maximum correlation distance.
  13192.  
  13193.       if (Execute_Debug_Code) then
  13194.          Status (Pid, Internals,
  13195.                  "Determination of tracks within Circle");
  13196.       end if;
  13197.  
  13198.       for Index in Track'range loop
  13199.  
  13200.          if (Execute_Debug_Code) then
  13201.             Status (Pid, Internals,
  13202.                     "Checking Track ", Integer(Index));
  13203.          end if;
  13204.  
  13205.          if Is_Active (Track(Index)) then
  13206.  
  13207.             Delta_Time := Observed_Time -
  13208.                           Track(Index).Last_Observed_Time;
  13209.  
  13210.             if (Execute_Debug_Code) then
  13211.                Status (Pid, Internals,
  13212.                        "Delta Time ", Float (Delta_Time));
  13213.             end if;
  13214.  
  13215.             Phi        := Make_Phi (Delta_Time);
  13216.  
  13217.             if (Execute_Debug_Code) then
  13218.                Status (Pid, Internals,
  13219.                        "State Transition Matrix ", Phi);
  13220.             end if;
  13221.  
  13222.             Predicted  := To_Vector(Phi * Track(Index).Smoothed);
  13223.  
  13224.             if (Execute_Debug_Code) then
  13225.                Status (Pid, Internals,
  13226.                        "Predicted Location ", Predicted);
  13227.             end if;
  13228.  
  13229.             if Track (Index).Coordinates_Are_In_The =
  13230.                Other_Coordinate_System then
  13231.  
  13232.                if (Execute_Debug_Code) then
  13233.                   Status (Pid, Internals,
  13234.                           "Other Coordinate System");
  13235.                end if;
  13236.  
  13237.                Other_Position := Original_Units_Of
  13238.                                  (Aggregate (Predicted (1),
  13239.                                              Predicted (4),
  13240.                                              Predicted (7)));
  13241.  
  13242.                Distance_From_Hit 
  13243.                   := Distance (Other_Position,
  13244.                                Position);
  13245.  
  13246.                if (Execute_Debug_Code) then
  13247.                   Status (Pid, Internals,
  13248.                           "Distance from Hit ",
  13249.                           Distance_From_Hit);
  13250.                end if;
  13251.  
  13252.                if Distance_From_Hit <=
  13253.                   Maximum_Correlation_Distance then
  13254.  
  13255.                   if (Execute_Debug_Code) then
  13256.                      Status (Pid, Internals,
  13257.                              "In Range");
  13258.                   end if;
  13259.  
  13260.                   if No_Tracks_In_Range then
  13261.  
  13262.                      No_Tracks_In_Range := False;
  13263.                      Minimum_Distance := Distance_From_Hit;
  13264.                      Track_Id := Index;
  13265.  
  13266.                   else
  13267.                      if Distance_From_Hit < Minimum_Distance then
  13268.                         Minimum_Distance := Distance_From_Hit;
  13269.                         Track_Id := Index;
  13270.                      end if;
  13271.                   end if;
  13272.                end if;
  13273.             else
  13274.  
  13275.                if (Execute_Debug_Code) then
  13276.                   Status (Pid, Internals,
  13277.                           "Same Coordinate System");
  13278.                end if;
  13279.  
  13280.                Same_Position := Original_Units_Of
  13281.                                 (Aggregate (Predicted (1),
  13282.                                             Predicted (4),
  13283.                                             Predicted (7)));
  13284.  
  13285.                Distance_From_Hit 
  13286.                   := Distance (Same_Position,
  13287.                                Position);
  13288.  
  13289.                if (Execute_Debug_Code) then
  13290.                   Status (Pid, Internals,
  13291.                           "Distance from Hit",
  13292.                           Distance_From_Hit);
  13293.                end if;
  13294.  
  13295.                if Distance_From_Hit <=
  13296.                   Maximum_Correlation_Distance then
  13297.  
  13298.                   if (Execute_Debug_Code) then
  13299.                      Status (Pid, Internals,
  13300.                              "In Range");
  13301.                   end if;
  13302.  
  13303.                   if No_Tracks_In_Range then
  13304.  
  13305.                      No_Tracks_In_Range := False;
  13306.                      Minimum_Distance := Distance_From_Hit;
  13307.                      Track_Id := Index;
  13308.  
  13309.                   else
  13310.                      if Distance_From_Hit < Minimum_Distance then
  13311.                         Minimum_Distance := Distance_From_Hit;
  13312.                         Track_Id := Index;
  13313.                      end if;
  13314.                   end if;
  13315.                end if;
  13316.             end if;
  13317.  
  13318.          end if;
  13319.       end loop;
  13320.  
  13321.       -- No tracks in range - therefore raise UNCORRELATED_PLOT.
  13322.  
  13323.       if No_Tracks_In_Range then
  13324.  
  13325.          if (Execute_Debug_Code) then
  13326.             Status (Pid, Parameters,
  13327.                     "No Tracks in range");
  13328.             Status (Pid, Entry_Exit,
  13329.                     "<-- Exit from function "&
  13330.                     "Kalman_Track.Correlation");
  13331.          end if;
  13332.  
  13333.          raise Uncorrelated_Plot;
  13334.       end if;
  13335.  
  13336.       -- At least one track in range - return closest
  13337.  
  13338.       if (Execute_Debug_Code) then
  13339.          Status (Pid, Parameters,
  13340.                  "Corrrelation to track ", Track_Id);
  13341.          Status (Pid, Entry_Exit,
  13342.                  "<-- Exit from function " &
  13343.                  "Kalman_Track.Correlation");
  13344.       end if;
  13345.  
  13346.       return Track_Id;
  13347.  
  13348.    end Generic_Correlation;
  13349.  
  13350.    pragma Page;
  13351.    -------------------------------------------------------------------
  13352.  
  13353.    function Correlation is
  13354.       new Generic_Correlation
  13355.           (Coordinate_Position       => Polar_Position,
  13356.            Other_Coordinate_Position => Cartesian_Position,
  13357.            Other_Coordinate_System   => Cartesian_System);
  13358.  
  13359.    function Correlation is
  13360.       new Generic_Correlation
  13361.           (Coordinate_Position       => Cartesian_Position,
  13362.            Other_Coordinate_Position => Polar_Position,
  13363.            Other_Coordinate_System   => Polar_System);
  13364.  
  13365.    pragma Page;
  13366.    -------------------------------------------------------------------
  13367.  
  13368.    procedure Generic_Initiate_Track
  13369.       (Location        : in     Coordinate_Location;
  13370.        Observed_Time   : in     Time;
  13371.        Object_Id       : in     Object_Identification;
  13372.        Track           : in out Track_Data;
  13373.        Track_Id        : in out Integer) is
  13374.  
  13375.       --!-------------------------------------------------------------
  13376.       --!
  13377.       --! Name:
  13378.       --!    Generic_Initiate_Track
  13379.       --!
  13380.       --! Purpose:
  13381.       --!    This generic procedure determines whether room exists in
  13382.       --!    the array of track records to initiate a new track. If 
  13383.       --!    so, Generic_Initiate_Track initializes the track record
  13384.       --!    and performs the Kalman_Filter operation Initiate on the
  13385.       --!    new track.
  13386.       --!
  13387.       --! Parameters:
  13388.       --!    Location
  13389.       --!       is the position, velocity, and acceleration of the
  13390.       --!       observed "hit."
  13391.       --!    Observed_Time
  13392.       --!       is the time at which the "hit" was recorded.
  13393.       --!    Object_Id
  13394.       --!       is the object identification information received 
  13395.       --!       with the "hit."
  13396.       --!    Track
  13397.       --!       is the array of track records.
  13398.       --!    Track_Id
  13399.       --!       is the track number of the initiated track.
  13400.       --!
  13401.       --! Exceptions:
  13402.       --!    No_More_Tracks_Available
  13403.       --!       is raised if no room exists to initiate a new track.
  13404.       --!
  13405.       --! Notes:
  13406.       --!    Not applicable.
  13407.       --!
  13408.       --!-------------------------------------------------------------
  13409.  
  13410.       Track_Is_Available : Boolean := False;
  13411.       Null_Location_Vector : constant Location_Vector
  13412.                              := (0.0, others => 0.0);
  13413.  
  13414.    begin
  13415.       if (Execute_Debug_Code) then
  13416.          Status (Pid, Entry_Exit,
  13417.                  "--> Entry to procedure " &
  13418.                  "Kalman_Track.Initiate_Track");
  13419.       end if;
  13420.  
  13421.       for Index in Track'range loop
  13422.  
  13423.          if not Is_Active (Track (Index)) then
  13424.  
  13425.             Track_Is_Available := True;
  13426.             Track_Id := Index;
  13427.             exit;
  13428.          end if;
  13429.       end loop;
  13430.  
  13431.       if Track_Is_Available then
  13432.  
  13433.          if (Execute_Debug_Code) then
  13434.             Status (Pid, Internals,
  13435.                     "Track is available");
  13436.          end if;
  13437.  
  13438.          Track (Track_Id) 
  13439.             := Single_Track'
  13440.                  (State => Active,
  13441.                   Coordinates_Are_In_The
  13442.                      => Input_Coordinate_System,
  13443.                   Object_Id
  13444.                      => new Object_Identification'(Object_Id),
  13445.                   Filter => Initialize,
  13446.                   Updated_Time => Observed_Time,
  13447.                   Smoothed => Null_Location_Vector,
  13448.                   Error_Covariance => (1 .. 9 => (1 .. 9 => 0.0)),
  13449.                   Maneuver_Detector => 0.0,
  13450.                   Predicted => Null_Location_Vector,
  13451.                   Maneuver_Indicator => 0.0,
  13452.                   Coast_Counter => 0,
  13453.                   Last_Observed_Time => Observed_Time,
  13454.                   Last_Observed_Location => Null_Location_Vector);
  13455.  
  13456.          Initiate (Location, Observed_Time,
  13457.                    Track (Track_Id).Smoothed,
  13458.                    Track (Track_Id).Last_Observed_Time,
  13459.                    Track (Track_Id).Predicted);
  13460.  
  13461.          Track (Track_Id).Last_Observed_Location 
  13462.             := Track (Track_Id).Smoothed;
  13463.  
  13464.          Track (Track_Id).Filter := Ready_To_Update;
  13465.  
  13466.       else
  13467.          if (Execute_Debug_Code) then
  13468.             Status (Pid, Internals,
  13469.                     "No More Tracks Available");
  13470.             Status (Pid, Entry_Exit,
  13471.                     "<-- Exit from procedure " &
  13472.                     "Kalman_Track.Initiate_track");
  13473.          end if;
  13474.  
  13475.          raise No_More_Tracks_Available;
  13476.       end if;
  13477.  
  13478.       if (Execute_Debug_Code) then
  13479.          Status (Pid, Parameters,
  13480.                  "New Track assigned to position ", Track_Id);
  13481.          Status (Pid, Entry_Exit,
  13482.                  "<-- Exit from procedure " &
  13483.                  "Kalman_Track.Initiate_track");
  13484.       end if;
  13485.  
  13486.    end Generic_Initiate_Track;
  13487.  
  13488.    pragma Page;
  13489.    -------------------------------------------------------------------
  13490.  
  13491.    procedure Initiate_Track is
  13492.       new Generic_Initiate_Track
  13493.           (Coordinate_Location     => Polar_Location,
  13494.            Input_Coordinate_System => Polar_System);
  13495.  
  13496.    procedure Initiate_Track is
  13497.       new Generic_Initiate_Track
  13498.           (Coordinate_Location     => Cartesian_Location,
  13499.            Input_Coordinate_System => Cartesian_System);
  13500.  
  13501.    pragma Page;
  13502.    -------------------------------------------------------------------
  13503.  
  13504.    procedure Generic_Update_Or_Filter
  13505.       (Location        : in     Coordinate_Location;
  13506.        Observed_Time   : in     Time;
  13507.        Track_Id        : in     Integer;
  13508.        Track           : in out Track_Data) is
  13509.  
  13510.       --!-------------------------------------------------------------
  13511.       --!
  13512.       --! Name:
  13513.       --!    Generic_Update_Or_Filter
  13514.       --!
  13515.       --! Purpose:
  13516.       --!    This generic procedure performs the Kalman Filter
  13517.       --!    operation Update or Filter dependent upon the filter
  13518.       --!    state of the specified track.
  13519.       --!
  13520.       --! Parameters:
  13521.       --!    Location
  13522.       --!       is the position, velocity, and acceleration of the
  13523.       --!       observed "hit."
  13524.       --!    Observed_Time
  13525.       --!       is the time at which the "hit" was recorded.
  13526.       --!    Track_Id
  13527.       --!       is the track number of the specified track.
  13528.       --!    Track
  13529.       --!       is the array of track records.
  13530.       --!
  13531.       --! Exceptions:
  13532.       --!    Not applicable.
  13533.       --!
  13534.       --! Notes:
  13535.       --!    Not applicable.
  13536.       --!
  13537.       --!-------------------------------------------------------------
  13538.  
  13539.    begin
  13540.       if (Execute_Debug_Code) then
  13541.          Status (Pid, Entry_Exit,
  13542.                  "--> Entry to procedure " &
  13543.                  "Kalman_Track.Update_or_Filter");
  13544.       end if;
  13545.  
  13546.       if Track (Track_Id).Filter = Ready_To_Filter then
  13547.  
  13548.          if (Execute_Debug_Code) then
  13549.             Status (Pid, Internals,
  13550.                     "Ready to filter");
  13551.          end if;
  13552.  
  13553.          Filter (Location,
  13554.                  Observed_Time,
  13555.                  Track (Track_Id).Maneuver_Detector,
  13556.                  Track (Track_Id).Smoothed,
  13557.                  Track (Track_Id).Last_Observed_Time,
  13558.                  Track (Track_Id).Error_Covariance,
  13559.                  Track (Track_Id).Predicted,
  13560.                  Track (Track_Id).Maneuver_Indicator);
  13561.  
  13562.       else
  13563.          if (Execute_Debug_Code) then
  13564.             Status (Pid, Internals,
  13565.                     "Ready to Update");
  13566.          end if;
  13567.  
  13568.          Update (Location,
  13569.                  Observed_Time,
  13570.                  Track (Track_Id).Smoothed,
  13571.                  Track (Track_Id).Last_Observed_Time,
  13572.                  Track (Track_Id).Error_Covariance,
  13573.                  Track (Track_Id).Predicted,
  13574.                  Track (Track_Id).Maneuver_Detector);
  13575.  
  13576.          Track (Track_Id).Filter := Ready_To_Filter;
  13577.       end if;
  13578.  
  13579.       if (Execute_Debug_Code) then
  13580.          Status (Pid, Entry_Exit,
  13581.                  "<-- Exit from procedure " &
  13582.                  "Kalman_Track.Update_or_Filter");
  13583.       end if;
  13584.  
  13585.    end Generic_Update_Or_Filter;
  13586.  
  13587.    pragma Page;
  13588.    -------------------------------------------------------------------
  13589.  
  13590.    procedure Update_Or_Filter is
  13591.       new Generic_Update_Or_Filter
  13592.           (Coordinate_Location => Polar_Location);
  13593.  
  13594.    procedure Update_Or_Filter is
  13595.       new Generic_Update_Or_Filter
  13596.           (Coordinate_Location => Cartesian_Location);
  13597.  
  13598.    pragma Page;
  13599.    -------------------------------------------------------------------
  13600.  
  13601.    procedure Generic_Track
  13602.       (Location        : in     Coordinate_Location;
  13603.        Observed_Time   : in     Time;
  13604.        Object_Id       : in     Object_Identification;
  13605.        Cycle_Time      : in     Duration;
  13606.        Track           : in out Track_Data;
  13607.        Track_Id        : in out Integer) is
  13608.  
  13609.       --!-------------------------------------------------------------
  13610.       --!
  13611.       --! Name:
  13612.       --!    Generic_Track
  13613.       --!
  13614.       --! Purpose:
  13615.       --!    This generic procedure correlates the observed Location
  13616.       --!    with an existing track or initiates a new track. It then
  13617.       --!    performs Kalman Filter operations on the specified track.
  13618.       --!    At the end of each Kalman Filter operation, Generic_Track
  13619.       --!    coasts tracks which have not been correlated with "hits"
  13620.       --!    for more than a cycle time of the sensor device.
  13621.       --!
  13622.       --! Parameters:
  13623.       --!    Location
  13624.       --!       is the position, velocity, and acceleration of the
  13625.       --!       observed "hit."
  13626.       --!    Observed_Time
  13627.       --!       is the time at which the "hit" was recorded.
  13628.       --!    Object_Id
  13629.       --!       is the object identification information received 
  13630.       --!       with the "hit."
  13631.       --!    Cycle_Time 
  13632.       --!       is the time it takes the sensor device to make
  13633.       --!       one full pass.
  13634.       --!    Track
  13635.       --!       is the array of track records.
  13636.       --!    Track_Id
  13637.       --!       is the track number of the initiated track.
  13638.       --!
  13639.       --! Exceptions:
  13640.       --!    Mismatched_Coordinate_System
  13641.       --!       is raised if a "hit" is correlated to a track whose
  13642.       --!       matrices are stored in the other coordinate system.
  13643.       --!    No_More_Tracks_Available
  13644.       --!       is raised if a new track should be initiated when
  13645.       --!       no room exists in the Track_Data for a new track.
  13646.       --!
  13647.       --! Notes:
  13648.       --!    An Uncorrelated_Plot exception raised in the Correlation
  13649.       --!    function is handled by initiating a new track.
  13650.       --!
  13651.       --!-------------------------------------------------------------
  13652.  
  13653.       Position              : Coordinate_Position;
  13654.       Difference_In_Theta   : Float;
  13655.       R                     : Float;
  13656.       R_Near_Origin         : Float := 2.0;
  13657.       Pi                    : constant Float := 3.1416;
  13658.       Large_Change_In_Theta : Float := Pi / 4.0;
  13659.  
  13660.    begin
  13661.       if (Execute_Debug_Code) then
  13662.          Status (Pid, Entry_Exit,
  13663.                  "--> Entry to procedure Kalman_Track.Track");
  13664.       end if;
  13665.  
  13666.       begin
  13667.          Track_Id := Correlation (Position_Component_Of (Location),
  13668.                                   Observed_Time,
  13669.                                   Object_Id,
  13670.                                   Track);
  13671.  
  13672.          if Track (Track_Id).Coordinates_Are_In_The =
  13673.             Other_Coordinate_System then
  13674.  
  13675.             if (Execute_Debug_Code) then
  13676.                Status (Pid, Parameters,
  13677.                        "Mismatched Coordinate System");
  13678.                Status (Pid, Entry_Exit,
  13679.                        "<-- Exit from procedure " &
  13680.                        "Kalman_Track.Track");
  13681.             end if;
  13682.  
  13683.             raise Mismatched_Coordinate_System;
  13684.  
  13685.          else
  13686.             if (Execute_Debug_Code) then
  13687.                Status (Pid, Internals,
  13688.                        "Plot correlated to ", Track_Id);
  13689.             end if;
  13690.  
  13691.             if Other_Coordinate_System = Cartesian_System then
  13692.  
  13693.                Position := Position_Component_Of (Location);
  13694.                R := Range_Component_Of (Position);
  13695.                Difference_In_Theta 
  13696.                   := abs (Theta_Component_Of (Position) -
  13697.                           Track (Track_Id).Smoothed (4));
  13698.  
  13699.             else
  13700.  
  13701.                R := R_Near_Origin + 1.0;
  13702.                Difference_In_Theta := 0.0;
  13703.  
  13704.             end if;
  13705.  
  13706.             if R <= R_Near_Origin or
  13707.                Difference_In_Theta >= Large_Change_In_Theta then
  13708.  
  13709.                Initiate (Location, Observed_Time,
  13710.                          Track (Track_Id).Smoothed,
  13711.                          Track (Track_Id).Last_Observed_Time,
  13712.                          Track (Track_Id).Predicted);
  13713.                Track (Track_Id).Filter := Ready_To_Update;
  13714.                Track (Track_Id).Maneuver_Indicator := 0.0;
  13715.  
  13716.             else
  13717.                Update_Or_Filter (Location,
  13718.                                  Observed_Time,
  13719.                                  Track_Id,
  13720.                                  Track);
  13721.  
  13722.             end if;
  13723.  
  13724.             Track (Track_Id).Last_Observed_Location 
  13725.                := Track (Track_Id).Smoothed;
  13726.             Track (Track_Id).Updated_Time := Observed_Time;
  13727.             Track (Track_Id).Coast_Counter := 0;
  13728.  
  13729.          end if;
  13730.  
  13731.       exception
  13732.          when Uncorrelated_Plot =>
  13733.             if (Execute_Debug_Code) then
  13734.                Status (Pid, Internals,
  13735.                        "Uncorrelated Plot");
  13736.             end if;
  13737.  
  13738.             Initiate_Track (Location,
  13739.                             Observed_Time,
  13740.                             Object_Id,
  13741.                             Track,
  13742.                             Track_Id);
  13743.  
  13744.          when others =>
  13745.             if (Execute_Debug_Code) then
  13746.                Status (Pid, Parameters,
  13747.                        "Unhandled Exception");
  13748.                Status (Pid, Entry_Exit,
  13749.                        "<-- Exit from procedure " &
  13750.                        "Kalman_Track.Track");
  13751.             end if;
  13752.             raise ;
  13753.       end;
  13754.  
  13755.       if (Execute_Debug_Code) then
  13756.          Status (Pid, Internals,
  13757.                  "Coast active tracks");
  13758.       end if;
  13759.  
  13760.       Coast (Observed_Time, Cycle_Time, Track);
  13761.  
  13762.       if (Execute_Debug_Code) then
  13763.          Status (Pid, Entry_Exit,
  13764.                  "<-- Exit from procedure " &
  13765.                  "Kalman_Track.Track");
  13766.       end if;
  13767.  
  13768.    end Generic_Track;
  13769.  
  13770.    pragma Page;
  13771.    -------------------------------------------------------------------
  13772.  
  13773.    procedure Cartesian_Track is
  13774.       new Generic_Track
  13775.           (Coordinate_Location     => Cartesian_Location,
  13776.            Coordinate_Position     => Cartesian_Position,
  13777.            Other_Location          => Polar_Location,
  13778.            Other_Coordinate_System => Polar_System);
  13779.  
  13780.    procedure Polar_Track is
  13781.       new Generic_Track
  13782.           (Coordinate_Location     => Polar_Location,
  13783.            Coordinate_Position     => Polar_Position,
  13784.            Other_Location          => Cartesian_Location,
  13785.            Other_Coordinate_System => Cartesian_System);
  13786.  
  13787.    pragma Page;
  13788.    -------------------------------------------------------------------
  13789.  
  13790.    procedure Track
  13791.       (Location      : in     Cartesian_Location;
  13792.        Observed_Time : in     Time;
  13793.        Cycle_Time    : in     Duration;
  13794.        Track         : in out Track_Data;
  13795.        Track_Id      : in out Integer;
  13796.        Object_Id     : in     Object_Identification := Null_Object) is
  13797.  
  13798.       --!-------------------------------------------------------------
  13799.       --!
  13800.       --! Name:
  13801.       --!    Track
  13802.       --!
  13803.       --! Purpose:
  13804.       --!    This procedure correlates the observed Location
  13805.       --!    with an existing track or initiates a new track. It then
  13806.       --!    performs Kalman Filter operations on the specified track.
  13807.       --!    At the end of each Kalman Filter operation, Track
  13808.       --!    coasts tracks which have not been correlated with "hits"
  13809.       --!    for more than a cycle time of the sensor device.
  13810.       --!
  13811.       --! Parameters:
  13812.       --!    Location
  13813.       --!       is the position, velocity, and acceleration of the
  13814.       --!       observed "hit."
  13815.       --!    Observed_Time
  13816.       --!       is the time at which the "hit" was recorded.
  13817.       --!    Cycle_Time 
  13818.       --!       is the time it takes the sensor device to make
  13819.       --!       one full pass.
  13820.       --!    Track
  13821.       --!       is the array of track records.
  13822.       --!    Track_Id
  13823.       --!       is the track number of the initiated track.
  13824.       --!    Object_Id
  13825.       --!       is the object identification information received 
  13826.       --!       with the "hit."
  13827.       --!
  13828.       --! Exceptions:
  13829.       --!    Mismatched_Coordinate_System
  13830.       --!       is raised if a "hit" is correlated to a track whose
  13831.       --!       matrices are stored in the other coordinate system.
  13832.       --!    No_More_Tracks_Available
  13833.       --!       is raised if a new track should be initiated when
  13834.       --!       no room exists in the Track_Data for a new track.
  13835.       --!
  13836.       --! Notes:
  13837.       --!    An Uncorrelated_Plot exception raised in the Correlation
  13838.       --!    function is handled by initiating a new track.
  13839.       --!
  13840.       --!-------------------------------------------------------------
  13841.  
  13842.    begin
  13843.  
  13844.       if (Execute_Debug_Code) then
  13845.          Status (Pid, Entry_Exit,
  13846.                  "--> Entry to procedure Kalman_Track.Track " &
  13847.                  "(Cartesian)");
  13848.       end if;
  13849.  
  13850.       Cartesian_Track (Location,
  13851.                        Observed_Time,
  13852.                        Object_Id,
  13853.                        Cycle_Time,
  13854.                        Track,
  13855.                        Track_Id);
  13856.  
  13857.       if (Execute_Debug_Code) then
  13858.          Status (Pid, Entry_Exit,
  13859.                  "<-- Exit from procedure Kalman_Track.Track " &
  13860.                  "(Cartesian)");
  13861.       end if;
  13862.  
  13863.    end Track;
  13864.  
  13865.    pragma Page;
  13866.    -------------------------------------------------------------------
  13867.  
  13868.    procedure Track
  13869.       (Location      : in     Polar_Location;
  13870.        Observed_Time : in     Time;
  13871.        Cycle_Time    : in     Duration;
  13872.        Track         : in out Track_Data;
  13873.        Track_Id      : in out Integer;
  13874.        Object_Id     : in     Object_Identification := Null_Object) is
  13875.  
  13876.       --!-------------------------------------------------------------
  13877.       --!
  13878.       --! Name:
  13879.       --!    Track
  13880.       --!
  13881.       --! Purpose:
  13882.       --!    This procedure correlates the observed Location
  13883.       --!    with an existing track or initiates a new track. It then
  13884.       --!    performs Kalman Filter operations on the specified track.
  13885.       --!    At the end of each Kalman Filter operation, Track
  13886.       --!    coasts tracks which have not been correlated with "hits"
  13887.       --!    for more than a cycle time of the sensor device.
  13888.       --!
  13889.       --! Parameters:
  13890.       --!    Location
  13891.       --!       is the position, velocity, and acceleration of the
  13892.       --!       observed "hit."
  13893.       --!    Observed_Time
  13894.       --!       is the time at which the "hit" was recorded.
  13895.       --!    Cycle_Time 
  13896.       --!       is the time it takes the sensor device to make
  13897.       --!       one full pass.
  13898.       --!    Track
  13899.       --!       is the array of track records.
  13900.       --!    Track_Id
  13901.       --!       is the track number of the initiated track.
  13902.       --!    Object_Id
  13903.       --!       is the object identification information received 
  13904.       --!       with the "hit."
  13905.       --!
  13906.       --! Exceptions:
  13907.       --!    Mismatched_Coordinate_System
  13908.       --!       is raised if a "hit" is correlated to a track whose
  13909.       --!       matrices are stored in the other coordinate system.
  13910.       --!    No_More_Tracks_Available
  13911.       --!       is raised if a new track should be initiated when
  13912.       --!       no room exists in the Track_Data for a new track.
  13913.       --!
  13914.       --! Notes:
  13915.       --!    An Uncorrelated_Plot exception raised in the Correlation
  13916.       --!    function is handled by initiating a new track.
  13917.       --!
  13918.       --!-------------------------------------------------------------
  13919.  
  13920.    begin
  13921.  
  13922.       if (Execute_Debug_Code) then
  13923.          Status (Pid, Entry_Exit,
  13924.                  "--> Entry to procedure " &
  13925.                  "Kalman_Track.Track (Polar)");
  13926.       end if;
  13927.  
  13928.       Polar_Track (Location,
  13929.                    Observed_Time,
  13930.                    Object_Id,
  13931.                    Cycle_Time,
  13932.                    Track,
  13933.                    Track_Id);
  13934.  
  13935.       if (Execute_Debug_Code) then
  13936.          Status (Pid, Entry_Exit,
  13937.                  "<-- Exit from procedure " &
  13938.                  "Kalman_Track.Track (Polar)");
  13939.       end if;
  13940.  
  13941.    end Track;
  13942.  
  13943.    pragma Page;
  13944.    -------------------------------------------------------------------
  13945.  
  13946.    procedure Track
  13947.       (Location      : in     Cartesian_Location;
  13948.        Observed_Time : in     Time;
  13949.        Cycle_Time    : in     Duration;
  13950.        Track         : in out Track_Data;
  13951.        Track_Id      : in out Integer;
  13952.        Cpu_Time      :    out Duration;
  13953.        Real_Time     :    out Duration;
  13954.        Object_Id     : in     Object_Identification := Null_Object) is
  13955.  
  13956.       --!-------------------------------------------------------------
  13957.       --!
  13958.       --! Name:
  13959.       --!    Track
  13960.       --!
  13961.       --! Purpose:
  13962.       --!    This procedure correlates the observed Location
  13963.       --!    with an existing track or initiates a new track. It then
  13964.       --!    performs Kalman Filter operations on the specified track.
  13965.       --!    At the end of each Kalman Filter operation, Track
  13966.       --!    coasts tracks which have not been correlated with "hits"
  13967.       --!    for more than a cycle time of the sensor device.
  13968.       --!
  13969.       --! Parameters:
  13970.       --!    Location
  13971.       --!       is the position, velocity, and acceleration of the
  13972.       --!       observed "hit."
  13973.       --!    Observed_Time
  13974.       --!       is the time at which the "hit" was recorded.
  13975.       --!    Cycle_Time 
  13976.       --!       is the time it takes the sensor device to make
  13977.       --!       one full pass.
  13978.       --!    Track
  13979.       --!       is the array of track records.
  13980.       --!    Track_Id
  13981.       --!       is the track number of the initiated track.
  13982.       --!    Cpu_Time
  13983.       --!       is the amount of CPU time used to execute the
  13984.       --!       tracking operations.
  13985.       --!    Real_Time
  13986.       --!       is the amount of wall time used to execute the
  13987.       --!       tracking operations.
  13988.       --!    Object_Id
  13989.       --!       is the object identification information received 
  13990.       --!       with the "hit."
  13991.       --!
  13992.       --! Exceptions:
  13993.       --!    Mismatched_Coordinate_System
  13994.       --!       is raised if a "hit" is correlated to a track whose
  13995.       --!       matrices are stored in the other coordinate system.
  13996.       --!    No_More_Tracks_Available
  13997.       --!       is raised if a new track should be initiated when
  13998.       --!       no room exists in the Track_Data for a new track.
  13999.       --!
  14000.       --! Notes:
  14001.       --!    An Uncorrelated_Plot exception raised in the Correlation
  14002.       --!    function is handled by initiating a new track.
  14003.       --!
  14004.       --!-------------------------------------------------------------
  14005.  
  14006.       Cpu_Start,
  14007.       Real_Start,
  14008.       Cpu_Stop,
  14009.       Real_Stop : Duration;
  14010.  
  14011.    begin
  14012.  
  14013.       if (Execute_Debug_Code) then
  14014.          Status (Pid, Entry_Exit,
  14015.                  "--> Entry to procedure Kalman_Track.Track " &
  14016.                  "(Cartesian)");
  14017.       end if;
  14018.  
  14019.       Get_Time (Cpu_Start, Real_Start);
  14020.  
  14021.       Cartesian_Track (Location,
  14022.                        Observed_Time,
  14023.                        Object_Id,
  14024.                        Cycle_Time,
  14025.                        Track,
  14026.                        Track_Id);
  14027.  
  14028.       Get_Time (Cpu_Stop, Real_Stop);
  14029.  
  14030.       Cpu_Time  := Cpu_Stop  - Cpu_Start;
  14031.       Real_Time := Real_Stop - Real_Start;
  14032.  
  14033.       if (Execute_Debug_Code) then
  14034.          Status (Pid, Entry_Exit,
  14035.                  "<-- Exit from procedure Kalman_Track.Track " &
  14036.                  "(Cartesian)");
  14037.       end if;
  14038.  
  14039.    end Track;
  14040.  
  14041.    pragma Page;
  14042.    -------------------------------------------------------------------
  14043.  
  14044.    procedure Track
  14045.       (Location      : in     Polar_Location;
  14046.        Observed_Time : in     Time;
  14047.        Cycle_Time    : in     Duration;
  14048.        Track         : in out Track_Data;
  14049.        Track_Id      : in out Integer;
  14050.        Cpu_Time      :    out Duration;
  14051.        Real_Time     :    out Duration;
  14052.        Object_Id     : in     Object_Identification := Null_Object) is
  14053.  
  14054.       --!-------------------------------------------------------------
  14055.       --!
  14056.       --! Name:
  14057.       --!    Track
  14058.       --!
  14059.       --! Purpose:
  14060.       --!    This procedure correlates the observed Location
  14061.       --!    with an existing track or initiates a new track. It then
  14062.       --!    performs Kalman Filter operations on the specified track.
  14063.       --!    At the end of each Kalman Filter operation, Track
  14064.       --!    coasts tracks which have not been correlated with "hits"
  14065.       --!    for more than a cycle time of the sensor device.
  14066.       --!
  14067.       --! Parameters:
  14068.       --!    Location
  14069.       --!       is the position, velocity, and acceleration of the
  14070.       --!       observed "hit."
  14071.       --!    Observed_Time
  14072.       --!       is the time at which the "hit" was recorded.
  14073.       --!    Cycle_Time 
  14074.       --!       is the time it takes the sensor device to make
  14075.       --!       one full pass.
  14076.       --!    Track
  14077.       --!       is the array of track records.
  14078.       --!    Track_Id
  14079.       --!       is the track number of the initiated track.
  14080.       --!    Cpu_Time
  14081.       --!       is the amount of CPU time used to execute the
  14082.       --!       tracking operations.
  14083.       --!    Real_Time
  14084.       --!       is the amount of wall time used to execute the
  14085.       --!       tracking operations.
  14086.       --!    Object_Id
  14087.       --!       is the object identification information received 
  14088.       --!       with the "hit."
  14089.       --!
  14090.       --! Exceptions:
  14091.       --!    Mismatched_Coordinate_System
  14092.       --!       is raised if a "hit" is correlated to a track whose
  14093.       --!       matrices are stored in the other coordinate system.
  14094.       --!    No_More_Tracks_Available
  14095.       --!       is raised if a new track should be initiated when
  14096.       --!       no room exists in the Track_Data for a new track.
  14097.       --!
  14098.       --! Notes:
  14099.       --!    An Uncorrelated_Plot exception raised in the Correlation
  14100.       --!    function is handled by initiating a new track.
  14101.       --!
  14102.       --!-------------------------------------------------------------
  14103.  
  14104.       Cpu_Start,
  14105.       Real_Start,
  14106.       Cpu_Stop,
  14107.       Real_Stop : Duration;
  14108.  
  14109.    begin
  14110.  
  14111.       if (Execute_Debug_Code) then
  14112.          Status (Pid, Entry_Exit,
  14113.                  "--> Entry to procedure " &
  14114.                  "Kalman_Track.Track (Polar)");
  14115.       end if;
  14116.  
  14117.       Get_Time (Cpu_Start, Real_Start);
  14118.  
  14119.       Polar_Track (Location,
  14120.                    Observed_Time,
  14121.                    Object_Id,
  14122.                    Cycle_Time,
  14123.                    Track,
  14124.                    Track_Id);
  14125.  
  14126.       Get_Time (Cpu_Stop, Real_Stop);
  14127.  
  14128.       Cpu_Time  := Cpu_Stop  - Cpu_Start;
  14129.       Real_Time := Real_Stop - Real_Start;
  14130.  
  14131.       if (Execute_Debug_Code) then
  14132.          Status (Pid, Entry_Exit,
  14133.                  "<-- Exit from procedure " &
  14134.                  "Kalman_Track.Track (Polar)");
  14135.       end if;
  14136.  
  14137.    end Track;
  14138.  
  14139. begin
  14140.  
  14141.    if (Execute_Debug_Code) then
  14142.       Pid := New_Package_Id;
  14143.       Status (Pid, Nothing,
  14144.               "Kalman_Track Package Initialization");
  14145.    end if;
  14146.  
  14147. end Kalman_Track;
  14148. --::::::::::::::::::::::::::::
  14149. --KALMAN-MAIN-BODY.ADA
  14150. --::::::::::::::::::::::::::::
  14151.  
  14152. with Generic_Spelling_Io;
  14153.  
  14154. with Text_Io;
  14155. with Calendar;
  14156. with Kalman_Options;
  14157. with Kalman_Definitions;
  14158. with Kalman_Trig_Lib;
  14159. with Kalman_Track;
  14160. with Kalman_Status;
  14161. with Kalman_Threshold;
  14162. with Kalman_Float_Io;
  14163. with Kalman_Integer_Io;
  14164. with Kalman_Duration_Io;
  14165. with Kalman_Time;
  14166.  
  14167. use Text_Io;
  14168. use Calendar;
  14169. use Kalman_Options;
  14170. use Kalman_Definitions;
  14171. use Kalman_Trig_Lib;
  14172. use Kalman_Track;
  14173. use Kalman_Status;
  14174. use Kalman_Threshold;
  14175. use Kalman_Float_Io;
  14176. use Kalman_Integer_Io;
  14177. use Kalman_Duration_Io;
  14178. use Kalman_Time;
  14179.  
  14180. procedure Kalman_Main is
  14181.  
  14182.    --!----------------------------------------------------------------
  14183.    --!
  14184.    --! Name:
  14185.    --!    Kalman_Main
  14186.    --!
  14187.    --! Purpose:
  14188.    --!    This procedure performs the required setup and 
  14189.    --!    initialization to minimally test the Kalman_Track 
  14190.    --!    Package. It should normally be called from the 
  14191.    --!    containing support environment as a main procedure.
  14192.    --!
  14193.    --! Parameters:
  14194.    --!    Not applicable.
  14195.    --!
  14196.    --! Files:
  14197.    --!    Hit_File
  14198.    --!       contains the observations to be passed to Track.
  14199.    --!
  14200.    --!    Log_File
  14201.    --!       receives the debug messages and data values produced
  14202.    --!       during testing if debug is on. 
  14203.    --!
  14204.    --!    Track_File
  14205.    --!       receives the smoothed locations returned from Track,
  14206.    --!       and final performance data. 
  14207.    --! 
  14208.    --!    Current_Input
  14209.    --!       contains interactive debug commands (if debugging).
  14210.    --!
  14211.    --!    Current_Output
  14212.    --!       contains interactive debug output (if debugging).
  14213.    --!
  14214.    --! Exceptions:
  14215.    --!    Not applicable.
  14216.    --!
  14217.    --! Notes:
  14218.    --!    Kalman_Main exists to simplify testing of the Ada Kalman
  14219.    --!    Filter. It shows one method by which the Ada Kalman Filter
  14220.    --!    can be used, but by no means defines the only method.
  14221.    --!    Kalman_Main accepts hit data as input and produces track
  14222.    --!    files as output. The track file contains the hit, smoothed
  14223.    --!    position, their difference, the maneuver indicator, and, for
  14224.    --!    Cartesian input, the speed of the tracked object.
  14225.    --!
  14226.    --! Contract:
  14227.    --!    Ada Tracking Package Using Kalman Filter Methods
  14228.    --!    Contract No. N66001-85-C-0044 (31 December 1984)
  14229.    --!
  14230.    --! Prepared for:
  14231.    --!    Naval Ocean Systems Center (WIS JPMO)
  14232.    --!    271 Catalina Blvd., Building A-33
  14233.    --!    San Diego, CA 92152
  14234.    --!
  14235.    --! Prepared by:
  14236.    --!    Software Systems Engineering
  14237.    --!    Federal Systems Group
  14238.    --!
  14239.    --!    Sanders Associates, Inc.
  14240.    --!    95 Canal Street
  14241.    --!    Nashua, NH 03061
  14242.    --!
  14243.    --! Author:
  14244.    --!    Jeffrey G. Smith
  14245.    --!
  14246.    --! Changes:
  14247.    --!    04-APR-1985
  14248.    --!       Changed Kalman_Trace to Kalman_Threshold because of 
  14249.    --!       TeleSoft file naming conflict with Kalman_Track.
  14250.    --!
  14251.    --!    04-APR-1985
  14252.    --!       Changed Kalman_Math_Lib to Kalman_Trig_Lib because of 
  14253.    --!       TeleSoft file naming conflict with Kalman_Matrix.
  14254.    --!
  14255.    --!    22-APR-1985
  14256.    --!       Added echo of option values to assist in testing.
  14257.    --!
  14258.    --!    23-APR-1985
  14259.    --!       Changed Track_File Open/Create to Create/Open in order
  14260.    --!       to permit multiple versions on VAX/VMS systems.
  14261.    --!
  14262.    --!    24-APR-1985
  14263.    --!       Commented out GET statements which initialize
  14264.    --!       white noise matrix coefficients and initialized the
  14265.    --!       values used in testing at declaration time.
  14266.    --!
  14267.    --!    29-APR-1985
  14268.    --!       Changed debug threshold on first call of procedure
  14269.    --!       Status to "Nothing".
  14270.    --!
  14271.    --!----------------------------------------------------------------
  14272.  
  14273.    Hit_File      : File_Type;
  14274.    Track_File    : File_Type;
  14275.    Pid           : Package_Id;
  14276.    Cartesian     : Cartesian_Location;
  14277.    Polar         : Polar_Location;
  14278.    Observed_Time : Time;
  14279.    Initial_Time  : Time;
  14280.    Cycle_Time    : Duration;
  14281.    Offset        : Duration;
  14282.    Tracks        : Track_Data (1..5);
  14283.    Track_Id      : Integer;
  14284.    Number_Of_Hits: Integer := 0;
  14285.    Degrees_To_Radians : Float := (3.1416 / 180.0);
  14286.    X_Nmph        : Float;
  14287.    Y_Nmph        : Float;
  14288.    Maneuver_In_Progress_Indicator : Float := 100.0;
  14289.    Maneuvering   : Float := 100.0;
  14290.    Straight_Line : Float := 5.0;
  14291.    Halt          : exception;
  14292.    Cpu_Time      : Duration;
  14293.    Real_Time     : Duration;
  14294.    Cpu_Total     : Duration := 0.0;
  14295.    Real_Total    : Duration := 0.0;
  14296.    Coordinates   : Coordinate_System;
  14297.  
  14298.    package Coordinate_Io is
  14299.       new Generic_Spelling_Io (Coordinate_System);
  14300.    use Coordinate_Io;
  14301.  
  14302.    package Vendor_Io is
  14303.       new Generic_Spelling_Io (Vendor_Type);
  14304.    use Vendor_Io;
  14305.  
  14306.    package Boolean_Io is
  14307.       new Generic_Spelling_Io (Boolean);
  14308.    use Boolean_Io;
  14309.  
  14310. begin
  14311.  
  14312.    if (Execute_Debug_Code) then
  14313.       Pid := New_Package_Id;
  14314.       Status (Pid, Nothing,
  14315.               "Kalman_Main Procedure Initialization");
  14316.       Status (Pid, Entry_Exit,
  14317.               "--> Enter procedure Kalman_Main");
  14318.    end if;
  14319.  
  14320.    Initial_Time := Clock;
  14321.  
  14322.    begin
  14323.       Open (Hit_File, In_File, "HIT$INPUT:");
  14324.    exception
  14325.       when others =>
  14326.  
  14327.          if (Execute_Debug_Code) then
  14328.             Status (Pid, Entry_Exit,
  14329.                     "Exception raised on Open (Hit_File)");
  14330.          end if;
  14331.  
  14332.          Put ("%KALMAN-E-HITEXC, ");
  14333.          Put ("Exception raised on Open (Hit_File)");
  14334.          New_Line;
  14335.  
  14336.          raise Halt;
  14337.    end;
  14338.  
  14339.    begin
  14340.       begin
  14341.          Create (Track_File, Out_File, "TRK$OUTPUT:");
  14342.       exception
  14343.          when others =>
  14344.             Open (Track_File, Out_File, "TRK$OUTPUT:");
  14345.       end;
  14346.  
  14347.    exception
  14348.       when others =>
  14349.          if (Execute_Debug_Code) then
  14350.             Status (Pid, Entry_Exit,
  14351.                     "Exception raised on Open (Track_File)");
  14352.          end if;
  14353.  
  14354.          Put ("%KALMAN-E-TRKEXC, ");
  14355.          Put ("Exception raised on Open (Track_File)");
  14356.          New_Line;
  14357.  
  14358.          raise Halt;
  14359.    end;
  14360.  
  14361.    --!----------------------------------------------------------------
  14362.    --!
  14363.    --! Get (Maneuver_In_Progress_Indicator,
  14364.    --!      Prompt => "%KALMAN-P-MANIND, " &
  14365.    --!      "Value at which maneuver is assumed? ");
  14366.    --!
  14367.    --! Get (Straight_Line,
  14368.    --!      Prompt => "%KALMAN-P-STLCON, " &
  14369.    --!      "Straight_Line White Noise Matrix Constant? ");
  14370.    --!
  14371.    --! Get (Maneuvering,
  14372.    --!      Prompt => "%KALMAN-P-MANCON, " &
  14373.    --!      "Maneuvering White Noise Matrix Constant? ");
  14374.    --!
  14375.    --!----------------------------------------------------------------
  14376.  
  14377.    New_Line (Track_File);
  14378.  
  14379.    Put (Track_File, "Track file for ");
  14380.    Put (Track_File, Date_And_Time (Initial_Time));
  14381.    New_Line (Track_File);
  14382.  
  14383.    New_Line (Track_File);
  14384.  
  14385.    Put (Track_File, "Math library: ");
  14386.    Put (Track_File, Vendor);
  14387.    New_Line (Track_File);
  14388.  
  14389.    Put (Track_File, "Execute debug code: ");
  14390.    Put (Track_File, Execute_Debug_Code);
  14391.    New_Line (Track_File);
  14392.  
  14393.    Put (Track_File, "Use fast matrix operations: ");
  14394.    Put (Track_File, Use_Fast_Matrix_Operations);
  14395.    New_Line (Track_File);
  14396.  
  14397.    New_Line (Track_File);
  14398.  
  14399.    Put (Track_File, "Maximum coast count: ");
  14400.    Put (Track_File, Integer (Maximum_Coast_Count), 1);
  14401.    New_Line (Track_File);
  14402.  
  14403.    Put (Track_File, "Maximum correlation distance: ");
  14404.    Put (Track_File, Float (Maximum_Correlation_Distance), 1);
  14405.    New_Line (Track_File);
  14406.  
  14407.    New_Line (Track_File);
  14408.  
  14409.    Put (Track_File, "Value at which maneuver is " &
  14410.                     "assumed to occur: ");
  14411.    Put (Track_File, Maneuver_In_Progress_Indicator,
  14412.         Fore => 5, Aft => 1, Exp => 0);
  14413.    New_Line (Track_File);
  14414.  
  14415.    Put (Track_File, "Straight-Line White Noise Matrix Constant: ");
  14416.    Put (Track_File, Straight_Line,
  14417.         Fore => 5, Aft => 1, Exp => 0);
  14418.    New_Line (Track_File);
  14419.  
  14420.    Put (Track_File, "Maneuvering White Noise Matrix Constant: ");
  14421.    Put (Track_File, Maneuvering,
  14422.         Fore => 5, Aft => 1, Exp => 0);
  14423.    New_Line (Track_File);
  14424.  
  14425.    begin
  14426.       Get (Hit_File, Cycle_Time);
  14427.       Get (Hit_File, Coordinates);
  14428.    exception
  14429.       when End_Error =>
  14430.          if (Execute_Debug_Code) then
  14431.             Status (Pid, Entry_Exit,
  14432.                     "End of file encountered on Get (Hit_File)");
  14433.          end if;
  14434.  
  14435.          Put ("%KALMAN-E-CYCLE, ");
  14436.          Put ("End of file encountered on Get (Hit_File)");
  14437.          New_Line;
  14438.  
  14439.          raise Halt;
  14440.    end;
  14441.  
  14442.    Put (Track_File, "Cycle Time: ");
  14443.    Put (Track_File, Cycle_Time);
  14444.    New_Line (Track_File);
  14445.  
  14446.    Put (Track_File, "Coordinate System: ");
  14447.    Put (Track_File, Coordinates);
  14448.    New_Line (Track_File, Spacing => 2);
  14449.  
  14450.    Set_Col (Track_File, To => 107);
  14451.    Put (Track_File, "Maneuver");
  14452.    New_Line (Track_File);
  14453.  
  14454.    Put (Track_File, "Track Id      Time     SCN " &
  14455.                     "      SMO     DELTA " &
  14456.                     "    SCN       SMO     DELTA " &
  14457.                     "   SCN      SMO     DELTA " &
  14458.                     "    Indicator");
  14459.  
  14460.    if Coordinates = Cartesian_System then
  14461.       Put (Track_File, "     SPEED");
  14462.    end if;
  14463.  
  14464.    New_Line (Track_File);
  14465.  
  14466.    if (Execute_Debug_Code) then
  14467.       Status (Pid, Internals, "Cycle Time ", Float(Cycle_Time));
  14468.    end if;
  14469.  
  14470.    while not End_Of_File (Hit_File) loop
  14471.  
  14472.       begin
  14473.          Get (Hit_File, Offset);
  14474.  
  14475.          if Coordinates = Polar_System then
  14476.             Get (Hit_File, Polar.Position.R);
  14477.             Get (Hit_File, Polar.Position.Theta);
  14478.             Polar.Position.Theta 
  14479.                := Polar.Position.Theta * Degrees_To_Radians;
  14480.          else
  14481.             Get (Hit_File, Cartesian.Position.X);
  14482.             Get (Hit_File, Cartesian.Position.Y);
  14483.          end if;
  14484.  
  14485.          Number_Of_Hits := Number_Of_Hits + 1;
  14486.  
  14487.       exception
  14488.          when End_Error =>
  14489.             if (Execute_Debug_Code) then
  14490.                Status (Pid, Entry_Exit,
  14491.                         "End of file encountered on Get (Hit_File)");
  14492.             end if;
  14493.  
  14494.             Put ("%KALMAN-E-ENDHIT, ");
  14495.             Put ("End of file encountered on Get (Hit_File)");
  14496.             New_Line;
  14497.  
  14498.             raise Halt;
  14499.       end;
  14500.  
  14501.       if (Execute_Debug_Code) then
  14502.          Status (Pid, Internals, "Time ", Float(Offset));
  14503.       end if;
  14504.  
  14505.       if Coordinates = Polar_System then
  14506.          if (Execute_Debug_Code) then
  14507.             Status (Pid, Internals, "R Position ",
  14508.                     Polar.Position.R);
  14509.             Status (Pid, Internals, "Theta Position ",
  14510.                     Polar.Position.Theta);
  14511.          end if;
  14512.  
  14513.          -- Track the observed object.
  14514.  
  14515.          Track (Polar,
  14516.                 Initial_Time + Offset,
  14517.                 Cycle_Time,
  14518.                 Tracks,
  14519.                 Track_Id,
  14520.                 Cpu_Time,
  14521.                 Real_Time);
  14522.       else
  14523.          if (Execute_Debug_Code) then
  14524.             Status (Pid, Internals, "X Position ",
  14525.                     Cartesian.Position.X);
  14526.             Status (Pid, Internals, "Y Position ",
  14527.                     Cartesian.Position.Y);
  14528.          end if;
  14529.  
  14530.          -- Track the observed object.
  14531.  
  14532.          Track (Cartesian,
  14533.                 Initial_Time + Offset,
  14534.                 Cycle_Time,
  14535.                 Tracks,
  14536.                 Track_Id,
  14537.                 Cpu_Time,
  14538.                 Real_Time);
  14539.       end if;
  14540.  
  14541.       Cpu_Total  := Cpu_Total  + Cpu_Time;
  14542.       Real_Total := Real_Total + Real_Time;
  14543.  
  14544.       if (Execute_Debug_Code) then
  14545.          Status (Pid, Internals, "Performance data");
  14546.          Status (Pid, Internals, "CPU Time ",  Float (Cpu_Time));
  14547.          Status (Pid, Internals, "Real Time ", Float (Real_Time));
  14548.          Status (Pid, Internals, "Track ID ", Track_Id);
  14549.       end if;
  14550.  
  14551.       Put (Track_File, Track_Id, Width =>5);
  14552.       Put (Track_File, "      ");
  14553.       Put (Track_File, Float (Offset),
  14554.            Fore => 4, Aft => 2, Exp => 0);
  14555.       Put (Track_File, ' ');
  14556.  
  14557.       if Coordinates = Polar_System then
  14558.  
  14559.          Put (Track_File, Polar.Position.R,
  14560.               Fore => 4, Aft => 4, Exp => 0);
  14561.          Put (Track_File, ' ');
  14562.          Put (Track_File, Tracks (Track_Id).Smoothed (1) /
  14563.                           Feet_Per_Nautical_Mile,
  14564.               Fore => 4, Aft => 4, Exp => 0);
  14565.          Put (Track_File, ' ');
  14566.          Put (Track_File, Polar.Position.R -
  14567.                           (Tracks (Track_Id).Smoothed (1) /
  14568.                            Feet_Per_Nautical_Mile),
  14569.               Fore => 2, Aft => 4, Exp => 0);
  14570.          Put (Track_File, ' ');
  14571.          Put (Track_File, Polar.Position.Theta,
  14572.               Fore => 4, Aft => 4, Exp => 0);
  14573.          Put (Track_File, ' ');
  14574.          Put (Track_File, Tracks (Track_Id).Smoothed (4),
  14575.               Fore => 4, Aft => 4, Exp => 0);
  14576.          Put (Track_File, ' ');
  14577.          Put (Track_File, Polar.Position.Theta -
  14578.                           Tracks (Track_Id).Smoothed (4),
  14579.               Fore => 2, Aft => 4, Exp => 0);
  14580.          Put (Track_File, ' ');
  14581.          Put (Track_File, Polar.Position.Height /
  14582.               Feet_Per_Nautical_Mile,
  14583.               Fore => 3, Aft => 4, Exp => 0);
  14584.          Put (Track_File, ' ');
  14585.          Put (Track_File, Tracks (Track_Id).Smoothed (7) /
  14586.                           Feet_Per_Nautical_Mile,
  14587.               Fore => 3, Aft => 4, Exp => 0);
  14588.          Put (Track_File, ' ');
  14589.          Put (Track_File, (Polar.Position.Height -
  14590.                            Tracks (Track_Id).Smoothed (7)) /
  14591.                            Feet_Per_Nautical_Mile,
  14592.               Fore => 2, Aft => 4, Exp => 0);
  14593.          Put (Track_File, ' ');
  14594.          Put (Track_File, Tracks (Track_Id).Maneuver_Indicator,
  14595.               Fore => 8, Aft => 4, Exp => 0);
  14596.  
  14597.       else
  14598.  
  14599.          Put (Track_File, Cartesian.Position.X,
  14600.               Fore => 4, Aft => 4, Exp => 0);
  14601.          Put (Track_File, ' ');
  14602.          Put (Track_File, Tracks (Track_Id).Smoothed (1) /
  14603.                           Feet_Per_Nautical_Mile,
  14604.               Fore => 4, Aft => 4, Exp => 0);
  14605.          Put (Track_File, ' ');
  14606.          Put (Track_File, Cartesian.Position.X -
  14607.                           (Tracks (Track_Id).Smoothed (1) /
  14608.                            Feet_Per_Nautical_Mile),
  14609.               Fore => 2, Aft => 4, Exp => 0);
  14610.          Put (Track_File, ' ');
  14611.          Put (Track_File, Cartesian.Position.Y,
  14612.               Fore => 4, Aft => 4, Exp => 0);
  14613.          Put (Track_File, ' ');
  14614.          Put (Track_File, Tracks (Track_Id).Smoothed (4) /
  14615.                           Feet_Per_Nautical_Mile,
  14616.               Fore => 4, Aft => 4, Exp => 0);
  14617.          Put (Track_File, ' ');
  14618.          Put (Track_File, Cartesian.Position.Y -
  14619.                           (Tracks (Track_Id).Smoothed (4) /
  14620.                            Feet_Per_Nautical_Mile),
  14621.               Fore => 2, Aft => 4, Exp => 0);
  14622.          Put (Track_File, ' ');
  14623.          Put (Track_File, Cartesian.Position.Z /
  14624.               Feet_Per_Nautical_Mile,
  14625.               Fore => 3, Aft => 4, Exp => 0);
  14626.          Put (Track_File, ' ');
  14627.          Put (Track_File, Tracks (Track_Id).Smoothed (7) /
  14628.                           Feet_Per_Nautical_Mile,
  14629.               Fore => 3, Aft => 4, Exp => 0);
  14630.          Put (Track_File, ' ');
  14631.          Put (Track_File, (Cartesian.Position.Z -
  14632.                            Tracks (Track_Id).Smoothed (7)) /
  14633.                            Feet_Per_Nautical_Mile,
  14634.               Fore => 2, Aft => 4, Exp => 0);
  14635.          Put (Track_File, ' ');
  14636.          Put (Track_File, Tracks (Track_Id).Maneuver_Indicator,
  14637.               Fore => 8, Aft => 4, Exp => 0);
  14638.  
  14639.          X_Nmph := Tracks (Track_Id).Smoothed (2) /
  14640.                    Feet_Per_Nautical_Mile *
  14641.                    Seconds_Per_Hour;
  14642.          Y_Nmph := Tracks (Track_Id).Smoothed (5) /
  14643.                    Feet_Per_Nautical_Mile *
  14644.                    Seconds_Per_Hour;
  14645.  
  14646.          Put (Track_File, Sqrt (X_Nmph ** 2 + Y_Nmph ** 2),
  14647.               Fore => 8, Aft => 1, Exp => 0);
  14648.  
  14649.       end if;
  14650.  
  14651.       New_Line (Track_File);
  14652.  
  14653.       if (Number_Of_Hits rem 5 = 0) then
  14654.          New_Line (Track_File);
  14655.       end if;
  14656.  
  14657.       if abs (Tracks (Track_Id).Maneuver_Indicator) >
  14658.          Maneuver_In_Progress_Indicator then
  14659.  
  14660.          Tracks (Track_Id).Maneuver_Detector := Maneuvering;
  14661.       else
  14662.          Tracks (Track_Id).Maneuver_Detector := Straight_Line;
  14663.       end if;
  14664.  
  14665.    end loop;
  14666.  
  14667.    New_Line (Track_File);
  14668.  
  14669.    Put (Track_File, "     Performance summary:");
  14670.    New_Line (Track_File);
  14671.  
  14672.    Put (Track_File, "        Number of radar hits: ");
  14673.    Put (Track_File, Number_Of_Hits, 1);
  14674.    New_Line (Track_File);
  14675.  
  14676.    Put (Track_File, "        CPU Time / Number of Hits: ");
  14677.    Put (Track_File, Float (Cpu_Total) / Float (Number_Of_Hits), 1);
  14678.    Put (Track_File, " seconds");
  14679.    New_Line (Track_File);
  14680.  
  14681.    Put (Track_File, "        Real Time / Number of Hits: ");
  14682.    Put (Track_File, Float (Real_Total) / Float (Number_Of_Hits), 1);
  14683.    Put (Track_File, " seconds");
  14684.    New_Line (Track_File);
  14685.  
  14686.    if (Execute_Debug_Code) then
  14687.       Status (Pid, Entry_Exit, "Performance summary");
  14688.       Status (Pid, Entry_Exit, "Number of hits ", Number_Of_Hits);
  14689.  
  14690.       Status (Pid, Entry_Exit, "CPU Time / Number of Hits ",
  14691.               Float (Cpu_Total) / Float (Number_Of_Hits));
  14692.  
  14693.       Status (Pid, Entry_Exit, "Real Time / Number of Hits ",
  14694.               Float (Real_Total) / Float (Number_Of_Hits));
  14695.  
  14696.       Status (Pid, Entry_Exit, "<-- Exit procedure Kalman_Main");
  14697.    end if;
  14698.  
  14699.    if Is_Open (Hit_File) then
  14700.       Close (Hit_File);
  14701.    end if;
  14702.  
  14703.    if Is_Open (Track_File) then
  14704.       Close (Track_File);
  14705.    end if;
  14706.  
  14707.    if Is_Open (Log_File) then
  14708.       Close (Log_File);
  14709.    end if;
  14710.  
  14711. exception
  14712.    when others =>
  14713.       if (Execute_Debug_Code) then
  14714.          Status (Pid, Entry_Exit,
  14715.                  "Exception raised in Kalman_Main");
  14716.          Status (Pid, Entry_Exit,
  14717.                  "<-- Exit procedure Kalman_Main");
  14718.       end if;
  14719.  
  14720.       Put ("%KALMAN-E-EXCPTN, ");
  14721.       Put ("Exception raised in Kalman_Main");
  14722.       New_Line;
  14723.  
  14724.       if Is_Open (Hit_File) then
  14725.          Close (Hit_File);
  14726.       end if;
  14727.  
  14728.       if Is_Open (Track_File) then
  14729.          Close (Track_File);
  14730.       end if;
  14731.  
  14732.       if Is_Open (Log_File) then
  14733.          Close (Log_File);
  14734.       end if;
  14735.  
  14736. end Kalman_Main;
  14737.