[BACK]Return to taka_pfp.rr CVS log [TXT][DIR] Up to [local] / OpenXM / src / asir-contrib / packages / src

File: [local] / OpenXM / src / asir-contrib / packages / src / taka_pfp.rr (download)

Revision 1.11, Tue Mar 11 02:00:53 2003 UTC (21 years, 2 months ago) by takayama
Branch: MAIN
CVS Tags: R_1_3_1-2, RELEASE_1_3_1_13b, RELEASE_1_2_3_12, RELEASE_1_2_3, RELEASE_1_2_2_KNOPPIX_b, RELEASE_1_2_2_KNOPPIX, RELEASE_1_2_2, KNOPPIX_2006, HEAD, DEB_REL_1_2_3-9
Changes since 1.10: +8 -4 lines

Fixed a bug for a complex step size.

/* $OpenXM: OpenXM/src/asir-contrib/packages/src/taka_pfp.rr,v 1.11 2003/03/11 02:00:53 takayama Exp $ */

/* Table. It should be moved to ??? in a fugure. Experimental */
#define Xm_eval_in_quote  0
#define Xm_eval_in_series 0x100
#define Xm_eval_in_num    0x200
/* minor numbers */
#define Xm_eval_mask       0xff
#define Xm_by_series       0
#define Xm_by_int          1
#define Xm_by_runge_kutta  2
#define Xm_by_conn_formula 3

                        /* _need space */
Xm_eval = Xm_eval_in_num  $

def taka_pfp_hypergeometric_pfq(A,B,Z) {
  extern Xm_eval;
  if (iand(Xm_eval,Xm_eval_in_series)) {
    return taka_pfp(A,B,Z,10); /* first ten terms, experimental */
  }
  if (iand(Xm_eval,Xm_eval_in_num)) {
    if (iand(Xm_eval,Xm_eval_mask) == Xm_by_int) {
       if (length(A) == 2 && length(B) == 1) {
          return tam_int1_2f1(A[0],A[1],B[0],Z);
       }
    }
    if (iand(Xm_eval,Xm_eval_mask) == Xm_by_runge_kutta) {
       return taka_pfp_runge_kutta(A,B,Z);
    }
    if (iand(Xm_eval,Xm_eval_mask) == Xm_by_conn_formula) {
       return tam_conn_pfq(A,B,Z);
    }
    /* Else use series */
    return taka_pfp(A,B,Z,10);
  }
  F=base_replace(quote(hypergeometric_pfp(a,b,z)),
                 [[a,A],[b,B],[z,Z]]);
  return F;
}

def taka_pfp_hypergeometric_2f1(A,B,C,Z) {
  return taka_pfp_hypergeometric_pfq([A,B],[C],Z);
}

def taka_pfp_gamma(A) {
  extern Xm_eval;
  if (Xm_eval == 0) {
    F=base_replace(quote(hypergeometric_gamma(a)),
                 [[a,A]]);
    return F;
  }else{
    return(pari(gamma,A));
  }
}

/* They have not yet been registered in names.rr */

/* Codes from misc/200205/runge-kutta.rr */
def taka_pfp_poch(A,B,N) {
  R = 1;
  M1 = length(A);
  M2 = length(B);
  for (I=0; I<N; I++) {
    for (J=0; J<M1; J++) {
      R = R*(A[J]+I);
    }
    for (J=0; J<M2; J++) {
      R = R/(B[J]+I);
    }
    R = R/(I+1);
  }
  return(R);
}
def taka_pfp_poch1(A,B,N) {
  R = 1;
  M1 = length(A);
  M2 = length(B);
  for (I=0; I<N; I++) {
    for (J=0; J<M1; J++) {
      R = R*(A[J]+I);
    }
    for (J=0; J<M2; J++) {
      R = R/(B[J]+I);
    }
  }
  return(R);
}

def taka_pfp_poch2(A,B,N,R) {
  if (N == 0) return R;
  M1 = length(A);
  M2 = length(B);
  for (J=0; J<M1; J++) {
      R = R*(A[J]+N-1);
  }
  for (J=0; J<M2; J++) {
      R = R/(B[J]+N-1);
  }
  R = R/N;
  return(R);
}

def taka_pfp(A,B,Z,N) {
  R = 0; P = 1;
  for (I=0; I<N; I++) {
     P = taka_pfp_poch2(A,B,I,P);
     R = R+P*Z^I;
  }
  return(R);
}

