File : fouriers.adb



package body Fouriers is

  function Deg(M,N: Integer; H: Fourier) return DegType is
  begin
    return Deg(H.C(M,N));
  end Deg;

  function ErrDeg(I: Integer; H: Fourier) return DegType is
  begin
    if H.P then return -1; end if;
    return Deg(H.E(I));
  end ErrDeg;

  function Par(H: Fourier) return Parity is
  begin
    return H.J;
  end Par;

  function Poly(H: Fourier; Check: in Boolean := False) return Boolean is
  begin
    if Trunc then return True; end if;
    if not Check then return H.P; end if;
    if not H.P then return False; end if;
    for I in FreqE loop
      if Deg(H.E(I)) >= 0 then raise Constraint_Error; end if;
    end loop;
    return True;
  end Poly;

  procedure SetPoly(P: in Boolean; H: in out Fourier) is
  begin
    if Trunc then return; end if;
    H.P := P;
    if P then
      for M in Freq1 loop
        for N in Freq2 loop
          ResetErrComp(H.C(M,N));
        end loop;
      end loop;
      for I in FreqE loop
        SetZero(H.E(I));
      end loop;
    end if;
  end SetPoly;

  function Rho(H: Fourier) return Weights is
  begin
    return H.R;
  end Rho;

  procedure SetRho(R: in Weights; H: in out Fourier) is
  begin
    H.R := R;
  end SetRho;

  procedure SetZero(J: in Parity; R: in Weights; H: out Fourier) is
  begin
    H.P := True;
    H.J := J;
    H.R := R;
    for M in Freq1 loop
      for N in Freq2 loop
        SetZero(H.C(M,N));
      end loop;
    end loop;
    for I in FreqE loop
      SetZero(H.E(I));
    end loop;
  end SetZero;

  procedure Component(M: in Freq1; N: in Freq2; H: in Fourier; P: out Taylor) is
  begin
    Copy(H.C(M,N),P);
  end Component;

  function Component(M: Freq1; N: Freq2; H: Fourier) return Taylor is
  begin
    return H.C(M,N);
  end Component;

  function Component(M: Freq1; N: Freq2; K: Power; H: Fourier) return Scalar is
  begin
    return Component(K,H.C(M,N));
  end Component;

  procedure ResetComponent(M: in Freq1; N: in Freq2; H: in out Fourier) is
  begin
    SetZero(H.C(M,N));
  end ResetComponent;

  procedure ErrComp(I: in FreqE; H: in Fourier; P: out Taylor) is
  begin
    Copy(H.E(I),P);
  end ErrComp;

  function ErrComp(I: FreqE; H: Fourier) return Taylor is
  begin
    return H.E(I);
  end ErrComp;

  procedure ResetErrComp(I: in FreqE; H: in out Fourier) is
  begin
    SetZero(H.E(I));
  end ResetErrComp;

  procedure ResetErrComp(H: in out Fourier) is
  begin
    for I in FreqE loop
      SetZero(H.E(I));
    end loop;
  end ResetErrComp;

  function EffSizeE(H: Fourier) return Integer is
  begin
    for I in reverse FreqE loop
      if not IsZero(H.E(I)) then return I; end if;
    end loop;
    return -1;
  end EffSizeE;

  function Ncut(M: Integer; L: Positive := Lmax; W: Positive := Wmax) return Integer is
    N: Integer;
  begin
    N := Integer'Min(W-IntCeiling(Rep(M)*Inv(Gold)),IntFloor(Rep(L+M)*Gold));
    if N>Size2 then raise Constraint_Error; end if;
    return N;
  exception
    when Undefined => raise Constraint_Error; return N;
  end Ncut;

  function NmaxDef return IntVec is
    Nmax: IntVec(Freq1);
  begin
    for M in Freq1 loop
      Nmax(M) := Ncut(M);
    end loop;
    return Nmax;
  end NmaxDef;

  function Kcut(M,N: Integer; L: Positive := Lmax; W: Positive := Wmax; P: Positive := Pdeg) return DegType is
--- k+a*|omega*nu|<P+1, where a=(P+1-Dho)/W
--- k+b*|Omega*nu|<P+1, where b=(P+1-Dho)/L
    KW,KL,K: Integer;
    Nudotw,Nudotbigw: Scalar;
  begin
    K := -1;
    if M in Freq1 and then N in Nmin(M) .. Ncut(M,L,W) then
      Nudotw    := Abs(Rep( M)*InvGold+Scal(N));
      Nudotbigw := Abs(Scal(M)+Rep(-N)*InvGold);
      if IntFloor(Nudotw)<W and IntFloor(Nudotbigw)<L then
        KW := P-IntFloor(Rep(P+1-Dho)*Nudotw/Rep(W));
        KL := P-IntFloor(Rep(P+1-Dho)*Nudotbigw/Rep(L));
        K := Integer'Min(KW,KL);
        if K<Dho then raise Constraint_Error; end if;
      end if;
    end if;
    return K;
  exception
    when Undefined => raise Constraint_Error; return -1;
  end Kcut;

  function DmaxDef return Degrees is
    Dmax: Degrees(Freq1,Freq2);
  begin
    for M in Freq1 loop
      for N in Freq2 loop
        Dmax(M,N) := Kcut(M,N);
      end loop;
    end loop;
    return Dmax;
  end DmaxDef;

  function IerrDef return IerrType is
    Nudotw,Nudotbigw: Scalar;
    Ierr: IerrType;
  begin
    for M in FreqE1 loop
      for N in FreqE2 loop
        Nudotw    := Abs(Rep( M)*InvGold+Scal(N));
        Nudotbigw := Abs(Scal(M)+Rep(-N)*InvGold);
        Ierr(M,N) := Integer'Min(SizeE,Integer'Max(IntFloor(Nudotw),IntFloor(Nudotbigw)));
      end loop;
    end loop;
    return Ierr;
  exception
    when Undefined => raise Constraint_Error; return Ierr;
  end IerrDef;

  function DminusDef(Sig,Kap: Rep) return Degrees is
    Nudotw,Nudotbigw: Scalar;
    Dminus: Degrees(Freq1,Freq2);
  begin
    for M in Freq1 loop
      for N in Freq2 loop
        Nudotw    := Abs(Rep( M)*InvGold+Scal(N));
        Nudotbigw := Abs(Scal(M)+Rep(-N)*InvGold);
        if Sig*Nudotbigw < Nudotw then
          Dminus(M,N) := IntFloor(Nudotw/Kap);
        else
          Dminus(M,N) := -1;
        end if;
      end loop;
    end loop;
    return Dminus;
  exception
    when Undefined => raise Constraint_Error; return Dminus;
  end DminusDef;

end Fouriers;