with Ada.Text_IO, Logicals, Scalars, Ints, Rationals, Flts.Std, Flt_Matrices, Flt_Vectors, Rationals;
use Ada.Text_IO, Logicals, Scalars, Ints, Rationals, Flts, Rationals;
with Recycling, Matrices, Vectors, Matrices.More, Vectors.More, Vectors.Ops, Generic_DFT;

pragma Elaborate_All (Ada.Text_IO,Logicals,Scalars,Ints,Rationals,Flts, Flt_Matrices,Flt_Vectors);
pragma Elaborate_All (Recycling,Matrices,Vectors,Matrices.More,Vectors.More, Generic_DFT);

generic

  CDeg: in Positive;  --- max degree
  RadC: in Radius;    --- default domain

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

  type Scalar is private;

  --- basic
  with function Info(Dummy: Scalar) return Scalar_Info is <>;
  with function IsSharp(S: Scalar) return Boolean is <>;
  with function IsZero(S: Scalar) return Boolean is <>;
  with function "="(S1,S2: Scalar) return Boolean is <>;
  with procedure SetZero(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 <>;

  --- sets
  with function Center0(S: Scalar) return Boolean is <>;
  with function Contains0(S: Scalar) return Logical is <>;
  with function Contains(S1,S2: Scalar) return Logical is <>; -- S1 constains S2
  with procedure BallAt0(R: in Flt; S: in out Scalar) is <>;
  with function BallAt0(R: Flt) return Scalar is <>;
  --  with procedure DiskAt0(R: in Flt; S: in out Scalar) is <>;
  --  with function DiskAt0(R: Flt) return Scalar is <>;
  with procedure ToErr(S: in out Scalar) is <>;
  with procedure ToErr(S1: in Scalar; S2: in out Scalar) is <>;
  with function ToErr(S: Scalar) return Scalar is <>;
  with procedure Center(S: in out Scalar) is <>;
  with procedure Center(S1: in Scalar; S2: in out Scalar) is <>;
  with function Center(S: Scalar) return Scalar is <>;
  with procedure ModCenter(S: in out Scalar) is <>;
  with procedure ModCenter(S1: in Scalar; S2: in out Scalar) is <>;
  with function ModCenter(S: Scalar) return Scalar is <>;
  with procedure ErrMult(R: in Radius; S: in out Scalar) is <>;
  with procedure Union(S1: in Scalar; S2: in out Scalar) is <>;
  with function Union(S1,S2: Scalar) return Scalar is <>;
  with procedure Intersection(S1: in Scalar; S2: in out Scalar; Empty: out Logical) is <>;

  --- order
  with function Sign(S: Scalar) return Integer is <>;
  with function Compare(S1,S2: Scalar) return Integer 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 ">="(S1,S2: Scalar) return Boolean is <>;
  with procedure Min(S1: in Scalar; S2: in out Scalar) is <>;
  with procedure Min(S1,S2: in Scalar; S3: in out Scalar) is <>;
  with function Min(S1,S2: Scalar) return Scalar is <>;
  with procedure Max(S1: in Scalar; S2: in out Scalar) is <>;
  with procedure Max(S1,S2: in Scalar; S3: in out Scalar) is <>;
  with function Max(S1,S2: Scalar) return Scalar is <>;
  with function Inf(S: Scalar) return Flt is <>; -- inf of real part
  with function Sup(S: Scalar) return Flt is <>; -- sup of real part

  --- arithmetic
  with procedure Neg(S: in out Scalar) is <>;
  with procedure Neg(S1: in Scalar; S2: in out Scalar) is <>;
  with function "-"(S: Scalar) return Scalar is <>;
  with procedure Add(I: in Integer; S: 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 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: in out Scalar) is <>;
  with function "-"(S1,S2: Scalar) return Scalar is <>;
  with procedure Mult(R: in Flt; S,Tmp: in out Scalar) is <>;
  with procedure Mult(R: in Flt; S: in out Scalar) is <>;
  with procedure Prod(R: in Flt; S1: in Scalar; S2: in out Scalar) is <>;
  with function "*"(R: Flt; S: Scalar) return Scalar is <>;
  with procedure AddProd(R: in Flt; S1: in Scalar; S2,Tmp: in out Scalar) is <>;
  with procedure AddProd(R: in Flt; S1: in Scalar; S2: in out Scalar) is <>;
  with procedure Mult(Q: in Rational; S: 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 function "*"(S1,S2: Scalar) return Scalar is <>;
  with procedure AddProd(S1,S2: in Scalar; S3,Tmp: in out Scalar) is <>;
  with procedure AddProd(S1,S2: in Scalar; S3: in out Scalar) is <>;
  with procedure SubProd(S1,S2: in Scalar; S3,Tmp: in out Scalar) is <>;
  with procedure Div(R: in Flt; S,Tmp: in out Scalar) is <>;
  with procedure Div(R: in Flt; S: in out Scalar) is <>;
  with procedure Quot(S1: in Scalar; R: in Flt; S2: in out Scalar) is <>;
  with function "/"(S: Scalar; R: Flt) return Scalar is <>;
  with procedure Div(S1: in Scalar; S2: in out Scalar) is <>;
  with procedure Quot(S1,S2: in Scalar; S3: in out Scalar) is <>;
  with function "/"(S1,S2: Scalar) return Scalar is <>;
  with procedure Inv(S1: in Scalar; S2: in out Scalar) is <>;
  with function Inv(S: Scalar) return Scalar is <>;
  with function "**"(S: Scalar; I: Integer) return Scalar is <>;

  --- fun
  with function IsReal(S: Scalar) return Boolean is <>;
  with procedure Adjoint(S: in out Scalar) is <>;
  with procedure Adjoint(S1: in Scalar; S2: in out Scalar) is <>;
  with function Adjoint(S: Scalar) return Scalar is <>;
  with procedure Real_Part(S: in out Scalar) is <>;
  with procedure Imag_Part(S: in out Scalar) is <>;
  with procedure Eval0(S: in out Scalar) is <>;
  with function "abs"(S: Scalar) return Scalar is <>;
  with procedure Norm(S1: in Scalar; S2: in out Scalar) is <>;
  with function Norm(S: Scalar) return Scalar is <>;
  with function MaxNorm(S: Scalar) return Radius is <>;
  with procedure Sqr(S: in out Scalar) is <>;
--  with procedure Sqr(S1: in Scalar; S2: in out Scalar) is <>;
  with function Sqr(S: Scalar) return Scalar is <>;
  with procedure Sqrt(S1: in Scalar; S2: in out Scalar) is <>;
  with function Sqrt(S: Scalar) return Scalar is <>;
  with procedure Root(K: in Positive; S1: in Scalar; S2: in out Scalar) is <>;
  with function Root(K: Positive; S: Scalar) return Scalar is <>;
  with procedure Exp(S1: in Scalar; S2: in out Scalar) is <>;
  with function Exp(S: Scalar) return Scalar is <>;
  with procedure ArcCos(S1: in Scalar; S2: in out Scalar) is <>;
  with function ArcCos(S: Scalar) return Scalar is <>;
  with procedure ArcSin(S1: in Scalar; S2: in out Scalar) is <>;
  with function ArcSin(S: Scalar) return Scalar is <>;
  with procedure Cos(S1: in Scalar; S2: in out Scalar) is <>;
  with function Cos(S: Scalar) return Scalar is <>;
  with procedure Sin(S1: in Scalar; S2: in out Scalar) is <>;
  with function Sin(S: Scalar) return Scalar is <>;
  with procedure Log(S1: in Scalar; S2: in out Scalar) is <>;
  with function Log(S: Scalar) return Scalar is <>;
--  with function Pi return Scalar is <>;
  with procedure Simple_Random(S: in out Scalar) is <>;
  with procedure QPower(Q: in Rational; S1: in Scalar; S2: in out Scalar) is <>;
  with procedure Roots2(B,C: in Scalar; U1,U2,V: in out Scalar) is <>;
  with procedure Roots3(B,C,D: in Scalar; U0,U1,U2,V: in out Scalar) is <>;

  --- conversion and i/o
  with function Approx(S: Scalar) return Flt is <>;
  with procedure Assign(K: in Integer; S: in out Scalar) is <>;
  with procedure Assign(Q: in Rational; S: in out Scalar) is <>;
  with procedure Assign(R: in Flt; S: in out Scalar) is <>;
  with function Scal(I: Integer) return Scalar is <>;
  with function Scal(Q: Rational) return Scalar is <>;
  with function Scal(R: Flt) return Scalar is <>;
  with procedure Enclose(R1,R2: in Flt; S: in out Scalar) is <>;
  with function Enclose(R1,R2: Flt) return 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 <>;

  --- misc
  with function Get_Precision(R: Scalar) return Positive is <>;
  with procedure Proper_Rounding is <>;
  --  with procedure Proper_Rounding(Dummy: in Scalar) is <>;
  --  with procedure Free_Cache(S: in Scalar) is <>;
  -------------------- end_include scalars

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

package Chebs is  -- Chebishev series

  package SV_More is new SV.More;
  package SV_Ops is new SV.Ops(Scalar => Scalar, SM => SM);

  subtype FLt_Matrix is Flt_Matrices.Matrix;
  subtype FLt_Vector is FLt_Vectors.Vector;

  EDeg: constant Positive := 2*CDeg;
  subtype Freq is Integer range 0 .. CDeg;
  subtype EFreq is Integer range 0 .. EDeg;
  subtype CPoly1 is SV.Vector(Freq);
  subtype Errs1 is Flt_Vector(EFreq); -- assumes rounding up

  PolyFac:  Radius  := One;           -- default domain for polynomials is PolyFac*Rad
  FProd_Parallel: Boolean := False;   -- run Product etc in parallel

  type Cheb is
    record
      C: CPoly1;               -- T_k(x)
      E: Errs1;                -- higher order frequency errors
      R: Radius := RadC;       -- domain of analyticity is {z+1/z : |z|< RadC}
    end record;

--------------- standard Scalar procedures

--- basic
  function Info(Dummy: Cheb) return Scalar_Info;
  function IsSharp(P: Cheb) return Boolean;         --- polynomial with sharp coeffs
  function IsZero(P: Cheb) return Boolean;
  function "="(P1,P2: Cheb) return Boolean;
  procedure SetZero(P: in out Cheb);
  procedure Copy(P1: in Cheb; P2: in out Cheb);
  procedure Swap(P1,P2: in out Cheb);

--- sets
  function Center0(P: Cheb) return Boolean;           --- symmetric about 0
  function Contains0(P: Cheb) return Logical;
  function Contains(P1,P2: Cheb) return Logical;
  procedure BallAt0(R: in Flt; P: in out Cheb);       --- 0-centered ball of radius |R|
  function BallAt0(R: Flt) return Cheb;               --- 0-centered ball of radius |R|
  procedure ToErr(P: in out Cheb);                    --- 0-centered set containing P
  procedure ToErr(P1: in Cheb; P2: in out Cheb);  --- 0-centered set containing P1
  function ToErr(P: Cheb) return Cheb;            --- 0-centered set containing P
  procedure Center(P: in out Cheb);
  procedure Center(P1: in Cheb; P2: in out Cheb);
  function Center(P: Cheb) return Cheb;
  procedure ModCenter(P: in out Cheb);
  procedure ModCenter(P1: in Cheb; P2: in out Cheb);
  function ModCenter(P: Cheb) return Cheb;            --- zero center
  procedure ErrMult(R: in Radius; P: in out Cheb);
  procedure Union(P1: in Cheb; P2: in out Cheb);
  function Union(P1,P2: Cheb) return Cheb;
  procedure Intersection(P1: in Cheb; P2: in out Cheb; Empty: out Logical);

--- order
  function Sign(P: Cheb) return Integer;
  function Compare(P1,P2: Cheb) return Integer;
  function "<"(P1,P2: Cheb) return Boolean;
  function "<="(P1,P2: Cheb) return Boolean;
  function ">="(P1,P2: Cheb) return Boolean;
  function ">"(P1,P2: Cheb) return Boolean;
  procedure Min(P1: in Cheb; P2: in out Cheb);
  procedure Min(P1,P2: in Cheb; P3: in out Cheb);
  function Min(P1,P2: Cheb) return Cheb;
  procedure Max(P1: in Cheb; P2: in out Cheb);
  procedure Max(P1,P2: in Cheb; P3: in out Cheb);
  function Max(P1,P2: Cheb) return Cheb;
  function Inf(P: Cheb) return Flt;
  function Sup(P: Cheb) return Flt;

--- addition and multiplication etc.
  procedure Neg(P: in out Cheb);
  procedure Neg(P1: in Cheb; P2: in out Cheb);
  function "-"(P: Cheb) return Cheb;
  procedure Add(I: in Integer; P: in out Cheb);
  procedure Add(P1: in Cheb; P2: in out Cheb);
  procedure Sum(P1,P2: in Cheb; P3: in out Cheb);
  function "+"(P1,P2: Cheb) return Cheb;
  procedure Sub(P1: in Cheb; P2: in out Cheb);
  procedure Diff(P1,P2: in Cheb; P3: in out Cheb);
  function "-"(P1,P2: Cheb) return Cheb;
  procedure Mult(R: in Flt; P,Tmp: in out Cheb);
  procedure Mult(R: in Flt; P: in out Cheb);
  procedure Prod(R: in Flt; P1: in Cheb; P2: in out Cheb);
  function "*"(R: Flt; P: Cheb) return Cheb;
  procedure AddProd(R: in Flt; P1: in Cheb; P2,Tmp: in out Cheb);
  procedure AddProd(R: in Flt; P1: in Cheb; P2: in out Cheb);
  procedure Mult(Q: in Rational; P: in out Cheb);
  procedure Mult(P1: in Cheb; P2: in out Cheb);
  procedure Prod(P1,P2: in Cheb; P3: in out Cheb);
  function "*"(P1,P2: Cheb) return Cheb;
  procedure AddProd(P1,P2: in Cheb; P3,Tmp: in out Cheb);
  procedure AddProd(P1,P2: in Cheb; P3: in out Cheb);
  procedure SubProd(P1,P2: in Cheb; P3,Tmp: in out Cheb);
  procedure Div(R: in Flt; P,Tmp: in out Cheb);
  procedure Div(R: in Flt; P: in out Cheb);
  procedure Quot(P1: in Cheb; R: in Flt; P2: in out Cheb);
  function "/"(P: Cheb; R: Flt) return Cheb;
  procedure Div(P1: in Cheb; P2: in out Cheb);
  procedure Quot(P1,P2: in Cheb; P3: in out Cheb);
  function "/"(P1,P2: Cheb) return Cheb;
  procedure Inv(P: in out Cheb);
  procedure Inv(P1: in Cheb; P2: in out Cheb);
  function Inv(P: Cheb) return Cheb;
  function "**"(P: Cheb; I: Integer) return Cheb;

--- functions
  function IsReal(P: Cheb) return Boolean;
  procedure Adjoint(P1: in Cheb; P2: in out Cheb);
  procedure Adjoint(P: in out Cheb);
  function Adjoint(P: Cheb) return Cheb;
  procedure Real_Part(P: in out Cheb);
  procedure Imag_Part(P: in out Cheb);
  procedure Eval0(P: in out Cheb);
  procedure Norm(P: in Cheb; Q: in out Cheb);
  function Norm(P: Cheb) return Cheb;
  function "abs"(P: Cheb) return Cheb renames Norm;
  function MaxNorm(P: Cheb) return Radius;
  procedure Sqr(P: in out Cheb);
  function Sqr(P: Cheb) return Cheb;
  procedure Sqrt(P1: in Cheb; P2: in out Cheb);
  function Sqrt(P: Cheb) return Cheb;
  procedure Root(K: in Positive; P1: in Cheb; P2: in out Cheb);
  function Root(K: Positive; P: Cheb) return Cheb;
  procedure Exp(P1: in Cheb; P2: in out Cheb);
  function Exp(P: Cheb) return Cheb;
  procedure ArcCos(P1: in Cheb; P2: in out Cheb);
  function ArcCos(P: Cheb) return Cheb;
  procedure ArcSin(P1: in Cheb; P2: in out Cheb);
  function ArcSin(P: Cheb) return Cheb;
  procedure Cos(P1: in Cheb; P2: in out Cheb);
  function Cos(P: Cheb) return Cheb;
  procedure Sin(P1: in Cheb; P2: in out Cheb);
  function Sin(P: Cheb) return Cheb;
  procedure Log(P1: in Cheb; P2: in out Cheb);
  function Log(P: Cheb) return Cheb;
  procedure Simple_Random(P: in out Cheb);
  procedure QPower(Q: in Rational; P1: in Cheb; P2: in out Cheb);
  procedure Roots2(B,C: in Cheb; U1,U2,V: in out Cheb);
  procedure Roots3(B,C,D: in Cheb; U0,U1,U2,V: in out Cheb);

--- conversion and i/o
  function Approx(P: Cheb) return Flt;
  procedure Assign(I: in Integer; P: in out Cheb);
  procedure Assign(Q: in Rational; P: in out Cheb);
  procedure Assign(R: in Flt; P: in out Cheb);
  function Scal(I: Integer) return Cheb;
  function Scal(Q: Rational) return Cheb;
  function Scal(R: Flt) return Cheb;
  procedure Enclose(R1,R2: in Flt; P: in out Cheb);
  function Enclose(R1,R2: Flt) return Cheb;
  procedure Show1(N: in String; P: in Cheb; Hide0: in Boolean := True);
  procedure Show2(N: in String; P1,P2: in Cheb; Hide0: in Boolean := True);
  procedure Put(F: in File_Type; P: in Cheb; Decimal: in Boolean := False);
  procedure Get(F: in File_Type; P: in out Cheb; Decimal: in Boolean := False);
  procedure Write(FileName: in String; P: in Cheb; Decimal: in Boolean := False);
  procedure Read(FileName: in String; P: in out Cheb; Decimal: in Boolean := False);

--- misc
  function Get_Precision(P: Cheb) return Positive;

--------------- other standard procedures
  function IsPoly(P: Cheb) return Boolean;
  function Frequency0(P: Cheb) return Boolean;
  function Rho(P: Cheb) return Radius;
  procedure SetRho(R: in Radius; P: in out Cheb; Check: in Boolean := True);
  procedure SetZero(R: in Radius; P: in out Cheb);

  procedure LiftErrs(P: in out Cheb; F: in Natural := 0);   -- make general errors start at frequency F
  procedure Assign(S: in Scalar; P: in out Cheb);
  function Scal(S: Scalar) return Cheb;

  procedure Coeff(I: in Integer; P: in Cheb; S: in out Scalar);
  function Coeff(I: Integer; P: Cheb) return Scalar;
  procedure AddCoeff(I: in Integer; S: in Scalar; P: in out Cheb);    -- P[I] := P[I] + S
  procedure Add(S: in Scalar; P: in out Cheb);
  procedure Mult(S: in Scalar; P: in out Cheb);                       -- P := S*P
  procedure Prod(S: in Scalar; P1: in Cheb; P2: in out Cheb);     -- P2 := S*P1;
  function "*"(S: Scalar; P: Cheb) return Cheb;                   -- return S*P
  procedure AddProd(S: in Scalar; P1: in Cheb; P2: in out Cheb);  -- P2 := P2+S*P1

  procedure Val(P: in Cheb; S1: in Scalar; S2: in out Scalar);
  function Val(P: Cheb; S: Scalar) return Scalar;
  procedure Val(P1: in Cheb; S: in Scalar; P2: in out Cheb);
  procedure SumEven(P: in Cheb; S: in out Scalar);
  procedure SumOdd(P: in Cheb; S: in out Scalar);
  function SumEven(P: Cheb) return Scalar;
  function SumOdd(P: Cheb) return Scalar;
  procedure SetIV(P: in out Cheb; T: in Scalar);
  procedure Norm1(P: in Cheb; S: in out Scalar);
  function Norm1(P: Cheb) return Scalar;
  procedure Monom(I: in Freq; P: in out Cheb);
  procedure HiUnitBall(I: in Integer; P: in out Cheb; R: in Radius := RadC);
  procedure Compose(C: in SV.Polynom1; P1: in Cheb; P2: in out Cheb);
  procedure CosSin(P: in Cheb; PC,PS: in out Cheb);
  procedure ScalProd(P,Q: in Cheb; S: in out Scalar);
  procedure DerAtOne(P: in Cheb; S: in out Scalar);
  procedure AntiDer(C: in out CPoly1);
  procedure AntiDer(P: in out Cheb);
  procedure AntiDer(P1: in Cheb; P2: in out Cheb);
  procedure AntiDerP(P: in out Cheb);                  ------ antiderivative+Cx such that P(-1)=P(1)
  procedure AntiDer2D(P: in out Cheb);                 ------ second antiderivative with homogeneous Dirichlet BC
  function Integral(P: Cheb; S1,S2: Scalar) return Scalar;

  function GuessRho(P: Cheb) return Radius;
  procedure Test_Some_Ops;

  type Cheb_Access is access Cheb;

private

  procedure AddProd(S: in Scalar; C1: in CPoly1; C2: in out CPoly1; Tmp: in out Scalar);
  procedure SubProd(S: in Scalar; C1: in CPoly1; C2: in out CPoly1; Tmp: in out Scalar);
  function QuasiDeg(C: CPoly1) return Natural;
  function QuasiDeg(E: Errs1) return Natural;
  function UpSumEven(E: Errs1) return Radius;
  procedure ErrProd(P1,P2: in Cheb; R3: in Radius; E3: out Errs1);
  procedure Mult(P1: in Cheb; P2,Tmp: in out Cheb);
  function UpSum(E: Errs1) return Radius;
  procedure Norm1(R: in Radius; C: in CPoly1; S: in out Scalar);
  function TrueF(E: Errs1) return Natural;
  function UpInvNormFac(R: Radius; I: Integer) return Radius;
  function UpNormFac(R: Radius; I: Integer) return Radius;
  procedure AddErr(I: in Integer; R: in Flt; E: in out Errs1);
  procedure EvenCoeff(I: in Natural; P: in Cheb; S: in out Scalar);
  function Simple(P: Cheb) return Boolean;
  procedure NewQuot(S0,S1: in Scalar; Q: in out Flt; N: in out Integer);

  procedure Exp_Split(P1: in Cheb; P2: in out Cheb; S: in out Scalar);
  procedure CosSin_Split(P1: in Cheb; P2: in out Cheb; C,S: in out Scalar);
  procedure Log_Split(P1: in Cheb; P2: in out Cheb; S: in out Scalar);
  procedure QPower_Split(Q: in Rational; P1: in Cheb; P2: in out Cheb; S: in out Scalar);
  function ExpTerms(R: Radius; Prec: Positive) return Natural;
  procedure Approx_Inv(P: in out Cheb);
  procedure Approx_Sqrt(P: in out Cheb);
  procedure Approx_Root(K: in Positive; P: in out Cheb);
  procedure Approx_ArcCos(P: in out Cheb);
  procedure Approx_ArcSin(P: in out Cheb);

  SZero:      constant Scalar      := Scal(0);
  SInfo:      constant Scalar_Info := Info(SZero);
  STrunc:     constant Boolean     := SInfo.IsNumeric;
  Std:        constant Boolean     := SInfo.IsStandard;
  SComplex:   constant Boolean     := SInfo.IsComplex;
  Not_STrunc: constant Boolean     := not STrunc;
  SHalf:      constant Scalar      := Scal(Half);
  SQuarter:   constant Scalar      := Scal(Quarter);
  SOne:       constant Scalar      := Scal(1);
  STwo:       constant Scalar      := Scal(2);
  SThree:     constant Scalar      := Scal(3);
  SFour:      constant Scalar      := Scal(4);
  FTrunc:     constant Boolean     := STrunc;

  FInfo: constant Scalar_Info := (RepType    => SInfo.RepType,
                                  IsStandard => Std,
                                  IsNumeric  => STrunc,
                                  IsComplex  => SComplex,
                                  NReps      => SInfo.NReps*(2*(EDeg)+1),
                                  RMode      => SInfo.RMode);

  package Alloc is new Recycling (Item => Cheb);
  subtype LF_Pointer is Alloc.LD_Pointer;
  Pool: Alloc.Protected_Data;

end Chebs;
