with Rationals, Flts;
use Rationals, Flts;

pragma Elaborate_All (Rationals,Flts);

generic

  Numeric: in Boolean;

  type Scalar is private;
  type Fun is private;

  with function IsZero(F: Fun) return Boolean is <>;
  with procedure SetZero(S: in out Fun) is <>;
  with function MaxNorm(F: Fun) return Radius is <>;
  with procedure Copy(F1: in Fun; F2: in out Fun) is <>;
  with procedure Mult(Q: in Rational; S: in out Fun) is <>;
  with procedure BallAt0(R: in Flt; F: in out Fun) is <>;
  with procedure Add(I: in Integer; S: in out Fun) is <>;
  with procedure Add(S: in Scalar; F: in out Fun) is <>;
  with procedure Add(F1: in Fun; F2: in out Fun) is <>;
  with procedure Sub(F1: in Fun; F2: in out Fun) is <>;
  with procedure Mult(S: in Scalar; F: in out Fun) is <>;
  with procedure Prod(S: in Scalar; F1: in Fun; F2: in out Fun) is <>;
  with procedure Mult(F1: in Fun; F2,Tmp: in out Fun) is <>;
  with procedure Prod(F1,F2: in Fun; F3: in out Fun) is <>;
  with procedure Show1(N: in String; P: in Fun; Hide0: in Boolean := True) is <>;

  with procedure Inv_Split(X: in Fun; Z: in out Fun; S: in out Scalar) is <>;
  with procedure QPower_Split(Q: in Rational; X: in Fun; Z: in out Fun; S: in out Scalar) is <>;
  with procedure Exp_Split(X: in Fun; Z: in out Fun; S: in out Scalar) is <>;
  with procedure CosSin_Split(X: in Fun; Z: in out Fun; C,S: in out Scalar) is <>;
  with procedure Log_Split(X: in Fun; Z: in out Fun; S: in out Scalar) is <>;

package Fun_Series is

  procedure Series_Inv(X: in Fun; Y: in out Fun; Iter: in Positive);
  procedure Series_QPower(Q: in Rational; X: in Fun; Y: in out Fun; Iter: in Positive);
  procedure Series_Log(X: in Fun; Y: in out Fun; Iter: in Positive);
  procedure Series_Exp(X: in Fun; Y: in out Fun; Iter: in Positive);
  procedure Series_CosSqrt(X: in Fun; Y: in out Fun; Iter: in Positive);    -- Y := Cos(Sqrt(X))
  procedure Series_SinSqrt(X: in Fun; Y: in out Fun; Iter: in Positive);    -- Y := Sin(Sqrt(X))/Sqrt(X)
  procedure Series_CosSin(X: in Fun; Yc,Ys: in out Fun; Iter: in Positive);
  procedure Series_ArcSinSqrt(X: in Fun; Y: in out Fun; Iter: in Positive); -- Y := ArcSin(Sqrt(X))/Sqrt(X)
  procedure Series_ArcSin(X: in Fun; Y: in out Fun; Iter: in Positive);

  --- 1+F(1)*X*[1+F(2)*X*[1+F(3)*X*[1+...]]]
  generic
    with function Fac(I: Positive) return Rational; --- assuming bounded in modulus by 1
  procedure Series(X: in Fun; Y: in out Fun; Decreasing: in Boolean; Iter: in Positive);

  pragma Inline_Always (Mult);

end Fun_Series;
