with Matrices;

pragma Elaborate_All (Matrices);

generic

  type Scalar is private;

  with function "="(S1,S2: Scalar) return Boolean is <>;
  with function IsZero(S: Scalar) return Boolean is  <>;
  with function IsReal(S: Scalar) return Boolean is  <>;
  with procedure SetZero(S: in out Scalar) is <>;
  with procedure Assign(I: in Integer; S: in out Scalar) is <>;
  with procedure Copy(S1: in Scalar; S2: in out Scalar) is <>;
  with procedure Swap(S1,S2: in out Scalar) is <>;
  with procedure Neg(S: in out Scalar) is <>;
  with procedure Neg(S1: in Scalar; S2: in out Scalar) is <>;
  with procedure Add(S1: in Scalar; S2: in out Scalar) is <>;
  with procedure Sum(S1,S2: in Scalar; S3: in out Scalar) is <>;
  with procedure Sub(S1: in Scalar; S2: in out Scalar) is <>;
  with procedure Diff(S1,S2: in Scalar; S3: in out Scalar) is <>;
  with procedure Mult(S1: in Scalar; S2: in out Scalar) is <>;
  with procedure Prod(S1,S2: in Scalar; S3: in out Scalar) is <>;
  with procedure AddProd(S1,S2: in Scalar; S3,Tmp: in out Scalar) is <>;
  with procedure Real_Part(S: in out Scalar) is <>;
  with procedure Imag_Part(S: in out Scalar) is <>;
  with procedure Adjoint(S: in out Scalar) is <>;
  with procedure Adjoint(S1: in Scalar; S2: in out Scalar) is <>;
  with procedure Show1(N: in String; S: in Scalar; Whatever: in Boolean := True) is <>;
  with procedure Show2(N: in String; S1,S2: in Scalar; Whatever: in Boolean := True) is <>;
  with procedure Put(F: in File_Type; S: in Scalar; Decimal: in Boolean := False) is <>;
  with procedure Get(F: in File_Type; S: in out Scalar; Decimal: in Boolean := False) is <>;
  with procedure Proper_Rounding is <>;

  with package SM is new Matrices (Scalar => Scalar);

  with procedure Mult(S: in Scalar; C: in out Component) is <>;
  with procedure Prod(S: in Scalar; C1: in Component; C2: in out Component) is <>;
  with procedure AddProd(S: in Scalar; C1: in Component; C2: in out Component) is <>;
  with procedure AddProd(C1,C2: in Component; S: in out Scalar) is <>;

package Vectors.Ops is

  procedure Mult(S: in Scalar; V: in out Vector);
  procedure Prod(S: in Scalar; V1: in Vector; V2: in out Vector);
  function "*"(S: Scalar; V: Vector) return Vector;
  procedure AddProd(S: in Scalar; V1: in Vector; V2: in out Vector);
  procedure ScalProd(V1,V2: in Vector; S: in out Scalar);
  function "*"(V1,V2: Vector) return Scalar;

  use SM;

  procedure Mult(A: in Matrix; V,Tmp: in out Vector);
  procedure Mult(A: in Matrix; V: in out Vector);
  procedure Prod(A: in Matrix; V1: in Vector; V2: in out Vector);
  function "*"(A: Matrix; V: Vector) return Vector;
  procedure AddProd(A: in Matrix; V1: in Vector; V2: in out Vector);
  procedure TransProd(A: in Matrix; V1: in Vector; V2: in out Vector);  -- V2 := (A^transpose)*V1

  VProd_Parallel: Boolean := False; --- applies only to AddProd

private

  procedure AddProd_Parallel(A: in Matrix; V1: in Vector; V2: in out Vector; NT: in Positive);

  Task_Error: Boolean := False;

end Vectors.Ops;
