laguerre.cpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /* Laguerre function
  2. Example
  3. laguerre(x,3)
  4. Result
  5. 1 3 3 2
  6. - --- x + --- x - 3 x + 1
  7. 6 2
  8. The computation uses the following recurrence relation.
  9. L(x,0,k) = 1
  10. L(x,1,k) = -x + k + 1
  11. n*L(x,n,k) = (2*(n-1)+1-x+k)*L(x,n-1,k) - (n-1+k)*L(x,n-2,k)
  12. In the "for" loop i = n-1 so the recurrence relation becomes
  13. (i+1)*L(x,n,k) = (2*i+1-x+k)*L(x,n-1,k) - (i+k)*L(x,n-2,k)
  14. */
  15. #include "stdafx.h"
  16. #include "defs.h"
  17. void
  18. eval_laguerre(void)
  19. {
  20. // 1st arg
  21. push(cadr(p1));
  22. eval();
  23. // 2nd arg
  24. push(caddr(p1));
  25. eval();
  26. // 3rd arg
  27. push(cadddr(p1));
  28. eval();
  29. p2 = pop();
  30. if (p2 == symbol(NIL))
  31. push_integer(0);
  32. else
  33. push(p2);
  34. laguerre();
  35. }
  36. #define X p1
  37. #define N p2
  38. #define K p3
  39. #define Y p4
  40. #define Y0 p5
  41. #define Y1 p6
  42. void
  43. laguerre(void)
  44. {
  45. int n;
  46. save();
  47. K = pop();
  48. N = pop();
  49. X = pop();
  50. push(N);
  51. n = pop_integer();
  52. if (n < 0) {
  53. push_symbol(LAGUERRE);
  54. push(X);
  55. push(N);
  56. push(K);
  57. list(4);
  58. restore();
  59. return;
  60. }
  61. if (issymbol(X))
  62. laguerre2(n);
  63. else {
  64. Y = X; // do this when X is an expr
  65. X = symbol(SECRETX);
  66. laguerre2(n);
  67. X = Y;
  68. push(symbol(SECRETX));
  69. push(X);
  70. subst();
  71. eval();
  72. }
  73. restore();
  74. }
  75. void
  76. laguerre2(int n)
  77. {
  78. int i;
  79. push_integer(1);
  80. push_integer(0);
  81. Y1 = pop();
  82. for (i = 0; i < n; i++) {
  83. Y0 = Y1;
  84. Y1 = pop();
  85. push_integer(2 * i + 1);
  86. push(X);
  87. subtract();
  88. push(K);
  89. add();
  90. push(Y1);
  91. multiply();
  92. push_integer(i);
  93. push(K);
  94. add();
  95. push(Y0);
  96. multiply();
  97. subtract();
  98. push_integer(i + 1);
  99. divide();
  100. }
  101. }
  102. #if SELFTEST
  103. static char *s[] = {
  104. "laguerre(x,n)",
  105. "laguerre(x,n,0)",
  106. "laguerre(x,n,k)",
  107. "laguerre(x,n,k)",
  108. "laguerre(x,0)-1",
  109. "0",
  110. "laguerre(x,1)-(-x+1)",
  111. "0",
  112. "laguerre(x,2)-1/2*(x^2-4*x+2)",
  113. "0",
  114. "laguerre(x,3)-1/6*(-x^3+9*x^2-18*x+6)",
  115. "0",
  116. "laguerre(x,0,k)-1",
  117. "0",
  118. "laguerre(x,1,k)-(-x+k+1)",
  119. "0",
  120. "laguerre(x,2,k)-1/2*(x^2-2*(k+2)*x+(k+1)*(k+2))",
  121. "0",
  122. "laguerre(x,3,k)-1/6*(-x^3+3*(k+3)*x^2-3*(k+2)*(k+3)*x+(k+1)*(k+2)*(k+3))",
  123. "0",
  124. "laguerre(a-b,10)-eval(subst(a-b,x,laguerre(x,10)))",
  125. "0",
  126. };
  127. void
  128. test_laguerre(void)
  129. {
  130. test(__FILE__, s, sizeof s / sizeof (char *));
  131. }
  132. #endif