#$include "main.mpl"

kernelopts('assertlevel'=2);
infolevel[bounds] := 5;
infolevel[ancont] := 3;
infolevel[nthterm] := 3;

with(gfun);
with(NumGfun);

test_aceval := proc(f, path, prec,
{deq := diffeqtohomdiffeq(holexprtodiffeq(f(z),y(z)),y(z))})
    local rec, val, err;
    rec := rectohomrec(diffeqtorec(deq,y(z),u(n)),u(n));
    val := ac_eval(deq,y(z),path,prec);
    err := evalf[prec*2](abs(val - f(path[-1])));
    ASSERT(err <= 10^(-prec));
end proc;

kernelopts(opaquemodules=false);

trace(NumGfun);
trace(test_aceval);
#trace(NumGfun:-bound_normal_diffeq_doit);
#trace(NumGfun:-needed_terms);
#trace(NumGfun:-nb_terms);
#trace(NumGfun:-one_sol_of_ineq);
#trace(NumGfun:-tail_bound);
#trace(max_of_exppoly_term);
#trace(parse_exppoly_term);
#trace(ratpolytocoeff);
#trace(`convert/fullparfrac`);
#trace(NumGfun:-bound_transition_matrix);
#trace(NumGfun:-step_transition_matrix);
#trace(NumGfun:-bound_ratpoly_coeffs);
#trace(bound_diffeq_doit);
#trace(bound_rec_doit);
#trace(poincare_type);
#trace(poincare_normalization);
#trace(mydiffeqtohomdiffeq);
#trace(typecheck_hr_eq);

try

#### constant

test_aceval(
    z -> 42,
    [0,1/3,1/2],
    30,
    deq = {diff(y(z),z), y(0)=42});

### polynomial (1+z instead of z since z's mindiffeq has a fake singularity in 0)

test_aceval(
    z -> 1+z,
    [0,1/3,1/2],
    30,
    deq = {y(z)-(z+1)*diff(y(z),z), y(0)=1});

### Airy function

#test_aceval(
#    z -> AiryAi(z),
#    [0,4*I+4],
#    1000);


### orddeq=11, ordrec=9 (bound computation is slow in exact mode)

test_aceval(
    z -> arctan(z) + log(1/(1-z)) + exp(z),
    [0,1/30,(1+I)/30,I/30],
    30);

### arctan(1/2) to 'high' order

#test_aceval( z -> arctan(z),  [0,1/2],  100000);

### rec with constant coefficients

test_aceval(
    z -> 1/(1-z),
    [0,1/30,(1+I)/30,I/30],
    30,
    deq = {y(z)+(z-1)*diff(y(z),z), y(0)=1});
test_aceval(
    z -> 1/(1-z),
    [0,1/2],
    30,
    deq = {y(z)+(z-1)*diff(y(z),z), y(0)=1});


### exp (low prec)

test_aceval(
    z -> exp(z),
    [0,-100],
    10);

### very low prec

test_aceval(
    z -> arctan(z),
    [0,1/5,1/3],
    1);

### Spheroidal wave function. Heun functions are the 'general' solution to the second order DE with
### 4 regular singular points

a := 1;
b := 1;
c := 1;
q := 1;
test_aceval(
    z ->  HeunC(0,-1/2,b,q,1/4-1/4*b-1/4*c,z^2),
    [0,1/3],
    10,
    deq = {(1-z^2)*diff(y(z),z,z) - 2*(b+1)*z*diff(y(z),z) + (c-4*q*z^2)*y(z), y(0)=1, D(y)(0)=0});

###
### MISC
###

deq := diffeqtohomdiffeq(holexprtodiffeq(arctan(z),y(z)),y(z));
transition_matrix(deq, y(z), [0,(1+I)/2,3*(1+I)/4,1+I,1/2+7*I/4,2*I], 10);

deq := diffeqtohomdiffeq(holexprtodiffeq(arctan(z),y(z)),y(z));
local_monodromy(deq, y(z), I, 0, 100);
map(identify,%);

## Regression tests

test_aceval(z -> exp(z/(1-z^2)), [0,1/3], 50);

end;
