eigenmath/integral.cpp

191 lines
2.8 KiB
C++
Raw Permalink Normal View History

2004-07-22 01:30:24 +02:00
#include "stdafx.h"
2004-03-03 21:24:06 +01:00
#include "defs.h"
2005-08-21 03:19:56 +02:00
#define F p3
#define X p4
#define N p5
void
eval_integral(void)
{
int i, n;
// evaluate 1st arg to get function F
p1 = cdr(p1);
push(car(p1));
eval();
// evaluate 2nd arg and then...
// example result of 2nd arg what to do
//
// integral(f) nil guess X, N = nil
// integral(f,2) 2 guess X, N = 2
// integral(f,x) x X = x, N = nil
// integral(f,x,2) x X = x, N = 2
// integral(f,x,y) x X = x, N = y
p1 = cdr(p1);
push(car(p1));
eval();
p2 = pop();
2006-01-16 20:37:31 +01:00
if (p2 == symbol(NIL)) {
2005-08-21 03:19:56 +02:00
guess();
2006-01-16 20:37:31 +01:00
push(symbol(NIL));
2005-08-21 03:19:56 +02:00
} else if (isnum(p2)) {
guess();
push(p2);
} else {
push(p2);
p1 = cdr(p1);
push(car(p1));
eval();
}
N = pop();
X = pop();
F = pop();
while (1) {
// N might be a symbol instead of a number
if (isnum(N)) {
push(N);
n = pop_integer();
if (n == (int) 0x80000000)
stop("nth integral: check n");
} else
n = 1;
push(F);
if (n >= 0) {
for (i = 0; i < n; i++) {
push(X);
integral();
}
} else {
n = -n;
for (i = 0; i < n; i++) {
push(X);
derivative();
}
}
F = pop();
// if N is nil then arglist is exhausted
2006-01-16 20:37:31 +01:00
if (N == symbol(NIL))
2005-08-21 03:19:56 +02:00
break;
// otherwise...
// N arg1 what to do
//
// number nil break
// number number N = arg1, continue
// number symbol X = arg1, N = arg2, continue
//
// symbol nil X = N, N = nil, continue
// symbol number X = N, N = arg1, continue
// symbol symbol X = N, N = arg1, continue
if (isnum(N)) {
p1 = cdr(p1);
push(car(p1));
eval();
N = pop();
2006-01-16 20:37:31 +01:00
if (N == symbol(NIL))
2005-08-21 03:19:56 +02:00
break; // arglist exhausted
if (isnum(N))
; // N = arg1
else {
X = N; // X = arg1
p1 = cdr(p1);
push(car(p1));
eval();
N = pop(); // N = arg2
}
} else {
X = N; // X = N
p1 = cdr(p1);
push(car(p1));
eval();
N = pop(); // N = arg1
}
}
2007-05-15 18:33:30 +02:00
push(F); // final result
2005-08-21 03:19:56 +02:00
}
2004-03-03 21:24:06 +01:00
void
integral(void)
{
save();
p2 = pop();
p1 = pop();
2004-07-22 01:30:24 +02:00
if (car(p1) == symbol(ADD))
2004-03-03 21:24:06 +01:00
integral_of_sum();
2004-07-22 01:30:24 +02:00
else if (car(p1) == symbol(MULTIPLY))
2004-03-03 21:24:06 +01:00
integral_of_product();
2004-07-22 01:30:24 +02:00
else
integral_of_form();
2007-05-16 04:34:44 +02:00
p1 = pop();
if (find(p1, symbol(INTEGRAL)))
stop("integral: sorry, could not find a solution");
push(p1);
simplify(); // polish the result
eval(); // normalize the result
2006-05-12 22:17:48 +02:00
restore();
2004-03-03 21:24:06 +01:00
}
2006-05-12 22:17:48 +02:00
void
2004-03-03 21:24:06 +01:00
integral_of_sum(void)
{
2004-07-22 01:30:24 +02:00
p1 = cdr(p1);
push(car(p1));
push(p2);
integral();
2004-03-03 21:24:06 +01:00
p1 = cdr(p1);
while (iscons(p1)) {
push(car(p1));
push(p2);
integral();
2004-07-22 01:30:24 +02:00
add();
2004-03-03 21:24:06 +01:00
p1 = cdr(p1);
}
}
2006-05-12 22:17:48 +02:00
void
2004-03-03 21:24:06 +01:00
integral_of_product(void)
{
2006-06-01 22:41:33 +02:00
push(p1);
push(p2);
partition();
p1 = pop(); // pop variable part
integral_of_form();
multiply(); // multiply constant part
2004-03-03 21:24:06 +01:00
}
2006-05-12 22:17:48 +02:00
extern char *itab[];
2005-12-16 02:09:51 +01:00
void
2006-05-12 22:17:48 +02:00
integral_of_form(void)
2005-12-16 02:09:51 +01:00
{
2006-05-12 22:17:48 +02:00
push(p1);
push(p2);
transform(itab);
p3 = pop();
if (p3 == symbol(NIL)) {
push_symbol(INTEGRAL);
push(p1);
push(p2);
list(3);
} else
push(p3);
2005-12-16 02:09:51 +01:00
}