revers.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /* revers.c
  2. *
  3. * Reversion of power series
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * extern int MAXPOL;
  10. * int n;
  11. * double x[n+1], y[n+1];
  12. *
  13. * polini(n);
  14. * revers( y, x, n );
  15. *
  16. * Note, polini() initializes the polynomial arithmetic subroutines;
  17. * see polyn.c.
  18. *
  19. *
  20. * DESCRIPTION:
  21. *
  22. * If
  23. *
  24. * inf
  25. * - i
  26. * y(x) = > a x
  27. * - i
  28. * i=1
  29. *
  30. * then
  31. *
  32. * inf
  33. * - j
  34. * x(y) = > A y ,
  35. * - j
  36. * j=1
  37. *
  38. * where
  39. * 1
  40. * A = ---
  41. * 1 a
  42. * 1
  43. *
  44. * etc. The coefficients of x(y) are found by expanding
  45. *
  46. * inf inf
  47. * - - i
  48. * x(y) = > A > a x
  49. * - j - i
  50. * j=1 i=1
  51. *
  52. * and setting each coefficient of x , higher than the first,
  53. * to zero.
  54. *
  55. *
  56. *
  57. * RESTRICTIONS:
  58. *
  59. * y[0] must be zero, and y[1] must be nonzero.
  60. *
  61. */
  62. /*
  63. Cephes Math Library Release 2.8: June, 2000
  64. Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier
  65. */
  66. #include <math.h>
  67. extern int MAXPOL; /* initialized by polini() */
  68. #ifdef ANSIPROT
  69. /* See polyn.c. */
  70. void polmov ( double *, int, double * );
  71. void polclr ( double *, int );
  72. void poladd ( double *, int, double *, int, double * );
  73. void polmul ( double *, int, double *, int, double * );
  74. void * malloc ( long );
  75. void free ( void * );
  76. #else
  77. void polmov(), polclr(), poladd(), polmul();
  78. void * malloc();
  79. void free ();
  80. #endif
  81. void revers( y, x, n)
  82. double y[], x[];
  83. int n;
  84. {
  85. double *yn, *yp, *ysum;
  86. int j;
  87. if( y[1] == 0.0 )
  88. mtherr( "revers", DOMAIN );
  89. /* printf( "revers: y[1] = 0\n" );*/
  90. j = (MAXPOL + 1) * sizeof(double);
  91. yn = (double *)malloc(j);
  92. yp = (double *)malloc(j);
  93. ysum = (double *)malloc(j);
  94. polmov( y, n, yn );
  95. polclr( ysum, n );
  96. x[0] = 0.0;
  97. x[1] = 1.0/y[1];
  98. for( j=2; j<=n; j++ )
  99. {
  100. /* A_(j-1) times the expansion of y^(j-1) */
  101. polmul( &x[j-1], 0, yn, n, yp );
  102. /* The expansion of the sum of A_k y^k up to k=j-1 */
  103. poladd( yp, n, ysum, n, ysum );
  104. /* The expansion of y^j */
  105. polmul( yn, n, y, n, yn );
  106. /* The coefficient A_j to make the sum up to k=j equal to zero */
  107. x[j] = -ysum[j]/yn[j];
  108. }
  109. free(yn);
  110. free(yp);
  111. free(ysum);
  112. }
  113. #if 0
  114. /* Demonstration program
  115. */
  116. #define N 10
  117. double y[N], x[N];
  118. double fac();
  119. main()
  120. {
  121. double a, odd;
  122. int i;
  123. polini( N-1 );
  124. a = 1.0;
  125. y[0] = 0.0;
  126. odd = 1.0;
  127. for( i=1; i<N; i++ )
  128. {
  129. /* sin(x) */
  130. /*
  131. if( i & 1 )
  132. {
  133. y[i] = odd/fac(i);
  134. odd = -odd;
  135. }
  136. else
  137. y[i] = 0.0;
  138. */
  139. y[i] = 1.0/fac(i);
  140. }
  141. revers( y, x, N-1 );
  142. for( i=0; i<N; i++ )
  143. printf( "%2d %.10e %.10e\n", i, x[i], y[i] );
  144. }
  145. #endif