vec_arith.h

Go to the documentation of this file.
00001 /*
00002   -------------------------------------------------------------------
00003   
00004   Copyright (C) 2006, 2007, Andrew W. Steiner
00005   
00006   This file is part of O2scl.
00007   
00008   O2scl is free software; you can redistribute it and/or modify
00009   it under the terms of the GNU General Public License as published by
00010   the Free Software Foundation; either version 3 of the License, or
00011   (at your option) any later version.
00012   
00013   O2scl is distributed in the hope that it will be useful,
00014   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016   GNU General Public License for more details.
00017   
00018   You should have received a copy of the GNU General Public License
00019   along with O2scl. If not, see <http://www.gnu.org/licenses/>.
00020 
00021   -------------------------------------------------------------------
00022 */
00023 
00024 #ifndef O2SCL_VEC_ARITH_H
00025 #define O2SCL_VEC_ARITH_H
00026 
00027 /** \file vec_arith.h
00028     \brief Vector and matrix arithmetic
00029 
00030     \todo Properly document the operators defined as macros
00031 
00032     \future Define operators for complex vector * real matrix
00033     \future These should be replaced by the BLAS routines where possible
00034 */
00035 
00036 #include <iostream>
00037 #include <complex>
00038 #include <o2scl/cx_arith.h>
00039 #include <o2scl/ovector_tlate.h>
00040 #include <o2scl/omatrix_tlate.h>
00041 #include <o2scl/uvector_tlate.h>
00042 #include <o2scl/umatrix_tlate.h>
00043 #include <o2scl/ovector_cx_tlate.h>
00044 #include <o2scl/omatrix_cx_tlate.h>
00045 #include <o2scl/uvector_cx_tlate.h>
00046 #include <o2scl/umatrix_cx_tlate.h>
00047 
00048 namespace o2scl_arith {
00049   
00050   /** \brief Naive vector copy
00051    */
00052   template<class vec_t, class vec2_t> 
00053     void vector_copy(size_t N, vec_t &v, vec2_t &v2) {
00054     for(size_t i=0;i<N;i++) v2[i]=v[i];
00055   }
00056   
00057   /** \brief Naive matrix copy
00058    */
00059   template<class mat_t, class mat2_t> 
00060     void matrix_copy(size_t M, size_t N, mat_t &m, mat2_t &m2) {
00061     for(size_t i=0;i<M;i++) {
00062       for(size_t j=0;j<N;j++) {
00063         m2[i][j]=m[i][j];
00064       }
00065     }
00066   }
00067 
00068   /** \brief Naive complex vector copy
00069    */
00070   template<class vec_t, class vec2_t> 
00071     void vector_cx_copy(size_t N, vec_t &v, vec2_t &v2) {
00072     for(size_t i=0;i<N;i++) {
00073       v2[i].dat[0]=v[i].dat[0];
00074       v2[i].dat[1]=v[i].dat[1];
00075     }
00076   }
00077   
00078   /** \brief Naive complex matrix copy
00079    */
00080   template<class mat_t, class mat2_t> 
00081     void matrix_cx_copy(size_t M, size_t N, mat_t &m, mat2_t &m2) {
00082     for(size_t i=0;i<M;i++) {
00083       for(size_t j=0;j<N;j++) {
00084         m2[i][j].dat[0]=m[i][j].dat[0];
00085         m2[i][j].dat[1]=m[i][j].dat[1];
00086       }
00087     }
00088   }
00089 
00090   /// The header macro for vector-vector addition
00091 #define O2SCL_OP_VEC_VEC_ADD(vec1,vec2,vec3) vec1 operator+     \
00092     (const vec2 &x, const vec3 &y);
00093   
00094   O2SCL_OP_VEC_VEC_ADD(o2scl::ovector,o2scl::ovector_view,o2scl::ovector_view)
00095     O2SCL_OP_VEC_VEC_ADD(o2scl::ovector,o2scl::ovector_view,o2scl::uvector_view)
00096     O2SCL_OP_VEC_VEC_ADD(o2scl::ovector,o2scl::uvector_view,o2scl::ovector_view)
00097     O2SCL_OP_VEC_VEC_ADD(o2scl::uvector,o2scl::uvector_view,o2scl::uvector_view)
00098     O2SCL_OP_VEC_VEC_ADD(o2scl::ovector_cx,o2scl::ovector_cx_view,
00099                        o2scl::ovector_cx_view)
00100     O2SCL_OP_VEC_VEC_ADD(o2scl::ovector_cx,o2scl::ovector_cx_view,
00101                        o2scl::uvector_cx_view)
00102     O2SCL_OP_VEC_VEC_ADD(o2scl::ovector_cx,o2scl::uvector_cx_view,
00103                        o2scl::ovector_cx_view)
00104     O2SCL_OP_VEC_VEC_ADD(o2scl::uvector_cx,o2scl::uvector_cx_view,
00105                        o2scl::uvector_cx_view)
00106     
00107 #ifdef O2SCL_NEVER_DEFINED
00108     }
00109 {
00110 #endif
00111   
00112   /// The header macro for vector-vector subtraction
00113 #define O2SCL_OP_VEC_VEC_SUB(vec1,vec2,vec3) vec1 operator-     \
00114     (const vec2 &x, const vec3 &y);
00115   
00116   O2SCL_OP_VEC_VEC_SUB(o2scl::ovector,o2scl::ovector_view,o2scl::ovector_view)
00117     O2SCL_OP_VEC_VEC_SUB(o2scl::ovector,o2scl::ovector_view,o2scl::uvector_view)
00118     O2SCL_OP_VEC_VEC_SUB(o2scl::ovector,o2scl::uvector_view,o2scl::ovector_view)
00119     O2SCL_OP_VEC_VEC_SUB(o2scl::uvector,o2scl::uvector_view,o2scl::uvector_view)
00120     O2SCL_OP_VEC_VEC_SUB(o2scl::ovector_cx,o2scl::ovector_cx_view,
00121                        o2scl::ovector_cx_view)
00122     O2SCL_OP_VEC_VEC_SUB(o2scl::ovector_cx,o2scl::ovector_cx_view,
00123                        o2scl::uvector_cx_view)
00124     O2SCL_OP_VEC_VEC_SUB(o2scl::ovector_cx,o2scl::uvector_cx_view,
00125                        o2scl::ovector_cx_view)
00126     O2SCL_OP_VEC_VEC_SUB(o2scl::uvector_cx,o2scl::uvector_cx_view,
00127                        o2scl::uvector_cx_view)
00128       
00129 #ifdef O2SCL_NEVER_DEFINED
00130     }
00131 {
00132 #endif
00133 
00134   /// The header macro for matrix * vector
00135 #define O2SCL_OP_MAT_VEC_MULT(vec1,vec2,mat) vec1 operator*     \
00136     (const mat &m, const vec2 &x);
00137   
00138   O2SCL_OP_MAT_VEC_MULT(o2scl::ovector,o2scl::ovector_view,o2scl::omatrix_view)
00139     O2SCL_OP_MAT_VEC_MULT(o2scl::ovector,o2scl::ovector_view,o2scl::umatrix_view)
00140     O2SCL_OP_MAT_VEC_MULT(o2scl::ovector,o2scl::uvector_view,o2scl::omatrix_view)
00141     O2SCL_OP_MAT_VEC_MULT(o2scl::uvector,o2scl::uvector_view,o2scl::umatrix_view)
00142     
00143 #ifdef O2SCL_NEVER_DEFINED
00144     }
00145 {
00146 #endif
00147 
00148   /// The header macro for complex matrix * complex vector
00149 #define O2SCL_OP_CMAT_CVEC_MULT(vec1,vec2,mat) vec1 operator*   \
00150     (const mat &m, const vec2 &x);
00151   
00152   O2SCL_OP_CMAT_CVEC_MULT(o2scl::ovector_cx,o2scl::ovector_cx_view,
00153                         o2scl::omatrix_cx_view)
00154     O2SCL_OP_CMAT_CVEC_MULT(o2scl::ovector_cx,o2scl::ovector_cx_view,
00155                           o2scl::umatrix_cx_view)
00156     O2SCL_OP_CMAT_CVEC_MULT(o2scl::ovector_cx,o2scl::uvector_cx_view,
00157                           o2scl::omatrix_cx_view)
00158     O2SCL_OP_CMAT_CVEC_MULT(o2scl::uvector_cx,o2scl::uvector_cx_view,
00159                           o2scl::umatrix_cx_view)
00160 
00161 #ifdef O2SCL_NEVER_DEFINED
00162     }
00163 {
00164 #endif
00165 
00166   /// The header macro for the operator form vector * matrix
00167 #define O2SCL_OP_VEC_MAT_MULT(vec1,vec2,mat) vec1 operator*     \
00168     (const vec2 &x, const mat &m);
00169   
00170   O2SCL_OP_VEC_MAT_MULT(o2scl::ovector,o2scl::ovector_view,o2scl::omatrix_view)
00171     O2SCL_OP_VEC_MAT_MULT(o2scl::ovector,o2scl::ovector_view,o2scl::umatrix_view)
00172     O2SCL_OP_VEC_MAT_MULT(o2scl::ovector,o2scl::uvector_view,o2scl::omatrix_view)
00173     O2SCL_OP_VEC_MAT_MULT(o2scl::uvector,o2scl::uvector_view,o2scl::umatrix_view)
00174 
00175 #ifdef O2SCL_NEVER_DEFINED
00176     }
00177 {
00178 #endif
00179 
00180   /// The header macro for the \c trans_mult form of vector * matrix
00181 #define O2SCL_OP_TRANS_MULT(vec1,vec2,mat) vec1 trans_mult      \
00182     (const vec2 &x, const mat &m);
00183   
00184   O2SCL_OP_TRANS_MULT(o2scl::ovector,o2scl::ovector_view,o2scl::omatrix_view)
00185     O2SCL_OP_TRANS_MULT(o2scl::ovector,o2scl::ovector_view,o2scl::umatrix_view)
00186     O2SCL_OP_TRANS_MULT(o2scl::ovector,o2scl::uvector_view,o2scl::omatrix_view)
00187     O2SCL_OP_TRANS_MULT(o2scl::uvector,o2scl::uvector_view,o2scl::umatrix_view)
00188             
00189 #ifdef O2SCL_NEVER_DEFINED
00190     }
00191 {
00192 #endif
00193 
00194   /// The header macro for a vector dot product
00195 #define O2SCL_OP_DOT_PROD(dtype,vec1,vec2) dtype dot    \
00196     (const vec1 &x, const vec2 &y);
00197             
00198   O2SCL_OP_DOT_PROD(double,o2scl::ovector_view,o2scl::ovector_view)
00199     O2SCL_OP_DOT_PROD(double,o2scl::ovector_view,o2scl::uvector_view)
00200     O2SCL_OP_DOT_PROD(double,o2scl::uvector_view,o2scl::ovector_view)
00201     O2SCL_OP_DOT_PROD(double,o2scl::uvector_view,o2scl::uvector_view)
00202 
00203 #ifdef O2SCL_NEVER_DEFINED
00204     }
00205 {
00206 #endif
00207 
00208   /// The header macro for a complex vector dot product
00209 #define O2SCL_OP_CX_DOT_PROD(dtype,vec1,vec2) dtype dot \
00210     (const vec1 &x, const vec2 &y);
00211 
00212   O2SCL_OP_CX_DOT_PROD(gsl_complex,o2scl::ovector_cx_view,
00213                      o2scl::ovector_cx_view)
00214     O2SCL_OP_CX_DOT_PROD(gsl_complex,o2scl::ovector_cx_view,
00215                        o2scl::uvector_cx_view)
00216     O2SCL_OP_CX_DOT_PROD(gsl_complex,o2scl::uvector_cx_view,
00217                        o2scl::ovector_cx_view)
00218     O2SCL_OP_CX_DOT_PROD(gsl_complex,o2scl::uvector_cx_view,
00219                        o2scl::uvector_cx_view)
00220 
00221 #ifdef O2SCL_NEVER_DEFINED
00222     }
00223 {
00224 #endif
00225 
00226   /// The header macro for vector=scalar*vector
00227 #define O2SCL_OP_SCA_VEC_MULT(dtype,vecv,vec) vec operator*     \
00228     (const dtype &x, const vecv &y);
00229   
00230   O2SCL_OP_SCA_VEC_MULT(double,o2scl::ovector_view,o2scl::ovector)
00231     O2SCL_OP_SCA_VEC_MULT(double,o2scl::uvector_view,o2scl::uvector)
00232     
00233 #ifdef O2SCL_NEVER_DEFINED
00234     }
00235 {
00236 #endif
00237 
00238   /// The header macro for vector=vector*scalar
00239 #define O2SCL_OP_VEC_SCA_MULT(dtype,vecv,vec) vec operator*     \
00240     (const vecv &x, const dtype &y);
00241   
00242   O2SCL_OP_VEC_SCA_MULT(double,o2scl::ovector_view,o2scl::ovector)
00243     O2SCL_OP_VEC_SCA_MULT(double,o2scl::uvector_view,o2scl::uvector)
00244 
00245 #ifdef O2SCL_NEVER_DEFINED
00246     }
00247 {
00248 #endif
00249               
00250   /** \brief The header macro for pairwise vector * vector (where either 
00251       vector can be real or complex)
00252   */
00253 #define O2SCL_OP_VEC_VEC_PRO(vec1,vec2,vec3) vec1 pair_prod     \
00254     (const vec2 &x, const vec3 &y);
00255   
00256   O2SCL_OP_VEC_VEC_PRO(o2scl::ovector,o2scl::ovector_view,o2scl::ovector_view)
00257     O2SCL_OP_VEC_VEC_PRO(o2scl::ovector,o2scl::ovector_view,o2scl::uvector_view)
00258     O2SCL_OP_VEC_VEC_PRO(o2scl::ovector,o2scl::uvector_view,o2scl::ovector_view)
00259     O2SCL_OP_VEC_VEC_PRO(o2scl::uvector,o2scl::uvector_view,o2scl::uvector_view)
00260     O2SCL_OP_VEC_VEC_PRO(o2scl::ovector_cx,o2scl::ovector_cx_view,o2scl::ovector_view)
00261     O2SCL_OP_VEC_VEC_PRO(o2scl::ovector_cx,o2scl::ovector_cx_view,o2scl::uvector_view)
00262     O2SCL_OP_VEC_VEC_PRO(o2scl::ovector_cx,o2scl::uvector_cx_view,o2scl::ovector_view)
00263     O2SCL_OP_VEC_VEC_PRO(o2scl::uvector_cx,o2scl::uvector_cx_view,o2scl::uvector_view)
00264     O2SCL_OP_VEC_VEC_PRO(o2scl::ovector_cx,o2scl::ovector_view,o2scl::ovector_cx_view)
00265     O2SCL_OP_VEC_VEC_PRO(o2scl::ovector_cx,o2scl::ovector_view,o2scl::uvector_cx_view)
00266     O2SCL_OP_VEC_VEC_PRO(o2scl::ovector_cx,o2scl::uvector_view,o2scl::ovector_cx_view)
00267     O2SCL_OP_VEC_VEC_PRO(o2scl::uvector_cx,o2scl::uvector_view,o2scl::uvector_cx_view)
00268     O2SCL_OP_VEC_VEC_PRO(o2scl::ovector_cx,o2scl::ovector_cx_view,
00269                        o2scl::ovector_cx_view)
00270     O2SCL_OP_VEC_VEC_PRO(o2scl::ovector_cx,o2scl::ovector_cx_view,
00271                        o2scl::uvector_cx_view)
00272     O2SCL_OP_VEC_VEC_PRO(o2scl::ovector_cx,o2scl::uvector_cx_view,
00273                        o2scl::ovector_cx_view)
00274     O2SCL_OP_VEC_VEC_PRO(o2scl::uvector_cx,o2scl::uvector_cx_view,
00275                        o2scl::uvector_cx_view)
00276     
00277   /// The source code macro for vector-vector addition
00278 #define O2SCL_OPSRC_VEC_VEC_ADD(vec1,vec2,vec3) vec1 o2scl_arith::operator+     \
00279       (const vec2 &x, const vec3 &y) {                                  \
00280       size_t m=x.size();                                                \
00281       if (y.size()<m) m=y.size();                                       \
00282       vec1 r(m);                                                        \
00283       for(size_t i=0;i<m;i++) {                                         \
00284         r[i]=x[i]+y[i];                                                 \
00285       }                                                                 \
00286       return r;                                                         \
00287     }
00288     
00289   /// The source code macro for vector-vector subtraction
00290 #define O2SCL_OPSRC_VEC_VEC_SUB(vec1,vec2,vec3) vec1 o2scl_arith::operator-     \
00291       (const vec2 &x, const vec3 &y) {                                  \
00292       size_t m=x.size();                                                \
00293       if (y.size()<m) m=y.size();                                       \
00294       vec1 r(m);                                                        \
00295       for(size_t i=0;i<m;i++) {                                         \
00296         r[i]=x[i]-y[i];                                                 \
00297       }                                                                 \
00298       return r;                                                         \
00299     }
00300 
00301   /// The source code macro for matrix * vector
00302 #define O2SCL_OPSRC_MAT_VEC_MULT(vec1,vec2,mat) vec1 o2scl_arith::operator*     \
00303       (const mat &m, const vec2 &x) {                                   \
00304       size_t nr=m.rows();                                               \
00305       size_t nc=m.cols();                                               \
00306       vec1 res(nr);                                                     \
00307       for(size_t i=0;i<nr;i++) {                                        \
00308         double r=0.0;                                                   \
00309         for(size_t j=0;j<nc;j++) {                                      \
00310           r+=m[i][j]*x[j];                                              \
00311         }                                                               \
00312         res[i]=r;                                                       \
00313       }                                                                 \
00314       return res;                                                       \
00315     } 
00316   
00317   /// The source code macro for complex matrix * complex vector
00318 #define O2SCL_OPSRC_CMAT_CVEC_MULT(vec1,vec2,mat) vec1 o2scl_arith::operator* \
00319       (const mat &m, const vec2 &x) {                                   \
00320       size_t nr=m.rows();                                               \
00321       size_t nc=m.cols();                                               \
00322       vec1 res(nr);                                                     \
00323       for(size_t i=0;i<nr;i++) {                                        \
00324         double re=0.0;                                                  \
00325         double im=0.0;                                                  \
00326         for(size_t j=0;j<nc;j++) {                                      \
00327           gsl_complex g=m[i][j]*x[j];                                   \
00328           re+=g.dat[0];                                                 \
00329           im+=g.dat[1];                                                 \
00330         }                                                               \
00331         res[i].dat[0]=re;                                               \
00332         res[i].dat[1]=im;                                               \
00333       }                                                                 \
00334       return res;                                                       \
00335     } 
00336   
00337   /// The source code macro for the operator form of vector * matrix
00338 #define O2SCL_OPSRC_VEC_MAT_MULT(vec1,vec2,mat) vec1 o2scl_arith::operator*     \
00339       (const vec2 &x, const mat &m) {                                   \
00340       size_t nr=m.rows();                                               \
00341       size_t nc=m.cols();                                               \
00342       vec1 res(nr);                                                     \
00343       for(size_t j=0;j<nc;j++) {                                        \
00344         double r=0.0;                                                   \
00345         for(size_t i=0;i<nr;i++) {                                      \
00346           r+=x[i]*m[i][j];                                              \
00347         }                                                               \
00348         res[j]=r;                                                       \
00349       }                                                                 \
00350       return res;                                                       \
00351     } 
00352   
00353   /// The source code macro for the \c trans_mult form of vector * matrix
00354 #define O2SCL_OPSRC_TRANS_MULT(vec1,vec2,mat) vec1 o2scl_arith::trans_mult      \
00355       (const vec2 &x, const mat &m) {                                   \
00356       size_t nr=m.rows();                                               \
00357       size_t nc=m.cols();                                               \
00358       vec1 res(nr);                                                     \
00359       for(size_t j=0;j<nc;j++) {                                        \
00360         double r=0.0;                                                   \
00361         for(size_t i=0;i<nr;i++) {                                      \
00362           r+=x[i]*m[i][j];                                              \
00363         }                                                               \
00364         res[j]=r;                                                       \
00365       }                                                                 \
00366       return res;                                                       \
00367     } 
00368   
00369   /// The source code macro for a vector dot product
00370 #define O2SCL_OPSRC_DOT_PROD(dtype,vec1,vec2) dtype o2scl_arith::dot    \
00371       (const vec1 &x, const vec2 &y) {                                  \
00372       size_t m=x.size();                                                \
00373       if (y.size()<m) m=y.size();                                       \
00374       dtype r=0;                                                        \
00375       for(size_t i=0;i<m;i++) {                                         \
00376         r+=x[i]*y[i];                                                   \
00377       }                                                                 \
00378       return r;                                                         \
00379     }
00380             
00381   /// The source code macro for a complex vector dot product
00382 #define O2SCL_OPSRC_CX_DOT_PROD(dtype,vec1,vec2) dtype o2scl_arith::dot \
00383       (const vec1 &x, const vec2 &y) {                                  \
00384       size_t m=x.size();                                                \
00385       if (y.size()<m) m=y.size();                                       \
00386       dtype r={{0.0,0.0}};                                              \
00387       for(size_t i=0;i<m;i++) {                                         \
00388         r+=x[i]*y[i];                                                   \
00389       }                                                                 \
00390       return r;                                                         \
00391     }
00392 
00393   /// The source code macro for vector=scalar*vector
00394 #define O2SCL_OPSRC_SCA_VEC_MULT(dtype,vecv,vec) vec o2scl_arith::operator*     \
00395       (const dtype &x, const vecv &y) {                                 \
00396       size_t m=y.size();                                                \
00397       vec r(m);                                                         \
00398       for(size_t i=0;i<m;i++) {                                         \
00399         r[i]=x*y[i];                                                    \
00400       }                                                                 \
00401       return r;                                                         \
00402     }
00403   
00404   /// The source code macro for vector=vector*scalar
00405 #define O2SCL_OPSRC_VEC_SCA_MULT(dtype,vecv,vec) vec o2scl_arith::operator*     \
00406       (const vecv &x, const dtype &y) {                                 \
00407       size_t m=x.size();                                                \
00408       vec r(m);                                                         \
00409       for(size_t i=0;i<m;i++) {                                         \
00410         r[i]=x[i]*y;                                                    \
00411       }                                                                 \
00412       return r;                                                         \
00413     }
00414   
00415   /** \brief The source code macro for pairwise vector * vector (where
00416       either vector can be real or complex)
00417   */
00418 #define O2SCL_OPSRC_VEC_VEC_PRO(vec1,vec2,vec3) vec1 o2scl_arith::pair_prod     \
00419       (const vec2 &x, const vec3 &y) {                                  \
00420       size_t m=x.size();                                                \
00421       if (y.size()<m) m=y.size();                                       \
00422       vec1 r(m);                                                        \
00423       for(size_t i=0;i<m;i++) {                                         \
00424         r[i]=x[i]*y[i];                                                 \
00425       }                                                                 \
00426       return r;                                                         \
00427     }
00428   
00429     }
00430 
00431 #endif

Documentation generated with Doxygen and provided under the GNU Free Documentation License. See License Information for details.

Project hosting provided by SourceForge.net Logo, O2scl Sourceforge Project Page