mcpele
1.0.0
The Monte Carlo Python Energy Landscape Explorer
|
00001 #ifndef _pele_vecn_h_ 00002 #define _pele_vecn_h_ 00003 00004 #include <cmath> 00005 #include <stdlib.h> 00006 #include <vector> 00007 #include <iostream> 00008 #include <pele/array.h> 00009 #include <string> 00010 #include <sstream> 00011 00012 namespace pele{ 00013 00014 template<size_t N> 00015 class VecN { 00016 typedef double dtype; 00017 dtype m_data[N]; 00018 00019 public: 00020 00024 VecN(){} 00025 00029 VecN(dtype const & d) { assign(d); } 00030 00034 VecN(pele::Array<dtype> const & x) 00035 { 00036 if (x.size() != N) { 00037 throw std::runtime_error("VecN constructor: array must have the same size as vector"); 00038 } 00039 for (size_t i = 0; i < N; ++i) { 00040 m_data[i] = x[i]; 00041 } 00042 } 00043 00044 size_t size() const { return N; } 00045 00049 inline dtype * data() { return m_data; } 00050 inline dtype const * data() const { return m_data; } 00051 00055 typedef dtype * iterator; 00056 typedef dtype const * const_iterator; 00057 inline iterator begin() { return data(); } 00058 inline iterator end() { return data() + size(); } 00059 inline const_iterator begin() const { return data(); } 00060 inline const_iterator end() const { return data() + size(); } 00061 00065 inline dtype & operator[](const size_t i) { return m_data[i]; } 00066 inline dtype const & operator[](const size_t i) const { return m_data[i]; } 00067 00071 void assign(dtype const & d) 00072 { 00073 for (size_t i=0; i<N; ++i){ 00074 m_data[i] = d; 00075 } 00076 } 00077 00081 VecN<N> & operator=(pele::Array<double> const & rhs) { 00082 if (rhs.size() != N) { 00083 throw std::runtime_error("operator=: array must have the same size"); 00084 } 00085 for (size_t i = 0; i < N; ++i) { 00086 m_data[i] = rhs[i]; 00087 } 00088 return *this; 00089 } 00090 00091 00092 /* 00093 * Compound Assignment Operators += -= *= 00094 */ 00095 VecN<N> &operator+=(const VecN<N> & rhs) { 00096 for (size_t i = 0; i < N; ++i) { 00097 m_data[i] += rhs[i]; 00098 } 00099 return *this; 00100 } 00101 00102 VecN<N> &operator+=(const dtype &rhs) { 00103 for (size_t i = 0; i < N; ++i) { 00104 m_data[i] += rhs; 00105 } 00106 return *this; 00107 } 00108 00109 VecN<N> &operator-=(const VecN<N> & rhs){ 00110 for (size_t i = 0; i < N; ++i) { 00111 m_data[i] -= rhs[i]; 00112 } 00113 return *this; 00114 } 00115 00116 VecN<N> &operator-=(const dtype &rhs) { 00117 for (size_t i = 0; i < N; ++i) { 00118 m_data[i] -= rhs; 00119 } 00120 return *this; 00121 } 00122 00123 VecN<N> &operator*=(const VecN<N> & rhs){ 00124 for (size_t i = 0; i < N; ++i) { 00125 m_data[i] *= rhs[i]; 00126 } 00127 return *this; 00128 } 00129 00130 VecN<N> &operator*=(const dtype &rhs) { 00131 for (size_t i = 0; i < N; ++i) { 00132 m_data[i] *= rhs; 00133 } 00134 return *this; 00135 } 00136 00137 00138 VecN<N> &operator/=(const VecN<N> & rhs){ 00139 for (size_t i = 0; i < N; ++i) { 00140 m_data[i] /= rhs[i]; 00141 } 00142 return *this; 00143 } 00144 00145 VecN<N> &operator/=(const dtype &rhs) { 00146 for (size_t i = 0; i < N; ++i) { 00147 m_data[i] /= rhs; 00148 } 00149 return *this; 00150 } 00151 00152 VecN<N> operator-(VecN<N> const & rhs) const { 00153 VecN<3> v; 00154 for (size_t i = 0; i < N; ++i) { 00155 v[i] = m_data[i] - rhs[i]; 00156 } 00157 return v; 00158 } 00159 00160 00164 dtype sum() const { 00165 dtype sum_array = 0; 00166 for (size_t i = 0; i<N; ++i){ 00167 sum_array += m_data[i]; 00168 } 00169 return sum_array; 00170 } 00171 00175 dtype prod() const { 00176 dtype p = 1; 00177 for (size_t i = 0; i<N; ++i){ 00178 p *= m_data[i]; 00179 } 00180 return p; 00181 } 00182 00183 }; // close VecN 00184 00185 template<size_t N, size_t M> 00186 class MatrixNM { 00187 typedef double dtype; 00188 static size_t const m_size = N * M; 00189 dtype m_data[m_size]; 00190 00191 public: 00192 00196 MatrixNM() {} 00197 00201 MatrixNM(dtype const & d) { assign(d); } 00202 00206 MatrixNM(pele::Array<dtype> const & x) 00207 { 00208 if (x.size() != m_size) { 00209 std::stringstream ss; 00210 ss << "MatrixNM constructor: array (size " << x.size() << ") must have the same size as matrix " << m_size; 00211 throw std::runtime_error( 00212 ss.str() 00213 ); 00214 } 00215 for (size_t i = 0; i < m_size; ++i) { 00216 m_data[i] = x[i]; 00217 } 00218 } 00219 00220 size_t size() const { return m_size; } 00221 00225 inline dtype * data() { return m_data; } 00226 inline dtype const * data() const { return m_data; } 00227 00231 typedef dtype * iterator; 00232 typedef dtype const * const_iterator; 00233 inline iterator begin() { return data(); } 00234 inline iterator end() { return data() + size(); } 00235 inline const_iterator begin() const { return data(); } 00236 inline const_iterator end() const { return data() + size(); } 00237 00241 void assign(dtype const & d) 00242 { 00243 for (size_t i=0; i<m_size; ++i){ 00244 m_data[i] = d; 00245 } 00246 } 00247 00251 inline dtype const & operator()(size_t i, size_t j) const 00252 { 00253 return m_data[i * M + j]; 00254 } 00255 inline dtype & operator()(size_t i, size_t j) 00256 { 00257 return m_data[i * M + j]; 00258 } 00259 00260 inline std::pair<size_t, size_t> shape() const 00261 { 00262 return std::pair<size_t, size_t>(N, M); 00263 } 00264 00265 MatrixNM<N, M> &operator*=(dtype const & rhs) { 00266 for (size_t i = 0; i < m_size; ++i) { 00267 m_data[i] *= rhs; 00268 } 00269 return *this; 00270 } 00271 00272 double trace() 00273 { 00274 double t = 0; 00275 for (size_t i = 0; i<N; ++i){ 00276 t += (*this)(i,i); 00277 } 00278 return t; 00279 } 00280 00281 MatrixNM<N,M> operator-(MatrixNM<N,M> const & rhs) const { 00282 MatrixNM<N,M> v; 00283 for (size_t i = 0; i < m_size; ++i) { 00284 v.m_data[i] = m_data[i] - rhs.m_data[i]; 00285 } 00286 return v; 00287 } 00288 00289 00290 }; // close MatrixNM 00291 00295 template<size_t N> 00296 inline double dot(VecN<N> const &v1, VecN<N> const &v2) 00297 { 00298 double dot = 0.; 00299 for (size_t i=0; i<N; ++i) { 00300 dot += v1[i] * v2[i]; 00301 } 00302 return dot; 00303 } 00304 00308 template<size_t N> 00309 inline double norm(VecN<N> const &v) 00310 { 00311 return sqrt(dot(v, v)); 00312 } 00313 00314 00321 template<size_t N, size_t L, size_t M> 00322 MatrixNM<N,M> dot(MatrixNM<N,L> const & A, MatrixNM<L, M> const & B) 00323 { 00324 MatrixNM<N,M> C(0); 00325 for (size_t i = 0; i<N; ++i){ 00326 for (size_t j = 0; j<M; ++j){ 00327 double val = 0; 00328 for (size_t k = 0; k<L; ++k){ 00329 val += A(i,k) * B(k,j); 00330 } 00331 C(i,j) = val; 00332 } 00333 } 00334 return C; 00335 } 00336 00340 template<size_t N, size_t M> 00341 pele::VecN<N> dot(MatrixNM<N,M> const & A, pele::VecN<M> const & v) 00342 { 00343 pele::VecN<N> C(0); 00344 for (size_t i = 0; i<N; ++i){ 00345 double val = 0; 00346 for (size_t k = 0; k<M; ++k){ 00347 val += A(i,k) * v[k]; 00348 } 00349 C[i] = val; 00350 } 00351 return C; 00352 } 00353 00354 template<size_t N, size_t M> 00355 pele::MatrixNM<M,N> transpose(MatrixNM<N,M> const & A) 00356 { 00357 pele::MatrixNM<M,N> mat; 00358 for (size_t i = 0; i<N; ++i){ 00359 for (size_t k = 0; k<M; ++k){ 00360 mat(k,i) = A(i,k); 00361 } 00362 } 00363 return mat; 00364 } 00365 00366 template<size_t N> 00367 pele::MatrixNM<N,N> identity() 00368 { 00369 pele::MatrixNM<N,N> A(0.); 00370 for (size_t i = 0; i<N; ++i) { 00371 A(i,i) = 1.; 00372 } 00373 return A; 00374 } 00375 00376 // for matrix printing 00377 template<size_t N, size_t M> 00378 inline std::ostream &operator<<(std::ostream &out, const MatrixNM<N,M> &a) { 00379 out << "[ "; 00380 for(size_t n=0; n<N;++n) { 00381 for(size_t m=0; m<M;++m) { 00382 if(m>0) out << ", "; 00383 out << a(n,m); 00384 } 00385 if (n < N-1) out << ",\n "; 00386 } 00387 out << " ]"; 00388 return out; 00389 } 00390 00391 // for vector printing 00392 template<size_t N> 00393 inline std::ostream &operator<<(std::ostream &out, const VecN<N> &a) { 00394 out << "[ "; 00395 for(size_t i=0; i < a.size();++i) { 00396 if(i>0) out << ", "; 00397 out << a[i]; 00398 } 00399 out << " ]"; 00400 return out; 00401 } 00402 00403 00404 } // close namespace pele 00405 #endif