-
Notifications
You must be signed in to change notification settings - Fork 1
/
Binomial.cpp
77 lines (63 loc) · 1.54 KB
/
Binomial.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/*
define (binomial n k)
;; Helper function to compute C(n,k) via forward recursion
(define (binomial-iter n k i prev)
(if (>= i k)
prev
(binomial-iter n k (+ i 1) (/ (* (- n i) prev) (+ i 1)))))
;; Use symmetry property C(n,k)=C(n, n-k)
(if (< k (- n k))
(binomial-iter n k 0 1)
(binomial-iter n (- n k) 0 1)))
*/
unsigned choose(unsigned n, unsigned k) {
unsigned r = 1;
unsigned d;
if (k > n) return 0;
for (d=1; d <= k; d++) {
r *= n--;
r /= d;
}
return r;
}
constexpr long long binomialIter(long long n, long long k, long long i, long long prev) {
return (i>=k) ? prev : binomialIter(n,k, i+1, ((n-i)*prev)/(i+1));
}
constexpr long long binomial(long long n, long long k) {
return (k>n) ? 0 : ( (k<(n-k)) ? binomialIter(n,k,0,1) : binomialIter(n,(n-k),0,1));
}
#include <iostream>
int main() {
for (int k=0; k!=10; ++k) {
for (int n=0; n!=10; ++n)
std::cout << choose(n,k) << " " << binomial(n,k) <<", ";
std::cout << std::endl;
}
return 0;
}
double bha(double x, double const * c, int degree) {
// double f=1.;
//for (int k=1; k!=degree; ++k)
// f*=(1.-x);
double ret=c[0];
for (int k=0; k!=degree; ++k) {
ret += c[k+1]*binomial(degree,k+1)*x;
x*=x;
}
return ret;
}
double foo(double x, double const * c) {
return bha(x,c,5);
}
double bho(double x, double const * c) {
int degree=5;
double f=1.;
for (int k=1; k!=degree; ++k)
f*=(1.-x);
x = x/(1-x);
double ret=c[degree];
for (int k=degree; k!=0; --k) {
ret += ret*x+c[k-1];
}
return f*ret;
}