     with ConsAK;
     with FileAK; use FileAK; -- for Load and Save
     with InteAK;
     with MathAK;

     package body A83_014_Vector is
     ----------------------------------------------------------------------
     ----------------------------------------------------------------------

     function "*" (
       F : float;
       V : Vector_Type )
       return Vector_Type is
     ----------------------------------------------------------------------
       Temp : Vector_Type ( V'range );
     begin
       for index in V'range loop
	 Temp ( index ) := F * V ( index );
       end loop;
       return Temp;
     end "*";

     function "/" (
       V : Vector_Type;
       F : float )
       return Vector_Type is
     ----------------------------------------------------------------------
       Temp : Vector_Type ( V'range ) := V;
     begin
       for Index in V'range loop
	 Temp ( Index ) := Temp ( Index ) / F;
       end loop;
       return Temp;
     end "/";

     function "-" (
       V : Vector_Type )
       return Vector_Type is
     ----------------------------------------------------------------------
       Temp : Vector_Type ( V'range );
     begin
       for index in V'range loop
	 Temp ( index ) := - V ( index );
       end loop;
       return Temp;
     end "-";

     function "-" (
       V1, V2 : Vector_Type )
       return Vector_Type is
     ----------------------------------------------------------------------
       Temp : Vector_Type ( V1'range );
     begin
       for index in Temp'range loop
	 Temp ( index ) := V1 ( index ) - V2 ( index );
       end loop;
       return Temp;
     end "-";

     function "-" (
       V : Vector_Type;
       F : float )
       return Vector_Type is
     ----------------------------------------------------------------------
       Temp : Vector_Type ( V'range );
     begin
       for index in V'range loop
	 Temp ( index ) := V ( index ) - F;
       end loop;
       return Temp;
     end "-";

     function "+" (
       V1, V2 : Vector_Type )
       return Vector_Type is
     ----------------------------------------------------------------------
       Temp : Vector_Type ( V1'range );
     begin
       for index in Temp'range loop
	 Temp ( index ) := V1 ( index ) + V2 ( index );
       end loop;
       return Temp;
     end "+";

     procedure Ask (
       V      : in out Vector_Type;
       Prompt : in     string ) is
     ----------------------------------------------------------------------
     begin
       Put_Line ( Prompt );
       for index in V'range loop
	 Get ( V ( index ) );
       end loop;
       ConsAK.Flush;
     end Ask;

     function Concatenate (
       V1, V2 : Vector_Type )
       return Vector_Type is
     ----------------------------------------------------------------------
     -- Example:  V1 ( -3..1 ), V2 ( -6..-4 ) ==> V ( -3..4 )
     -- Example:  V1 (  1..3 ), V2 (  1..3  ) ==> V (  1..6 )
     ----------------------------------------------------------------------
     V : Vector_Type ( V1'first..( V1'first
	 + abs ( V1'last - V1'first ) + abs ( V2'last - V2'first ) + 1 ) );
     begin
       for index in V1'range loop
	 V ( index ) := V1 ( index );
       end loop;
       for index in V2'range loop
	 V ( V1'last + 1 - V2'first + index ) := V2 ( index );
       end loop;
       return V;
     end Concatenate;

     procedure Demo is
     ---------------------------------------------------------------------------
       Default :          natural :=  1;
       Min     : constant natural :=  0;
       Max     : constant natural := 16;
       Option  :          natural;
     begin
       loop
	 Put_Line ( Copyright );
	 Put_Line ( Description );
	 New_Line;
	 Put_Line ( " 0 = Quit" );
	 Put_Line ( " 1 = *" );
	 Put_Line ( " 2 = /" );
	 Put_Line ( " 3 = - (negation)" );
	 Put_Line ( " 4 = - (vector/vector subtraction)" );
	 Put_Line ( " 5 = - (vector/float subtraction)" );
	 Put_Line ( " 6 = Ask" );
	 Put_Line ( " 7 = Concatenate" );
	 Put_Line ( " 8 = Dot" );
	 Put_Line ( " 9 = Fill" );
	 Put_Line ( "10 = Load" );
	 Put_Line ( "11 = Max" );
	 Put_Line ( "12 = Min" );
	 Put_Line ( "13 = Put_Line ( Vector_Integer_Type )" );
	 Put_Line ( "14 = Put_Line ( Vector_Type )" );
	 Put_Line ( "15 = Save" );
	 Put_Line ( "16 = Sum" );
	 New_Line;
	 Option := InteAK.Ask_Nat ( "Option ", Default, Min, Max );
	 Default := Option + 1;
	 if Default > Max then
	   Default := Min;
	 end if;
	 case Option is
	   when  0 => exit;
	   when others =>
	     Put_Line (
	       "No demonstrations are currently available." );
--             "The demonstration of that option is currently not available." );
	 end case;
	 ConsAK.Pause;
	 New_Line;
       end loop;
     end Demo;

     function Dot (
       V1, V2 : Vector_Type )
       return float is
     ----------------------------------------------------------------------
     -- V1 and V2 need to be of the same range.
     -- Same size ranges but different ( -3..-1 and +1..+3 ) should be
     --   added later.
     ----------------------------------------------------------------------
       D : float := 0.0;
     begin
       for index in V1'range loop
	 D := D + V1 ( index ) * V2 ( index );
       end loop;
       return D;
     end Dot;

     function Fill (
       V : Vector_Type;
       F : float := 0.0 )
       return Vector_Type is
     ----------------------------------------------------------------------
       V_New : Vector_Type ( V'range ) := ( others => F );
     begin
       return V_New;
     end Fill;

     procedure Load (
       V         :    out Vector_Type;
       File_Name : in     string ) is
     ----------------------------------------------------------------------
       File : File_Type;
     begin
       V := ( others => 0.0 );
       Open ( File, In_File, File_Name );
       for Index in V'range loop
	 exit when End_Of_File ( File );
	 Get ( File, V ( Index ) );
       end loop;
       Close ( File );
     end Load;

     function Max (
       V : Vector_Type )
       return float is
     ----------------------------------------------------------------------
       Temp : float;
     begin
       Temp := V ( V'first );
       for Index in V'range loop
	 if V ( Index ) > Temp then
	   Temp := V ( Index );
	 end if;
       end loop;
       return Temp;
     end Max;

     function Max_Index (
       V : Vector_Type )
       return integer is
     ----------------------------------------------------------------------
       Temp_Max   :  float;
       Temp_Index :  integer := V'first;
     begin
       Temp_Max := V ( V'first );
       for Index in V'range loop
	 if V ( Index ) > Temp_Max then
	   Temp_Max := V ( Index );
	   Temp_Index := Index;
	 end if;
       end loop;
       return Temp_Index;
     end Max_Index;

     function Mean (
       V : Vector_Type )
       return float is
     ----------------------------------------------------------------------
     begin
       return Sum ( V ) / float ( V'length );
     end Mean;

     function Min (
       V : Vector_Type )
       return float is
     ----------------------------------------------------------------------
       Temp : float;
     begin
       Temp := V ( V'first );
       for Index in V'range loop
	 if V ( Index ) < Temp then
	   Temp := V ( Index );
	 end if;
       end loop;
       return Temp;
     end Min;

     function Min_Index (
       V : Vector_Type )
       return integer is
     ----------------------------------------------------------------------
       Temp_Min   :  float;
       Temp_Index :  integer := V'first;
     begin
       Temp_Min := V ( V'first );
       for Index in V'range loop
	 if V ( Index ) < Temp_Min then
	   Temp_Min := V ( Index );
	   Temp_Index := Index;
	 end if;
       end loop;
       return Temp_Index;
     end Min_Index;

     function Norm (
       V : Vector_Type )
       return float is
     ----------------------------------------------------------------------
       Temp : float := 0.0;
     begin
       for Index in V'range loop
	 Temp := Temp + V ( Index ) ** 2;
       end loop;
       return MathAK."**" ( Temp, 0.5 ); -- Square root of Temp
     end Norm;

     procedure Put (
       V : in Vector_Integer_Type ) is
     ----------------------------------------------------------------------
     begin
       for index in V'range loop
	 Put ( integer'image ( V ( index ) ) );
	 Put ( ' ' );
       end loop;
     end Put;

     procedure Put (
       File : in     File_Type;
       V    : in     Vector_Type;
       Fore : in     Field := Default_Fore;
       Aft  : in     Field := Default_Aft;
       Exp  : in     Field := Default_Exp ) is
     ----------------------------------------------------------------------
     begin
       for index in V'range loop
	 Put ( File, V ( index ), Fore, Aft, Exp );
	 Put ( File, ' ' );
       end loop;
     end Put;

     procedure Put (
       V    : in     Vector_Type;
       Fore : in     Field := Default_Fore;
       Aft  : in     Field := Default_Aft;
       Exp  : in     Field := Default_Exp ) is
     ----------------------------------------------------------------------
     begin
       for index in V'range loop
	 Put ( V ( index ), Fore, Aft, Exp );
	 Put ( ' ' );
       end loop;
     end Put;

     procedure Put_Line (
       V : in Vector_Integer_Type ) is
     ----------------------------------------------------------------------
     begin
       Put ( V );
       New_Line;
     end Put_Line;

     procedure Put_Line (
       File : in     File_Type;
       V    : in     Vector_Type;
       Fore : in     Field := Default_Fore;
       Aft  : in     Field := Default_Aft;
       Exp  : in     Field := Default_Exp ) is
     ----------------------------------------------------------------------
     begin
       Put ( File, V, Fore, Aft, Exp );
       New_Line ( File );
     end Put_Line;

     procedure Put_Line (
       V    : in     Vector_Type;
       Fore : in     Field := Default_Fore;
       Aft  : in     Field := Default_Aft;
       Exp  : in     Field := Default_Exp ) is
     ----------------------------------------------------------------------
     begin
       Put ( V, Fore, Aft, Exp );
       New_Line;
     end Put_Line;

     procedure Save (
       V         : in     Vector_Type;
       File_Name : in     string ) is
     ----------------------------------------------------------------------
       File : File_Type;
     begin
       Create ( File, Out_File, File_Name );
       for Index in V'range loop
	 Put ( File, V ( Index ) );
	 New_Line ( File );
       end loop;
       Close ( File );
     end Save;

     function Sum (
       V : Vector_Type )
       return float is
     ----------------------------------------------------------------------
       Temp : float := 0.0;
     begin
       for Index in V'range loop
	 Temp := Temp + V ( Index );
       end loop;
       return Temp;
     end Sum;

     function TanH (
       V : Vector_Type )
       return Vector_Type is
     ----------------------------------------------------------------------
       TanH_V : Vector_Type ( V'range );
     begin
       for Index in V'range loop
	 TanH_V ( Index ) := MathAK.TanH ( V ( Index ) );
       end loop;
       return TanH_V;
     end TanH;

     ----------------------------------------------------------------------
     ----------------------------------------------------------------------
     end A83_014_Vector;