/*&usage  pfp_euler_derivates(A,B,Z,N,M)
  It returns
  (F,T F, T^2 F, ..., T^M F) where T is the euler operator z d/dz.
 example: taka_pfp_euler_derivatives([1/12,5/12],[1/2],0.4,20,2);
 example: taka_pfp_euler_derivatives([1/12,5/12],[1/2],
             eval(exp(0)*1323/1331),300,2);
*/
/*  test data.
z*D[z*D[ Hypergeometric2F1[1/12,5/12,1/2,z],z],z] /. z->0.4
--> 0.07856325931358881
z*D[z*D[ Hypergeometric2F1[1/12,5/12,1/2,z],z],z] /. z->1323/1331
--> 1992.8936...  (The error is about 1992-1073.)
*/
def taka_pfp_euler_derivatives(A,B,Z,N,M) {
  Ans = newvect(M+1);
  for (I=0; I<=M; I++) Ans[I] = 0;
  P = 1;
  for (I=0; I<N; I++) {
     P = taka_pfp_poch2(A,B,I,P);
     Zi = Z^I;
     C = 1;
     for (J=0; J<=M; J++) {
       Ans[J] += P*Zi*C;  /* C = I^J */
       C   *= I;  
     }
  }
  return(vtol(Ans));
}

def taka_pfp_series(A,B,Z,N) {
  F = taka_pfp(A,B,Z,N);
  F1 = nm(F);
  F2 = dn(F);
  R = [];
  for (I=0; I<N; I++) {
    G1 = coef(F1,I,Z);
    G1 = red(G1/F2);
    R = cons(G1,R);
  }
  return R;
}

/* (th{x}+cc[1])(th{x}+cc[2])(th{x}+cc[3])(th{x}+cc[4])(th{x}+cc[5])  
     - x (th{x}+aa[1])(th{x}+aa[2])(th{x}+aa[3])(th{x}+aa[4])(th{x}+aa[5]) */
/* 
Taka_pfp_rule = [[cc[1],0],[cc[2],c1-1],[cc[3],c2-1],[cc[4],c3-1],[cc[5],c4-1],
                 [aa[1],a1],[aa[2],a2],[aa[3],a3],[aa[4],a4],[aa[5],a5]]$
*/
def taka_pfp_rule(CC,Size) {
  Rule = [[taka_pfp_iv(CC,1),0]];
  for (I=2; I<=Size; I++) {
    Rule = cons([taka_pfp_iv(CC,I),taka_pfp_iv(CC,I-1)-1],Rule);
  }
  return Rule;
}

def taka_pfp_iv(V,I) {
  return strtov(rtostr(V)+rtostr(I));
}

/* Differential equation for p F p-1 is  dY/dx=omega[] Y       */
def taka_pfp_omega(Size) {
     Aaa = taka_pfp_fun(aa,Size); Ccc = taka_pfp_fun(cc,Size); 
     Tmp = newvect(Size);
     for (K=0; K<Size-1; K++) Tmp[K] = taka_pfp_nvec(K+1,Size);
     Tmp[Size-1] = taka_pfp_nnvec(Aaa,Ccc,Size);
     Tmp = map(vtol,Tmp);
     Tmp = vtol(Tmp);
     Tmp = newmat(Size,Size,Tmp);
     return base_replace(Tmp,taka_pfp_rule(cc,Size));
}

def taka_pfp_fun(Bb,Size) {
  Tmp = 1;
  for (K=1; K<=Size; K++) {
    Tmp = Tmp*(x+taka_pfp_iv(Bb,K));
  }
  Ans = newvect(Size);
  for (K=0; K<Size; K++) {
    Ans[K] = coef(Tmp,K,x);
  }
  return Ans;
}

def taka_pfp_nvec(K,Size) {
  Tmp = newvect(Size);
  Tmp[K] = 1/x;
  return Tmp;
}

def taka_pfp_nnvec(Aaa,Ccc,Size) {
  Tmp = newvect(Size);
  for (K=0; K<Size; K++) {
    Tmp[K] = (Aaa[K]*x-Ccc[K])/(x*(1-x));
  }
  return Tmp;
}

/*
 Taka_pfp_rule1 
=[[aa1,1/5], [aa2,1/5], [aa3,1/5], [aa4,1/5],[aa5,1],
  [cc1,2/5], [cc2, 3/5],[cc3,4/5], [cc4,1]]
*/
def taka_pfp_1_omega() {
   Taka_pfp_rule1 
   =[[aa1,1/5], [aa2,1/5], [aa3,1/5], [aa4,1/5],
     [cc1,2/5], [cc2,3/5], [cc3,4/5]]$
   Omega = taka_pfp_omega(4);
   Omega = base_replace(Omega, Taka_pfp_rule1);
   return Omega;
}

/* 
  Test programs.
  Need glib, taka_plot.rr, taka_runge_kutta.rr 
*/
def taka_pfp_1() {
  /* Solving p F p-1 by the adaptive Runge-Kutta. */
   Omega = taka_pfp_1_omega();
   F0 = Omega*newmat(4,1,[[y1],[y2],[y3],[y4]]);
   F = newvect(4,[ F0[0][0], F0[1][0], 
                   F0[2][0], F0[3][0] ]);
   F = base_cancel(F);
   print (F);
   Y = [y1,y2,y3,y4];
   /* T=taka_runge_kutta_4_adaptive(F,x,Y,-10,[1,0,0,0],0.1,-1); */
   T=taka_runge_kutta_4_adaptive(F,x,Y,-10,[1,0,0,0.5],0.1,-0.1); 
   /* T=taka_runge_kutta_4_adaptive(F,x,Y,-0.5,[1,0,0,1],-0.1,-10); */
   /* T1 = number_real_part(T); 
   taka_plot_auto(T1); */ 
   taka_plot_auto(T);
}

