$search
00001 00008 /***************************************************************************** 00009 ** Ifdefs 00010 *****************************************************************************/ 00011 00012 #ifndef ECL_GEOMETRY_PASCALS_HPP_ 00013 #define ECL_GEOMETRY_PASCALS_HPP_ 00014 00015 /***************************************************************************** 00016 ** Includes 00017 *****************************************************************************/ 00018 00019 #include <ecl/config/macros.hpp> 00020 #include <ecl/containers/array.hpp> 00021 #include <ecl/formatters/common.hpp> 00022 #include <ecl/formatters/number.hpp> 00023 00024 /***************************************************************************** 00025 ** Namespaces 00026 *****************************************************************************/ 00027 00028 namespace ecl { 00029 00030 /***************************************************************************** 00031 ** Class [PascalsTriangle] 00032 *****************************************************************************/ 00033 00056 template <int N> 00057 class ECL_PUBLIC PascalsTriangle { 00058 public: 00059 /********************* 00060 ** C&D 00061 **********************/ 00062 PascalsTriangle(); 00063 virtual ~PascalsTriangle() {}; 00064 00065 /********************* 00066 ** Iterators 00067 **********************/ 00068 typedef typename Array<int,(N+2)*(N+1)/2>::const_iterator const_iterator; 00069 const_iterator begin(unsigned int index = 0) const; 00070 const_iterator end(unsigned int index = 0) const; 00071 00072 /********************* 00073 ** Streaming 00074 **********************/ 00075 template <typename OutputStream, int PowerN> 00076 friend OutputStream& operator<<(OutputStream &ostream, const PascalsTriangle<PowerN> &triangle); 00077 00078 private: 00079 Array<int,(N+2)*(N+1)/2> coefficients; 00080 }; 00081 /***************************************************************************** 00082 ** Specialisations [Pascals Triangle][3] 00083 *****************************************************************************/ 00094 template <> 00095 class ECL_PUBLIC PascalsTriangle<3> { 00096 public: 00097 /********************* 00098 ** C&D 00099 **********************/ 00106 PascalsTriangle(); 00107 virtual ~PascalsTriangle() {}; 00108 00109 /********************* 00110 ** Iterators 00111 **********************/ 00112 typedef Array<int,10>::const_iterator const_iterator; 00120 const_iterator begin(unsigned int index = 0) const; 00128 const_iterator end(unsigned int index = 0) const; 00129 00130 /********************* 00131 ** Streaming 00132 **********************/ 00133 template <typename OutputStream> 00134 friend OutputStream& operator<<(OutputStream &ostream, const PascalsTriangle<3> &triangle); 00135 00136 private: 00137 Array<int,10> coefficients; 00138 }; 00139 00140 /***************************************************************************** 00141 ** Specialisations [Pascals Triangle][5] 00142 *****************************************************************************/ 00153 template <> 00154 class ECL_PUBLIC PascalsTriangle<5> { 00155 public: 00156 /********************* 00157 ** C&D 00158 **********************/ 00165 PascalsTriangle(); 00166 virtual ~PascalsTriangle() {}; 00167 00168 /********************* 00169 ** Iterators 00170 **********************/ 00171 typedef Array<int,21>::const_iterator const_iterator; 00179 const_iterator begin(unsigned int index = 0) const; 00187 const_iterator end(unsigned int index = 0) const; 00188 00189 /********************* 00190 ** Streaming 00191 **********************/ 00192 template <typename OutputStream> 00193 friend OutputStream& operator<<(OutputStream &ostream, const PascalsTriangle<5> &triangle); 00194 00195 private: 00196 Array<int,21> coefficients; 00197 }; 00198 00199 /***************************************************************************** 00200 ** Implementation [Pascals Triangle] 00201 *****************************************************************************/ 00207 template <int N> 00208 PascalsTriangle<N>::PascalsTriangle() { 00209 int counter = 0; 00210 for (int i = N+1; i > 0; --i ) { 00211 for (int j = 0; j < i; ++j ) { 00212 if ( ( i == N+1 ) || ( j == 0 ) ) { 00213 coefficients[counter] = 1; 00214 } else { 00215 coefficients[counter] = coefficients[counter-1] + coefficients[counter-(i+1)]; 00216 } 00217 ++counter; 00218 } 00219 } 00220 } 00221 00229 template <int N> 00230 typename PascalsTriangle<N>::const_iterator PascalsTriangle<N>::begin(unsigned int index) const { 00231 int coeff_index = 0; 00232 for (unsigned int i = 0; i < index; ++i ) { 00233 coeff_index += N+1-i; 00234 } 00235 return const_iterator( &coefficients[coeff_index] ); 00236 } 00244 template <int N> 00245 typename PascalsTriangle<N>::const_iterator PascalsTriangle<N>::end(unsigned int index) const { 00246 int coeff_index = 0; 00247 for (unsigned int i = 0; i <= index; ++i ) { 00248 coeff_index += N+1-i; 00249 } 00250 coeff_index -= 1; // dont want to call beyond the array limit. 00251 return const_iterator( (&coefficients[coeff_index])+1); 00252 } 00253 00254 /***************************************************************************** 00255 ** Streaming 00256 *****************************************************************************/ 00257 00270 template <typename OutputStream, int PowerN> 00271 OutputStream& operator << ( OutputStream &ostream, const PascalsTriangle<PowerN> &triangle) 00272 { 00273 Format<int> format(2+PowerN/5,CentreAlign); // Rough hack to get a good auto-sizing working. Might blow up for large N. 00274 int counter = 0; 00275 for (int i = PowerN+1; i > 0; --i ) { 00276 for (int j = 0; j < i; ++j ) { 00277 ostream << format(triangle.coefficients[counter]) << " "; 00278 ++counter; 00279 } 00280 ostream << "\n"; 00281 } 00282 ostream.flush(); 00283 00284 return ostream; 00285 } 00286 00296 template <typename OutputStream> 00297 OutputStream& operator << ( OutputStream &ostream, const PascalsTriangle<3> &triangle) 00298 { 00299 Format<int> format(2,CentreAlign); 00300 int counter = 0; 00301 for (int i = 4; i > 0; --i ) { 00302 for (int j = 0; j < i; ++j ) { 00303 ostream << format(triangle.coefficients[counter]) << " "; 00304 ++counter; 00305 } 00306 ostream << "\n"; 00307 } 00308 ostream.flush(); 00309 00310 return ostream; 00311 } 00312 00322 template <typename OutputStream> 00323 OutputStream& operator << ( OutputStream &ostream, const PascalsTriangle<5> &triangle) 00324 { 00325 Format<int> format(3,CentreAlign); 00326 int counter = 0; 00327 for (int i = 6; i > 0; --i ) { 00328 for (int j = 0; j < i; ++j ) { 00329 ostream << format(triangle.coefficients[counter]) << " "; 00330 ++counter; 00331 } 00332 ostream << "\n"; 00333 } 00334 ostream.flush(); 00335 00336 return ostream; 00337 } 00338 00339 } // namespace ecl 00340 00341 00342 00343 #endif /* ECL_GEOMETRY_PASCALS_HPP_ */