00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef _BINOM_H
00034 #define _BINOM_H
00035
00036 #include <stdexcept>
00037 #include <vector>
00038
00039 namespace Go {
00042
00043
00044
00046 inline double binom(int n, int i)
00047 {
00048 if (i < 0 || i > n)
00049 return 0.0;
00050
00051 static std::vector<std::vector<double> > pascals_triangle(10);
00052 static bool first_time = true;
00053 if (first_time) {
00054 first_time = false;
00055 pascals_triangle.resize(1);
00056 pascals_triangle[0].resize(1);
00057 pascals_triangle[0][0] = 1;
00058 }
00059 int old_size = pascals_triangle.size();
00060 if (old_size < n+1) {
00061
00062 pascals_triangle.resize(n+1);
00063
00064 for (int nr = old_size; nr < n+1; ++nr) {
00065 pascals_triangle[nr].resize(nr+1);
00066 pascals_triangle[nr][0] = 1.0;
00067 for (int j = 1; j < nr; ++j) {
00068 pascals_triangle[nr][j]
00069 = pascals_triangle[nr-1][j-1] + pascals_triangle[nr-1][j];
00070 }
00071 pascals_triangle[nr][nr] = 1.0;
00072 }
00073 }
00074 return pascals_triangle[n][i];
00075 }
00076
00078 inline double factorial(int n)
00079 {
00080 double res = 1;
00081 for (int i = 2; i <= n; ++i) {
00082 res *= i;
00083 }
00084 return res;
00085 }
00086
00088 inline double trinomial(int n, int i, int j)
00089 {
00090 if (i < 0 || i > n || j < 0 || j > n)
00091 return 0;
00092
00093 return binom(n, i) * binom(n-i, j);
00094 }
00095
00096
00098 inline double quadrinomial(int n, int i, int j, int k)
00099 {
00100 if (i < 0 || i > n || j < 0 || j > n || k < 0 || k > n)
00101 return 0;
00102
00103 return binom(n, i) * binom(n-i, j) * binom(n-i-j, k);
00104 }
00105
00107 };
00108
00109 #endif // _BINOM_H
00110
00111