/*
  K M Briggs 2004 Sep 03

  Try fps in C and compute generating functions for connected labelled
  graphs.  Output data in form suitable for estimating asymptotic 
  expansions.

  Notes:

> T:=sum(n^(n-1)*z^n/n!,n=1..infinity):
> s:=series(T-T^2/2,z,10):
> seq(i!*coeff(s,z^i),i=1..9);
  1, 1, 3, 16, 125, 1296, 16807, 262144, 4782969
 
> W0:=sum(n^(n-2)*z^n/n!,n=1..infinity):
> series(W0,z,10):
> seq(i!*coeff(w,z^i),i=1..9);
  1, 1, 3, 16, 125, 1296, 16807, 262144, 4782969
  
*/

#include "fps.h"

void test() {
  const int n=200;
  fps_t f1,f2,f3,f4,xp1;
  f1=fps_init(n);
  f2=fps_init(n);
  f3=fps_init(n);
  f4=fps_init(n);
  xp1=fps_init(n);
  fps_zero(f1);
  fps_zero(f2);
  fps_zero(f3);
  fps_zero(f4);
  fps_zero(xp1);
  fps_setterm_si(xp1,1,0);
  fps_setterm_si(xp1,1,1);
  fps_setterm_si(f1,1,0);
  fps_setterm_si(f1,5,3);
  fps_setterm_q(f1,6,5,567);
  fps_setterm_si(f2,7,3);
  fps_setterm_si(f2,-4,5);
  fps_add(f3,f1,f2);
  //printf("f1...\n"); fps_show(f1);
  //printf("f2...\n"); fps_show(f2);
  //printf("f1+f2...\n"); fps_show(3);
  fps_mul(f3,f1,f2);
  //printf("f3=f1*f2...\n"); fps_show(f3);
  fps_div(f2,f3,f1);
  //printf("f3/f1...\n"); fps_show(f2);
  //printf("f1...\n"); fps_show(f1);
  fps_powi(f3,f1,3);
  //printf("f1^3...\n"); fps_show(f3);
  //printf("1+x...\n"); fps_show(xp1);
  fps_log(f3,xp1);
  //printf("log(1+x)...\n"); fps_show(f3);
}

void testW0(int n, int digits) {
  // maple checks...
  //printf("T...\n"); fps_show(T);
  //> T:=series(sum(n^(n-1)*z^n/n!,n=1..infinity),z=0,10);
  //> lprint(series(T-T^2/2,z));
  //series(1*z+1/2*z^2+1/2*z^3+2/3*z^4+25/24*z^5+O(z^6),z,6)
  //> lprint(series(T-T^2/2,z=0,10));
  //series(1*z+1/2*z^2+1/2*z^3+2/3*z^4+25/24*z^5+9/5*z^6+2401/720*z^7+2048/315*z^8+59049/4480*z^9+O(z^10),z,10)
  //printf("W_{-1}...\n"); fps_show(Wm1); fps_list(Wm1);
  //> lprint(series(-log(1-T)/2-T/2-T^2/4,z=0,10));
  //series(1/6*z^3+5/8*z^4+37/20*z^5+61/12*z^6+4553/336*z^7+8551/240*z^8+26809/288*z^9+O(z^10),z,10)
  int i;
  mpq_t z;
  fps_t f1,f2,f3,f4,T,Wm1,W0,W1;
  mpq_init(z);
  f1=fps_init(n);
  f2=fps_init(n);
  f3=fps_init(n);
  f4=fps_init(n);
  T=fps_init(n);
  Wm1=fps_init(n);
  W0 =fps_init(n);
  W1 =fps_init(n);
  fps_get_W(Wm1,W0,W1,n);
  fps_egf_to_ogf(f1,Wm1);
  //printf("# ogf(W_{-1})...\n"); fps_list(f1);
  fps_egf_to_ogf(f2,W0);
  //printf("# ogf(W_0)...\n"); fps_list(f2);
  fps_egf_to_ogf(f3,W1);
  for (i=0; i<=n; i++) {
    printf("%d ",i);
    fps_getterm(z,f1,i);
    mpq_out_str(stdout,10,z); // Wm1[i]
    printf(" ");
    fps_getterm(z,f2,i);
    mpq_out_str(stdout,10,z); // W0[i]
    printf(" ");
    fps_getterm(z,f3,i);
    mpq_out_str(stdout,10,z); // W1[i]
    printf("\n");
  }
}

int main(int argc, char* argv[]) {
  int n=100,digits=50;
  if (argc>1) n=atoi(argv[1]); 
  if (argc>2) digits=atoi(argv[2]); 
  fprintf(stderr,"%s\n",fps_version);
  testW0(n,digits);
  return 0;
}
