$include "/users/04/info/mezzarob/prive/NumGfun/main.mpl";

with(gfun):
with(NumGfun):

print(NumGfun_version);

kernelopts(opaquemodules=false):
kernelopts(assertlevel=2):
#interface(verboseproc=2):

trace(bound_ratpoly_coeffs);
trace(bound_ratpoly);
#trace(poincare_normalization);
#trace(argmax);
#trace(bound_rec);
#trace(`value/Coeftayl`);
#trace(`abs/RootOf`);
#trace(typecheck_hr_eq);
#trace(parse_exppoly_term);
#trace(bound_diffeq_doit);
#trace(bound_normal_diffeq_doit);
#trace(bound_diffeq_tail);
#trace(bound_diffeq);
#trace(tail_bound);
#trace(one_sol_of_ineq);
#trace(bound_transition_matrix);
#trace(one_sol_of_ineq);

#trace(NumGfun);

infolevel[bounds] := 10;
#infolevel[one_sol_of_ineq] := 10;

try


print ("===== MISC =====");

t := RootOf(_Z^8-2*_Z+1,0.6110876563 + 0.8843359539*I);
abs(evalf(t));
abs(t);

taylorcoeffs := proc(expr, x, n:=100)
    local s, k;
    s := convert(taylor(expr, x=0, n),polynom);
    return [seq(coeff(s, x, k), k=0..n-1)];
end proc;

ASSERT(colinear([1,2,3],[2,4,5],[1,2]));
ASSERT(colinear([x^2,0,x^3+x],[x,0,1+x^2],[1,2,3]));
ASSERT(not colinear([0,0,x^3+x],[x,0,1+x^2],[1,2,3]));
ASSERT(colinear([0,0,0],[x,0,1+x^2],[1,2,3]));

print ("===== bound_ratpoly etc. =====");

for rat in[
    (z^7+3*z^2+z+1)/((z-2)^3*(z^3-3)*(z-I)^2),
    (1+2*z)/((z^2-1)*(z-1/2)),
    1/(1-z)^2*(1-2*z)^2,
    1/((1-z)*(1-2*z)^5),
    (2*z^2-9*z+8)/((2-z)*(2+z)^2),
    NULL]
do
    brat := bound_ratpoly(rat,z);
    delta := evalf(taylorcoeffs(brat, z) - map(abs, taylorcoeffs(rat, z)));
#    print(rat, brat,  delta);
    ASSERT(type(delta,'list'('nonnegative')));
end do;

rat := (z^3-z^2-z+5)/5; alpha := 1/2; m := 4;
M := bound_ratpoly_coeffs(rat,z,alpha,m);
delta := evalf(taylorcoeffs(M/(1-alpha*z)^m, z) - map(abs, taylorcoeffs(rat, z)));
ASSERT(type(delta,list(nonnegative)));

print ("===== bound_diffeq etc. =====");

todeq := proc(f)
    diffeqtohomdiffeq(holexprtodiffeq(f,y(z)),y(z));
end proc;

for deq in [
    ## singularité apparente, sans conditions initiales...
   { -z*(z-1)^2*diff(y(z),z,z) +(z-1)*(z^2-2*z-1)*diff(y(z),z) + (z^2-1)*y(z) = 0 },
    ## 1 irrégulier
   todeq(exp(1/(1-z))/exp(1)),
    ## Ici, après homogénisation, la singularité dominante est de module < 1, et elle est régulière.
    ## C'est un bon exemple avec un comportement un peu pathologique...
    { todeq(exp(1/(1-z))/exp(1)+log(z)), y(0) = 0, D(y)(0) = -1},
    ## 0 point ordinaire, les c[k] devraient être tous nuls
   todeq(cos(1/(1-z))),
    # rayon de convergence infini
   { diff(y(z),z) = y(z), y(0)=1 },
    ## ... avec exposant de 1/n! non entier
   todeq(AiryAi(z)),
    ## 0 singulier régulier
   todeq(BesselJ(1,z)),
    ## divers
   todeq(1/z+1/(1-z)),
   todeq(log(1-z)/(z^3-2)^3), # nombreuses sing, mais toutes régulières, dominante=1
   todeq(1/exp(1)*exp(1/(1-z))+1/(1+z/3)),
    # Penser à tester avec des équations qui ont des solutions d'exposant négatif, et tout ça...
    NULL]
do
    print("=== start test===");
    print(bound_diffeq(deq, y(z)));
    print(bound_diffeq_tail(deq, y(z), n));
    print([seq(needed_terms(deq, y(z), 0, 0, 1/2, 1/2^(2^k)), k=2..12)]);
end do;

# solution divergente
bound_diffeq(rectodiffeq({u(n+1)=(n+1)*u(n), u(0)=1}, u(n), y(z)), y(z));

print ("===== bound_rec =====");

ifnonzero := proc(x) if x=0 then return 1 else return x end if end proc;
for rec in [
    { u(n+1) = u(n), u(0) = 0 },
    { u(n+1) = u(n), u(0) = 18 },  # apparemment, on borne par 18(n+1)
    { u(n+1) = (n+1) * u(n), u(0) = 0 },
    { u(n+1) = (n+1) * u(n), u(0) = 1 },
    {(n+2)*u(n+2) = u(n), u(0)=1, u(1)=1},
    { u(n+2)=u(n+1)+(n+1)*u(n), u(0)=1, u(1)=3 },
    {(n + 1)*u(n + 1) = (2*n + 3)*u(n), u(0) = 1},
    {u(n+1)=u(n)+1, u(0)=-1},  # borné par 2^n p(n)... cas non générique ?
    {u(n+1)=u(n)+1, u(0)=1},  # borné par un polynôme
    {u(n+1)=u(n)+1, u(0)=-2},  # encore un cas non générique, (3/2)^n p(n)
    NULL]
do
    print("=== start test===");
    bound := bound_rec(rec, u(n));
    p := rectoproc(rec, u(n));
    delta := [seq(evalf(value(bound)-abs(p(n))), n=0..30)];
    print(bound, delta);
    ASSERT(type(delta,'list'('nonnegative')))
end do;

print ("===== bound_transition_matrix =====");

for arg in [
    #[{diff(y(z),z) = y(z), y(0) = 1}, [0, 1, 2, 2+2*I]],
    [todeq(arctan(z)), [0,1/2,1,3/2,2,2+I/2]],
    NULL]
do
    print("=== start test===");
    bound_transition_matrix(arg[1], y(z), arg[2]);
end do;


## formule des Chudnovsy pour pi
A := 13591409;
B := 545140134;
C := 640320^3;
rec := { (A+B*n) * (3*n+3)* (3*n+2)*(3*n+1) * (n+1)^3 * C * u(n+1)
         + (6*n+6)*(6*n+5)*(6*n+4)*(6*n+3)*(6*n+2)*(6*n+1) * (A+B*(n+1)) * u(n),
         u(0) = A };
bound_rec_tail(rec, u(n));

## permutations de Baxter
rec := { (n+2)*(n+3)*a(n) = (7*n^2+7*n-2)*a(n-1) + 8*(n-1)*(n-2)*a(n-2), a(0)=1, a(1)=1 };
bound_rec(rec, a(n));

end;
