integral.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. #include "stdafx.h"
  2. #include "defs.h"
  3. #define F p3
  4. #define X p4
  5. #define N p5
  6. void
  7. eval_integral(void)
  8. {
  9. int i, n;
  10. // evaluate 1st arg to get function F
  11. p1 = cdr(p1);
  12. push(car(p1));
  13. eval();
  14. // evaluate 2nd arg and then...
  15. // example result of 2nd arg what to do
  16. //
  17. // integral(f) nil guess X, N = nil
  18. // integral(f,2) 2 guess X, N = 2
  19. // integral(f,x) x X = x, N = nil
  20. // integral(f,x,2) x X = x, N = 2
  21. // integral(f,x,y) x X = x, N = y
  22. p1 = cdr(p1);
  23. push(car(p1));
  24. eval();
  25. p2 = pop();
  26. if (p2 == symbol(NIL)) {
  27. guess();
  28. push(symbol(NIL));
  29. } else if (isnum(p2)) {
  30. guess();
  31. push(p2);
  32. } else {
  33. push(p2);
  34. p1 = cdr(p1);
  35. push(car(p1));
  36. eval();
  37. }
  38. N = pop();
  39. X = pop();
  40. F = pop();
  41. while (1) {
  42. // N might be a symbol instead of a number
  43. if (isnum(N)) {
  44. push(N);
  45. n = pop_integer();
  46. if (n == (int) 0x80000000)
  47. stop("nth integral: check n");
  48. } else
  49. n = 1;
  50. push(F);
  51. if (n >= 0) {
  52. for (i = 0; i < n; i++) {
  53. push(X);
  54. integral();
  55. }
  56. } else {
  57. n = -n;
  58. for (i = 0; i < n; i++) {
  59. push(X);
  60. derivative();
  61. }
  62. }
  63. F = pop();
  64. // if N is nil then arglist is exhausted
  65. if (N == symbol(NIL))
  66. break;
  67. // otherwise...
  68. // N arg1 what to do
  69. //
  70. // number nil break
  71. // number number N = arg1, continue
  72. // number symbol X = arg1, N = arg2, continue
  73. //
  74. // symbol nil X = N, N = nil, continue
  75. // symbol number X = N, N = arg1, continue
  76. // symbol symbol X = N, N = arg1, continue
  77. if (isnum(N)) {
  78. p1 = cdr(p1);
  79. push(car(p1));
  80. eval();
  81. N = pop();
  82. if (N == symbol(NIL))
  83. break; // arglist exhausted
  84. if (isnum(N))
  85. ; // N = arg1
  86. else {
  87. X = N; // X = arg1
  88. p1 = cdr(p1);
  89. push(car(p1));
  90. eval();
  91. N = pop(); // N = arg2
  92. }
  93. } else {
  94. X = N; // X = N
  95. p1 = cdr(p1);
  96. push(car(p1));
  97. eval();
  98. N = pop(); // N = arg1
  99. }
  100. }
  101. push(F); // final result
  102. }
  103. void
  104. integral(void)
  105. {
  106. save();
  107. p2 = pop();
  108. p1 = pop();
  109. if (car(p1) == symbol(ADD))
  110. integral_of_sum();
  111. else if (car(p1) == symbol(MULTIPLY))
  112. integral_of_product();
  113. else
  114. integral_of_form();
  115. p1 = pop();
  116. if (find(p1, symbol(INTEGRAL)))
  117. stop("integral: sorry, could not find a solution");
  118. push(p1);
  119. simplify(); // polish the result
  120. eval(); // normalize the result
  121. restore();
  122. }
  123. void
  124. integral_of_sum(void)
  125. {
  126. p1 = cdr(p1);
  127. push(car(p1));
  128. push(p2);
  129. integral();
  130. p1 = cdr(p1);
  131. while (iscons(p1)) {
  132. push(car(p1));
  133. push(p2);
  134. integral();
  135. add();
  136. p1 = cdr(p1);
  137. }
  138. }
  139. void
  140. integral_of_product(void)
  141. {
  142. push(p1);
  143. push(p2);
  144. partition();
  145. p1 = pop(); // pop variable part
  146. integral_of_form();
  147. multiply(); // multiply constant part
  148. }
  149. extern char *itab[];
  150. void
  151. integral_of_form(void)
  152. {
  153. push(p1);
  154. push(p2);
  155. transform(itab);
  156. p3 = pop();
  157. if (p3 == symbol(NIL)) {
  158. push_symbol(INTEGRAL);
  159. push(p1);
  160. push(p2);
  161. list(3);
  162. } else
  163. push(p3);
  164. }