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
|