File : minifuns-ops.ads


with Ada.Text_IO;
use Ada.Text_IO;

generic

-------------------- begin_include scalars Scalar

  type Scalar is private;

--- addition and multiplication
  with function IsZero(S: Scalar) return Boolean is  <>;
  with procedure SetZero(S: out Scalar) is <>;
  with procedure Neg(S: in out Scalar) is <>;
  with procedure Neg(S1: in Scalar; S2: out Scalar) is <>;
  with function "-"(S: Scalar) return Scalar is <>;
  with procedure Add(S1: in Scalar; S2: in out Scalar) is <>;
  with procedure Sum(S1,S2: in Scalar; S3: out Scalar) is <>;
  with function "+"(S1,S2: Scalar) return Scalar is <>;
  with procedure Sub(S1: in Scalar; S2: in out Scalar) is <>;
  with procedure Diff(S1,S2: in Scalar; S3: out Scalar) is <>;
  with function "-"(S1,S2: Scalar) return Scalar is <>;
  with procedure Mult(I: in Integer; S: in out Scalar) is <>;
  with procedure Prod(I: in Integer; S1: in Scalar; S2: out Scalar) is <>;
  with function "*"(I: Integer; S: Scalar) return Scalar is <>;
  with procedure MultAdd(I: Integer; S1: in Scalar; S2: in out Scalar) is <>;
  with procedure Mult(S1: in Scalar; S2: in out Scalar) is <>;
  with procedure Prod(S1,S2: in Scalar; S3: out Scalar) is <>;
  with function "*"(S1,S2: Scalar) return Scalar is <>;
  with procedure MultAdd(S1,S2: in Scalar; S3: in out Scalar) is <>;
  with function "**"(S: Scalar; I: Integer) return Scalar is <>;

--- conversion and i/o
  with function Scal(K: Integer) return Scalar is <>;
  with function Scal(R: Rep) return Scalar is <>;
  with procedure ShowType(S: in Scalar) is <>;
  with procedure Show1(N: in String; S: in Scalar) is <>;
  with procedure Show2(N: in String; S,S2: in Scalar) is <>;
  with procedure Get(F: in File_Type; S: out Scalar; Decimal: in Boolean := False) is <>;
  with procedure Put(F: in File_Type; S: in Scalar; Decimal: in Boolean := False) is <>;
-------------------- end_include scalars

-------------------- begin_include scalars-more Scalar

--- basic
  with function IsNumeric(S: Scalar) return Boolean is <>;
  with function IsSharp(S: Scalar) return Boolean is <>;
  with function IsNumbers(S: Scalar) return Boolean is <>;
  with procedure ModNumbers(S: in out Scalar) is <>;
  with procedure ToBalls(S: in out Scalar) is <>;
  with function Approx(S: Scalar) return Rep is <>;

--- sets
  with function Center0(S: Scalar) return Boolean is <>;
  with function Contains0(S: Scalar) return Boolean is <>;
  with function Contains(S1,S2: Scalar) return Boolean is <>;
  with function BallAt0(R: Rep) return Scalar is <>;
  with function BallAt0(S: Scalar) return Scalar is <>;
  with function DiskAt0(R: Rep) return Scalar is <>;
  with function DiskAt0(S: Scalar) return Scalar is <>;
  with function Disk(R1,R2: Rep) return Scalar is <>;
  with function Disk(S: Scalar) return Scalar is <>;
  with function Center(S: Scalar) return Scalar is <>;
  with function CenterDisk(S: Scalar) return Scalar is <>;
  with function ModCenter(S: Scalar) return Scalar is <>;
  with function Union(S1,S2: Scalar) return Scalar is <>;
  with function Intersection(S1,S2: Scalar) return Scalar is <>;

--- order
  with function "<"(S1,S2: Scalar) return Boolean is <>;
  with function "<="(S1,S2: Scalar) return Boolean is <>;
  with function ">="(S1,S2: Scalar) return Boolean is <>;
  with function ">"(S1,S2: Scalar) return Boolean is <>;
  with function Min(S1,S2: Scalar) return Scalar is <>;
  with function Max(S1,S2: Scalar) return Scalar is <>;
  with function Inf(S: Scalar) return Rep is <>;
  with function Sup(S: Scalar) return Rep is <>;

