eigenmath/binomial.cpp

114 lines
1.4 KiB
C++
Raw Permalink Normal View History

2004-03-03 21:24:06 +01:00
// Binomial coefficient
//
// Input: tos-2 n
//
// tos-1 k
//
// Output: Binomial coefficient on stack
//
// binomial(n, k) = n! / k! / (n - k)!
//
// The binomial coefficient vanishes for k < 0 or k > n. (A=B, p. 19)
2005-06-30 03:25:26 +02:00
#include "stdafx.h"
2004-03-03 21:24:06 +01:00
#include "defs.h"
2005-06-30 03:16:38 +02:00
static void ybinomial(void);
2004-03-03 21:24:06 +01:00
static int check_args(void);
2005-06-30 03:16:38 +02:00
void
eval_binomial(void)
{
push(cadr(p1));
eval();
push(caddr(p1));
eval();
binomial();
}
2004-03-03 21:24:06 +01:00
void
binomial(void)
{
save();
2005-06-30 03:16:38 +02:00
ybinomial();
2004-03-03 21:24:06 +01:00
restore();
}
#define N p1
#define K p2
static void
2005-06-30 03:16:38 +02:00
ybinomial(void)
2004-03-03 21:24:06 +01:00
{
K = pop();
N = pop();
if (check_args() == 0) {
2004-06-25 22:45:15 +02:00
push(zero);
2004-03-03 21:24:06 +01:00
return;
}
push(N);
factorial();
push(K);
factorial();
divide();
push(N);
push(K);
subtract();
factorial();
divide();
}
static int
check_args(void)
{
2004-06-25 22:45:15 +02:00
if (isnum(N) && lessp(N, zero))
2004-03-03 21:24:06 +01:00
return 0;
2004-06-25 22:45:15 +02:00
else if (isnum(K) && lessp(K, zero))
2004-03-03 21:24:06 +01:00
return 0;
else if (isnum(N) && isnum(K) && lessp(N, K))
return 0;
else
return 1;
}
2007-05-08 16:57:30 +02:00
#if SELFTEST
2004-03-03 21:24:06 +01:00
char *s[] = {
"binomial(12,6)",
"924",
"binomial(n,k)",
// "1/(factorial(k))*factorial(n)*1/(factorial(-k+n))",
// "factorial(n)/(factorial(k)*factorial(-k+n))",
"n!/(k!*(-k+n)!)",
"binomial(0,k)",
// "1/(factorial(k))*1/(factorial(-k))",
// "1/(factorial(k)*factorial(-k))",
"1/(k!*(-k)!)",
"binomial(n,0)",
"1",
"binomial(-1,k)",
"0",
"binomial(n,-1)",
"0",
};
void
test_binomial(void)
{
test(__FILE__, s, sizeof s / sizeof (char *));
}
2007-05-08 16:57:30 +02:00
#endif