realroot_doc 0.1.1
|
00001 #ifndef realroot_SOLVE_SBDSLV_BINOMIALS_H 00002 #define realroot_SOLVE_SBDSLV_BINOMIALS_H 00003 00004 #include <vector> 00005 #include <assert.h> 00006 //-------------------------------------------------------------------- 00007 namespace mmx { 00008 00009 #ifndef WITH_POW 00010 #define WITH_POW 00011 template<class T> 00012 T pow(const T& a, int i) 00013 { 00014 assert(i>=0); 00015 if(i == 1) return a; 00016 if(i > 0) 00017 { 00018 if (a == T(1)) return a; 00019 if (a == T(-1)) return (i % 2 == 0) ? T(1) : T(-1); 00020 T y(a); 00021 T z(1); 00022 unsigned int n = i; 00023 unsigned int m; 00024 while (n > 0) { 00025 m = n / 2; 00026 if (n %2 ) 00027 { 00028 z *= y; 00029 } 00030 y = y * y; 00031 n = m; 00032 } 00033 return z; 00034 } 00035 return T(1); 00036 } 00037 #endif //WITH_POW 00038 //---------------------------------------------------------------------- 00040 template <typename T> T factorial(int n) 00041 { 00042 T r=1; 00043 for (int i=2;i<=n;i++) r*=n; 00044 return(r); 00045 } 00046 00047 00048 #ifndef WITH_BINOMIAL 00049 #define WITH_BINOMIAL 00050 00052 template <typename T> T binomial(int n, int p) 00053 { 00054 T n1=1; 00055 00056 if(p!=0) 00057 { 00058 if((n-p)<p) p=n-p; 00059 int n2=n; 00060 for(int i=1;i<=p;i++,n2--) n1=n1*n2/T(i); 00061 } 00062 00063 return(n1); 00064 } 00065 #endif //WITH_BINOMIAL 00066 //---------------------------------------------------------------------- 00067 template<typename C> 00068 struct binomials { 00069 static binomials default_; 00070 std::vector<int> offs; 00071 std::vector<C> data; 00072 binomials(const binomials& b):offs(b.offs),data(b.data) {} 00073 binomials(); 00074 // return the list [ binomial(d,i) ], for i = 0..d 00075 const C* operator[]( int d ); 00076 const C& operator()( int i, int j ) { return (*this)[i][j]; }; 00077 }; 00078 00079 // IMPLEMENTATION 00080 00081 template<class C> 00082 binomials<C>::binomials() : offs(2), data(3) 00083 { 00084 offs[0] = 0; data[0] = 1; 00085 offs[1] = 1; data[offs[1]] = 1; data[offs[1]+1] = 1; 00086 }; 00087 00088 template<class C> binomials<C> binomials<C>::default_; 00089 00090 template<class C> 00091 const C* binomials<C>::operator[]( int d ) 00092 { 00093 int s,j,x; 00094 if ( (s=offs.size()) > d ) return &*(data.begin())+offs[d]; 00095 for ( x = 0, j = s; j <= d; x += j+1, j ++ ) {} 00096 offs.resize(d+1); 00097 data.resize(data.size()+x); 00098 for ( j = s; j <= d; j ++ ) 00099 { 00100 offs[j] = offs[j-1] + j; 00101 for ( int i = 0; i < j-1; i ++ ) 00102 data[offs[j]+i+1] = data[offs[j-1]+i] + data[offs[j-1]+i+1]; 00103 data[offs[j]] = data[offs[j]+j] = 1; 00104 }; 00105 return &*(data.begin())+offs[d]; 00106 }; 00107 00108 } //namespace mmx 00109 00110 #endif