File : taylors.adb
package body Taylors is
function Deg(P: Taylor) return Degree is
begin
return P.D;
end Deg;
function EffDeg(P: Taylor) return Degree is
begin
if P.D<0 then return -1; end if;
for K in reverse 0 .. P.D loop
if P.C(K) /= ScalZero then
return K;
end if;
end loop;
if Trunc or else P.E=ScalZero then return -1; end if;
return 0;
end EffDeg;
procedure SetDeg(D: in Degree; P: in out Taylor) is
begin
if D<P.D then P.D := D; end if;
end SetDeg;
procedure SetZero(P: out Taylor) is
begin
P.D := -1;
end SetZero;
function IsZero(P: Taylor) return Boolean is
begin
if P.D<0 then return True; end if;
for K in reverse 0 .. P.D loop
if P.C(K) /= ScalZero then
return False;
end if;
end loop;
return Trunc or else P.E=ScalZero;
end IsZero;
procedure Cleanup(P: in out Taylor) is
begin
if P.D<0 then return; end if;
for K in reverse 0 .. P.D loop
exit when P.C(K) /= ScalZero;
P.D := K-1;
end loop;
if Trunc or else P.D >= 0 or else P.E=ScalZero then return; end if;
P.D := 0;
end Cleanup;
procedure Copy(P1: in Taylor; P2: out Taylor) is
begin
P2.D := P1.D;
P2.E := P1.E; -- garbage in Numeric case
for K in 0 .. P1.D loop
P2.C(K) := P1.C(K);
end loop;
end Copy;
function Component(K: Power; P: Taylor) return Scalar is
begin
if K > P.D then
return ScalZero;
end if;
return P.C(K);
end Component;
procedure Component(K: in Power; P1: in Taylor; P2: out Taylor) is
begin
if K>P1.D then
P2.D := -1;
else
P2.D := 0;
P2.C(0) := P1.C(K);
P2.E := ScalZero;
end if;
end Component;
procedure SetComponent(D: in Power; S: in Scalar; P: in out Taylor) is
begin
if D>P.D then
if S=ScalZero then return; end if;
for K in P.D+1 .. D-1 loop
P.C(K) := ScalZero;
end loop;
P.C(D) := S;
if P.D<0 then P.E := ScalZero; end if;
P.D := D;
return;
end if;
if D /= P.D or else S /= ScalZero then
P.C(D) := S;
return;
end if;
if Trunc or else D>0 or else P.E=ScalZero then
P.D := D-1;
return;
end if;
P.C(0) := S; -- when only P.E remains nonzero
end SetComponent;
procedure ResetComponent(P: in out Taylor; Kmin: in Natural := 0; Kmax: in Integer := Size) is
begin
if Kmax<P.D then
for K in Kmin .. Kmax loop
P.C(K) := ScalZero;
end loop;
elsif Kmin<=P.D then
if Trunc or else Kmin>0 or else P.E=ScalZero then
P.D := Kmin-1;
else
P.C(0) := ScalZero; -- when only P.E remains nonzero
end if;
end if;
end ResetComponent;
function ErrComp(P: Taylor) return Scalar is
begin
if Trunc or else P.D<0 then
return ScalZero;
end if;
return P.E;
end ErrComp;
procedure SetErrComp(S: in Scalar; P: in out Taylor) is
begin
if Trunc then return; end if;
if P.D<0 then
if S=ScalZero then return; end if;
P.D := 0;
P.C(0) := ScalZero; -- when only P.E remains
end if;
P.E := Abs(S);
end SetErrComp;
procedure ResetErrComp(P: in out Taylor) is
begin
if Trunc then return; end if;
if P.D=0 and then P.C(0)=ScalZero then P.D := -1; return; end if;
P.E := ScalZero;
end ResetErrComp;
end Taylors;