--- functions
  with function Norm(S: Scalar) return Scalar is <>;
  with function MaxNorm(S: Scalar) return Radius is <>;
  with function Sqr(S: Scalar) return Scalar is <>;
  with function "*"(R: Rep; S: Scalar) return Scalar is <>;
  with function "/"(S: Scalar; R: Rep) return Scalar is <>;
  with function Inv(S: Scalar) return Scalar is <>;
  with function "/"(S1,S2: Scalar) return Scalar is <>;
  with function Exp(S: Scalar) return Scalar is <>;
  with function Log(S: Scalar) return Scalar is <>;
  with function Sqrt(S: Scalar) return Scalar is <>;

-------------------- end_include scalars-more

package MiniFuns.Ops is

  pragma Elaborate_Body;

  type Vec3 is            --  simple vector
    record                --  also function A*U+B*V+C (if U,V are variables)
      A,B,C: Scalar;
    end record;

  type Mat3 is            --  special 3x3 matrix
    record                --  transposed:
      U: Vec3;            --  U.A  U.B  U.C
      V: Vec3;            --  V.A  V.B  V.C
    end record;           --   0    0    1

  subtype Bas3 is Mat3;   --  Basis

  function Det(B: Mat3) return Scalar;
  procedure Normalize(B: in out Bas3);
  procedure Translate(R0,S0: in Scalar; F: in out Vec3);
  procedure Prod(B: in Mat3; W1: in Vec3; W2: out Vec3);
  procedure Prod(B1,B2: in Mat3; B3: out Mat3);
  procedure Inv(B: in out Mat3);
  procedure Scale(S: in Scalar; B: in out Bas3);
  procedure Center(B: in out Bas3; R0,S0: out Scalar);
  function Dom(U,V: Vec3; R: RadPair) return RadPair;  -- bounds on U and V to fit size R
  procedure Show1(N: in String; W: in Vec3);
  procedure Show1(N: in String; B: in Mat3);

--- args ops

  function InvDet(A: Args) return Scalar;
  procedure Approx(B: in Bas3; A: out Args);
  procedure Convert(A: in Args; B: out Bas3);
  procedure Coord(A1,A2: in Args; B: out Mat3);  -- express A1 in variables A2
  function CoordT2(A: Args) return Vec3;         -- express T*T in variables A
  function CoordS1(A: Args) return Vec3;         -- express S in variables A
  procedure Scale(S: in Scalar; A1,A2: in Args; B: out Mat3);   -- scaling change of variables

  procedure ValTS(T,S: in Scalar; A: in Args; U,V: out Scalar); -- compute U,V from T,S
  procedure Val(X,Y: in Scalar; A: in Args; U,V: out Scalar);   -- compute U,V from X,Y
  function ValTSRadii(T,S: Scalar; A: Args) return RadPair;     -- size of corresponding U,V
  function ValRadii(X,Y: Scalar; A: Args) return RadPair;       -- size of corresponding U,V
  function ValS1(U,V: Scalar; A: Args) return Scalar;           -- value of S, given U,V
  function ValT2(U,V: Scalar; A: Args) return Scalar;           -- value of T*T, given U,V

  function TNorm(A: Args; R: RadPair) return Scalar;                   -- norm factor rho_t
  function TNorm(D: Domain) return Scalar;                             -- norm factor rho_t
  procedure CheckDomainTS(E: in String; D: in Domain; T,S: in Scalar); -- check if T,S in domain
  procedure CheckDomain(E: in String; D: in Domain; X,Y: in Scalar);   -- check if X,Y in domain

private

  Scal_Zero:     constant Scalar  := Scal(0);
  Scal_One:      constant Scalar  := Scal(1);
  M_Trunc:       constant Boolean := IsNumeric(Scal_Zero);

  pragma Inline (InvDet);

end MiniFuns.Ops;