eigenmath/gamma.cpp

149 lines
2.0 KiB
C++
Raw Permalink Normal View History

2005-07-30 21:37:29 +02:00
//-----------------------------------------------------------------------------
//
// Author : philippe.billet@noos.fr
//
// Gamma function gamma(x)
//
//-----------------------------------------------------------------------------
#include "stdafx.h"
#include "defs.h"
2005-07-31 18:39:53 +02:00
void gamma(void);
2005-07-30 21:37:29 +02:00
static void gammaf(void);
static void gamma_of_sum(void);
void
eval_gamma(void)
{
push(cadr(p1));
eval();
2005-07-31 18:39:53 +02:00
gamma();
2005-07-30 21:37:29 +02:00
}
void
2005-07-31 18:39:53 +02:00
gamma(void)
2005-07-30 21:37:29 +02:00
{
save();
gammaf();
restore();
}
static void
gammaf(void)
{
// double d;
p1 = pop();
2005-08-06 22:57:37 +02:00
if (isrational(p1) && MEQUAL(p1->u.q.a, 1) && MEQUAL(p1->u.q.b, 2)) {
2005-07-30 21:37:29 +02:00
push_symbol(PI);;
push_rational(1,2);
power();
return;
}
2005-08-06 22:57:37 +02:00
if (isrational(p1) && MEQUAL(p1->u.q.a, 3) && MEQUAL(p1->u.q.b, 2)) {
2005-07-30 21:37:29 +02:00
push_symbol(PI);;
push_rational(1,2);
power();
push_rational(1,2);
multiply();
return;
}
// if (p1->k == DOUBLE) {
// d = exp(lgamma(p1->u.d));
// push_double(d);
// return;
// }
if (isnegativeterm(p1)) {
push_symbol(PI);
push_integer(-1);
multiply();
push_symbol(PI);
push(p1);
multiply();
sine();
push(p1);
multiply();
push(p1);
negate();
2005-07-31 18:39:53 +02:00
gamma();
2005-07-30 21:37:29 +02:00
multiply();
divide();
return;
}
if (car(p1) == symbol(ADD)) {
gamma_of_sum();
return;
}
push_symbol(GAMMA);
push(p1);
list(2);
return;
}
static void
gamma_of_sum(void)
{
p3 = cdr(p1);
2005-08-06 22:57:37 +02:00
if (isrational(car(p3)) && MEQUAL(car(p3)->u.q.a, 1) && MEQUAL(car(p3)->u.q.b, 1)) {
2005-07-30 21:37:29 +02:00
push(cadr(p3));
push(cadr(p3));
2005-07-31 18:39:53 +02:00
gamma();
2005-07-30 21:37:29 +02:00
multiply();
}
else {
2005-08-06 22:57:37 +02:00
if (isrational(car(p3)) && MEQUAL(car(p3)->u.q.a, -1) && MEQUAL(car(p3)->u.q.b, 1)) {
2005-07-30 21:37:29 +02:00
push(cadr(p3));
2005-07-31 18:39:53 +02:00
gamma();
2005-07-30 21:37:29 +02:00
push(cadr(p3));
push_integer(-1);
add();
divide();
}
else {
push_symbol(GAMMA);
push(p1);
list(2);
return;
}
}
}
2007-05-08 16:57:30 +02:00
#if SELFTEST
2005-07-30 21:37:29 +02:00
static char *s[] = {
"Gamma(a)",
"Gamma(a)",
// "float(gamma(10))",
// "362880",
"Gamma(x+1)",
"x*Gamma(x)",
"Gamma(1/2)",
"pi^(1/2)",
2006-02-10 18:01:28 +01:00
"Gamma(x-1)-Gamma(x)/(-1+x)",
"0",
2005-07-30 21:37:29 +02:00
"Gamma(-x)",
"-pi/(x*Gamma(x)*sin(pi*x))",
};
void
test_gamma(void)
{
test(__FILE__, s, sizeof s / sizeof (char *));
}
2007-05-08 16:57:30 +02:00
#endif