besselj.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /* Bessel J function
  2. 1st arg x
  3. 2nd arg n
  4. Recurrence relation
  5. besselj(x,n) = (2/x) (n-1) besselj(x,n-1) - besselj(x,n-2)
  6. besselj(x,1/2) = sqrt(2/pi/x) sin(x)
  7. besselj(x,-1/2) = sqrt(2/pi/x) cos(x)
  8. For negative n, reorder the recurrence relation as
  9. besselj(x,n-2) = (2/x) (n-1) besselj(x,n-1) - besselj(x,n)
  10. Substitute n+2 for n to obtain
  11. besselj(x,n) = (2/x) (n+1) besselj(x,n+1) - besselj(x,n+2)
  12. Examples
  13. besselj(x,3/2) = (1/x) besselj(x,1/2) - besselj(x,-1/2)
  14. besselj(x,-3/2) = -(1/x) besselj(x,-1/2) - besselj(x,1/2)
  15. */
  16. #include "stdafx.h"
  17. #include "defs.h"
  18. #include "math.h"
  19. void
  20. eval_besselj(void)
  21. {
  22. push(cadr(p1));
  23. eval();
  24. push(caddr(p1));
  25. eval();
  26. besselj();
  27. }
  28. void
  29. besselj(void)
  30. {
  31. save();
  32. yybesselj();
  33. restore();
  34. }
  35. #define X p1
  36. #define N p2
  37. #define SGN p3
  38. void
  39. yybesselj(void)
  40. {
  41. double d;
  42. int n;
  43. N = pop();
  44. X = pop();
  45. push(N);
  46. n = pop_integer();
  47. // numerical result
  48. if (isdouble(X) && n != (int) 0x80000000) {
  49. d = jn(n, X->u.d);
  50. push_double(d);
  51. return;
  52. }
  53. // bessej(0,0) = 1
  54. if (iszero(X) && iszero(N)) {
  55. push_integer(1);
  56. return;
  57. }
  58. // besselj(0,n) = 0
  59. if (iszero(X) && n != (int) 0x80000000) {
  60. push_integer(0);
  61. return;
  62. }
  63. // half arguments
  64. if (N->k == NUM && MEQUAL(N->u.q.b, 2)) {
  65. // n = 1/2
  66. if (MEQUAL(N->u.q.a, 1)) {
  67. push_integer(2);
  68. push_symbol(PI);
  69. divide();
  70. push(X);
  71. divide();
  72. push_rational(1, 2);
  73. power();
  74. push(X);
  75. sine();
  76. multiply();
  77. return;
  78. }
  79. // n = -1/2
  80. if (MEQUAL(N->u.q.a, -1)) {
  81. push_integer(2);
  82. push_symbol(PI);
  83. divide();
  84. push(X);
  85. divide();
  86. push_rational(1, 2);
  87. power();
  88. push(X);
  89. cosine();
  90. multiply();
  91. return;
  92. }
  93. // besselj(x,n) = (2/x) (n-sgn(n)) besselj(x,n-sgn(n)) - besselj(x,n-2*sgn(n))
  94. push_integer(MSIGN(N->u.q.a));
  95. SGN = pop();
  96. push_integer(2);
  97. push(X);
  98. divide();
  99. push(N);
  100. push(SGN);
  101. subtract();
  102. multiply();
  103. push(X);
  104. push(N);
  105. push(SGN);
  106. subtract();
  107. besselj();
  108. multiply();
  109. push(X);
  110. push(N);
  111. push_integer(2);
  112. push(SGN);
  113. multiply();
  114. subtract();
  115. besselj();
  116. subtract();
  117. return;
  118. }
  119. #if 0 // test cases needed
  120. if (isnegativeterm(X)) {
  121. push(X);
  122. negate();
  123. push(N);
  124. power();
  125. push(X);
  126. push(N);
  127. negate();
  128. power();
  129. multiply();
  130. push_symbol(BESSELJ);
  131. push(X);
  132. negate();
  133. push(N);
  134. list(3);
  135. multiply();
  136. return;
  137. }
  138. if (isnegativeterm(N)) {
  139. push_integer(-1);
  140. push(N);
  141. power();
  142. push_symbol(BESSELJ);
  143. push(X);
  144. push(N);
  145. negate();
  146. list(3);
  147. multiply();
  148. return;
  149. }
  150. #endif
  151. push(symbol(BESSELJ));
  152. push(X);
  153. push(N);
  154. list(3);
  155. }