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
,
O2scl Sourceforge Project Page