pele
Python energy landscape explorer
/home/js850/projects/pele/source/pele/vecn.h
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
 All Classes Namespaces Functions Variables Typedefs