def taka_pfp_2_omega() {
   Taka_pfp_rule1 
   =[[aa1,1/2], [aa2,1/2],
     [cc1,3/2]]$
   Omega = taka_pfp_omega(2);
   Omega = base_replace(Omega, Taka_pfp_rule1);
   return Omega;
}

def taka_pfp_2() {
  /* Solving 2 F 1 by the adaptive Runge-Kutta. */
   Omega = taka_pfp_2_omega();
   F0 = Omega*newmat(2,1,[[y1],[y2]]);
   F = newvect(2,[ F0[0][0], F0[1][0]]);
   F = base_cancel(F);
   print (F);
   Y = [y1,y2];
   T=taka_runge_kutta_4_adaptive(F,x,Y,0.1,[1.01746,0.018314],0.001,0.25);
   /* The initial value is computed by Mathematica */
   /* T1 = number_real_part(T); 
   taka_plot_auto(T1); */ 
   print(T[0][1]*3);
   taka_plot_auto(T);
}

def taka_pfp_aa_cc_rule(A,B) {
  Rule = [ ];
  P = length(A);
  Q = length(B);
  for (I=0; I<P; I++) {
    Rule = cons([taka_pfp_iv(aa,I+1),A[I]],Rule);
  }
  for (I=0; I<Q; I++) {
    Rule = cons([taka_pfp_iv(cc,I+1),B[I]],Rule);
  }
  return Rule;
}

/*&usage  pfp_runge_kutta(A,B,Z)
 example: taka_pfp_runge_kutta([1/12,5/12],[1/2],1323/1331); -->exact: 1.3659
 example: taka_pfp_runge_kutta([7/2,7/2],[31/5],1.3+1.3*@i);
             -------> exact: -0.7973029718645974 - 0.5288535335094111*I
 example: taka_pfp_runge_kutta([7/2,7/2],[31/5],13+13*@i);
             -------> exact: 0.001644777051991857 + 0.0005057784138817566*I
*/
#define SERIES_N  30
#define SERIES_LIMIT 0.5
#define INITIAL_STEP 100
def taka_pfp_runge_kutta(A,B,Z) {
  P = length(A); Q = length(B);
  if (P-1 != Q) {
    print([A,B,Z]);
    error("pfp_runge_kutta() does not work for these parameters.");
  }
  if (Z == 1) error("pfp_runge_kutta() cannot evaluate the value at z=1.");
  for (I=0; I<Q; I++) {
    if (type(B[I]) <= 1) {
      if ((ntype(B[I]) == 0) && (dn(B[I]) == 1) && (B[I] < 0)) {
        error("p F q is not defined for parameters in negative integers.");
      }
    }
  }

  /* cf. taka_pfp_1() */
  Omega = taka_pfp_omega(P);
  Ylist1 = [ ];  Ylist0 = [ ];
  for (I=1; I<=P; I++) {
    Ylist1 = cons([taka_pfp_iv("y",I)],Ylist1);
    Ylist0 = cons(taka_pfp_iv("y",I),Ylist0);
  }
  Ylist1 = reverse(Ylist1); Ylist0 = reverse(Ylist0);

  F0 = Omega*newmat(P,1,Ylist1);
  Ylist2 = [ ];
  for (I=0; I<P; I++) {
    Ylist2 = cons(F0[I][0], Ylist2);
  }
  Ylist2 = reverse(Ylist2);

  F = newvect(P,Ylist2);
  F = base_cancel(F);

  Y = Ylist0;

  if (number_abs(Z) < SERIES_LIMIT) {
    return eval(taka_pfp(A,B,eval(exp(0)*Z),SERIES_N));
  }

  if (imag(Z) == 0 && Z > 1) {
     error("pfp_runge_kutta() cannot evalute the value on [1,infty]");
  }
  /* Set the staring point X0 */
  X0 = eval(Z*0.3/number_abs(Z));
  /* Set the initial step */
  H = eval((Z-X0)/INITIAL_STEP);

  InitialValue = taka_pfp_euler_derivatives(A,B,X0,SERIES_N,P-1);
  Rule = taka_pfp_aa_cc_rule(A,B);
  F = base_replace(F,Rule);

  T = taka_runge_kutta_4_adaptive(F,x,Y,X0,InitialValue,H,Z);
  print("Stopped to use the adaptive method. Step size is "+rtostr(H));
  T2 = taka_runge_kutta_4(F,x,Y,T[1][0],cdr(T[1]),H,Z);
  return [[T2[0][0],T2[0][1]], T, T2];  
}

Loaded_taka_pfp=1$
end$