CLHEP VERSION Reference Documentation
   
CLHEP Home Page     CLHEP Documentation     CLHEP Bug Reports

Vector.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 // ---------------------------------------------------------------------------
00003 //
00004 #ifdef GNUPRAGMA
00005 #pragma implementation
00006 #endif
00007 
00008 #include <string.h>
00009 
00010 #include "CLHEP/Matrix/defs.h"
00011 #include "CLHEP/Random/Random.h"
00012 #include "CLHEP/Vector/ThreeVector.h"
00013 #include "CLHEP/Matrix/Vector.h"
00014 #include "CLHEP/Matrix/Matrix.h"
00015 
00016 #ifdef HEP_DEBUG_INLINE
00017 #include "CLHEP/Matrix/Vector.icc"
00018 #endif
00019 
00020 namespace CLHEP {
00021 
00022 // Simple operation for all elements
00023 
00024 #define SIMPLE_UOP(OPER)          \
00025    HepGenMatrix::mIter a=m.begin();            \
00026    HepGenMatrix::mIter e=m.begin()+num_size(); \
00027    for(;a<e; a++) (*a) OPER t;
00028 
00029 #define SIMPLE_BOP(OPER)          \
00030    mIter a=m.begin();            \
00031    mcIter b=m2.m.begin();               \
00032    mcIter e=m.begin()+num_size(); \
00033    for(;a<e; a++, b++) (*a) OPER (*b);
00034 
00035 #define SIMPLE_TOP(OPER)          \
00036    HepGenMatrix::mcIter a=m1.m.begin();            \
00037    HepGenMatrix::mcIter b=m2.m.begin();         \
00038    HepGenMatrix::mIter t=mret.m.begin();         \
00039    HepGenMatrix::mcIter e=m1.m.begin()+m1.num_size(); \
00040    for( ;a<e; a++, b++, t++) (*t) = (*a) OPER (*b);
00041 
00042 #define CHK_DIM_2(r1,r2,c1,c2,fun) \
00043    if (r1!=r2 || c1!=c2)  { \
00044      HepGenMatrix::error("Range error in Vector function " #fun "(1)."); \
00045    }
00046 
00047 #define CHK_DIM_1(c1,r2,fun) \
00048    if (c1!=r2) { \
00049      HepGenMatrix::error("Range error in Vector function " #fun "(2)."); \
00050    }
00051 
00052 // Constructors. (Default constructors are inlined and in .icc file)
00053 
00054 HepVector::HepVector(int p)
00055    : m(p), nrow(p)
00056 {
00057 }
00058 
00059 HepVector::HepVector(int p, int init)
00060    : m(p), nrow(p)
00061 {
00062    switch (init)
00063    {
00064    case 0:
00065       m.assign(p,0);
00066       break;
00067       
00068    case 1:
00069       {
00070          mIter e = m.begin() + nrow;
00071          for (mIter i=m.begin(); i<e; i++) *i = 1.0;
00072          break;
00073       }
00074       
00075    default:
00076       error("Vector: initialization must be either 0 or 1.");
00077    }
00078 }
00079 
00080 HepVector::HepVector(int p, HepRandom &r)
00081    : m(p), nrow(p)
00082 {
00083    HepGenMatrix::mIter a = m.begin();
00084    HepGenMatrix::mIter b = m.begin() + nrow;
00085    for(;a<b;a++) *a = r();
00086 }
00087 
00088 
00089 //
00090 // Destructor
00091 //
00092 HepVector::~HepVector() {
00093 }
00094 
00095 HepVector::HepVector(const HepVector &m1)
00096    : HepGenMatrix(m1), m(m1.nrow), nrow(m1.nrow)
00097 {
00098    m = m1.m;
00099 }
00100 
00101 //
00102 // Copy constructor from the class of other precision
00103 //
00104 
00105 
00106 HepVector::HepVector(const HepMatrix &m1)
00107    : m(m1.nrow), nrow(m1.nrow)
00108 {
00109    if (m1.num_col() != 1)
00110       error("Vector::Vector(Matrix) : Matrix is not Nx1");
00111    
00112    m = m1.m;
00113 }
00114 
00115 // trivial methods
00116 
00117 inline int HepVector::num_row() const {return nrow;} 
00118 inline int HepVector::num_size() const {return nrow;} 
00119 inline int HepVector::num_col() const { return 1; }
00120 
00121 // operator()
00122 
00123 #ifdef MATRIX_BOUND_CHECK
00124 inline double & HepVector::operator()(int row, int col)
00125 {
00126   if( col!=1 || row<1 || row>nrow)
00127      error("Range error in HepVector::operator(i,j)");
00128 #else
00129 inline double & HepVector::operator()(int row, int)
00130 {
00131 #endif
00132 
00133   return *(m.begin()+(row-1));
00134 }
00135 
00136 #ifdef MATRIX_BOUND_CHECK
00137 inline const double & HepVector::operator()(int row, int col) const 
00138 {
00139   if( col!=1 || row<1 || row>nrow)
00140      error("Range error in HepVector::operator(i,j)");
00141 #else
00142 inline const double & HepVector::operator()(int row, int) const 
00143 {
00144 #endif
00145 
00146   return *(m.begin()+(row-1));
00147 }
00148 
00149 // Sub matrix
00150 
00151 HepVector HepVector::sub(int min_row, int max_row) const
00152 #ifdef HEP_GNU_OPTIMIZED_RETURN
00153 return vret(max_row-min_row+1);
00154 {
00155 #else
00156 {
00157   HepVector vret(max_row-min_row+1);
00158 #endif
00159   if(max_row > num_row())
00160     error("HepVector::sub: Index out of range");
00161   HepGenMatrix::mIter a = vret.m.begin();
00162   HepGenMatrix::mcIter b = m.begin() + min_row - 1;
00163   HepGenMatrix::mIter e = vret.m.begin() + vret.num_row();
00164   for(;a<e;) *(a++) = *(b++);
00165   return vret;
00166 }
00167 
00168 HepVector HepVector::sub(int min_row, int max_row)
00169 {
00170   HepVector vret(max_row-min_row+1);
00171   if(max_row > num_row())
00172     error("HepVector::sub: Index out of range");
00173   HepGenMatrix::mIter a = vret.m.begin();
00174   HepGenMatrix::mIter b = m.begin() + min_row - 1;
00175   HepGenMatrix::mIter e = vret.m.begin() + vret.num_row();
00176   for(;a<e;) *(a++) = *(b++);
00177   return vret;
00178 }
00179 
00180 void HepVector::sub(int row,const HepVector &v1)
00181 {
00182   if(row <1 || row+v1.num_row()-1 > num_row())
00183     error("HepVector::sub: Index out of range");
00184   HepGenMatrix::mcIter a = v1.m.begin();
00185   HepGenMatrix::mIter b = m.begin() + row - 1;
00186   HepGenMatrix::mcIter e = v1.m.begin() + v1.num_row();
00187   for(;a<e;) *(b++) = *(a++);
00188 }
00189 
00190 //
00191 // Direct sum of two matricies
00192 //
00193 
00194 HepVector dsum(const HepVector &m1,
00195                                      const HepVector &m2)
00196 #ifdef HEP_GNU_OPTIMIZED_RETURN
00197   return mret(m1.num_row() + m2.num_row(), 0);
00198 {
00199 #else
00200 {
00201   HepVector mret(m1.num_row() + m2.num_row(),
00202                                        0);
00203 #endif
00204   mret.sub(1,m1);
00205   mret.sub(m1.num_row()+1,m2);
00206   return mret;
00207 }
00208 
00209 /* -----------------------------------------------------------------------
00210    This section contains support routines for matrix.h. This section contains
00211    The two argument functions +,-. They call the copy constructor and +=,-=.
00212    ----------------------------------------------------------------------- */
00213 HepVector HepVector::operator- () const 
00214 #ifdef HEP_GNU_OPTIMIZED_RETURN
00215       return m2(nrow);
00216 {
00217 #else
00218 {
00219    HepVector m2(nrow);
00220 #endif
00221    HepGenMatrix::mcIter a=m.begin();
00222    HepGenMatrix::mIter b=m2.m.begin();
00223    HepGenMatrix::mcIter e=m.begin()+num_size();
00224    for(;a<e; a++, b++) (*b) = -(*a);
00225    return m2;
00226 }
00227 
00228    
00229 
00230 HepVector operator+(const HepMatrix &m1,const HepVector &m2)
00231 #ifdef HEP_GNU_OPTIMIZED_RETURN
00232      return mret(m2);
00233 {
00234 #else
00235 {
00236   HepVector mret(m2);
00237 #endif
00238   CHK_DIM_2(m1.num_row(),m2.num_row(),m1.num_col(),1,+);
00239   mret += m1;
00240   return mret;
00241 }
00242 
00243 HepVector operator+(const HepVector &m1,const HepMatrix &m2)
00244 #ifdef HEP_GNU_OPTIMIZED_RETURN
00245      return mret(m1);
00246 {
00247 #else
00248 {
00249   HepVector mret(m1);
00250 #endif
00251   CHK_DIM_2(m1.num_row(),m2.num_row(),1,m2.num_col(),+);
00252   mret += m2;
00253   return mret;
00254 }
00255 
00256 HepVector operator+(const HepVector &m1,const HepVector &m2)
00257 #ifdef HEP_GNU_OPTIMIZED_RETURN
00258      return mret(m1.num_row());
00259 {
00260 #else
00261 {
00262   HepVector mret(m1.num_row());
00263 #endif
00264   CHK_DIM_1(m1.num_row(),m2.num_row(),+);
00265   SIMPLE_TOP(+)
00266   return mret;
00267 }
00268 
00269 //
00270 // operator -
00271 //
00272 
00273 HepVector operator-(const HepMatrix &m1,const HepVector &m2)
00274 #ifdef HEP_GNU_OPTIMIZED_RETURN
00275      return mret;
00276 {
00277 #else
00278 {
00279   HepVector mret;
00280 #endif
00281   CHK_DIM_2(m1.num_row(),m2.num_row(),m1.num_col(),1,-);
00282   mret = m1;
00283   mret -= m2;
00284   return mret;
00285 }
00286 
00287 HepVector operator-(const HepVector &m1,const HepMatrix &m2)
00288 #ifdef HEP_GNU_OPTIMIZED_RETURN
00289      return mret(m1);
00290 {
00291 #else
00292 {
00293   HepVector mret(m1);
00294 #endif
00295   CHK_DIM_2(m1.num_row(),m2.num_row(),1,m2.num_col(),-);
00296   mret -= m2;
00297   return mret;
00298 }
00299 
00300 HepVector operator-(const HepVector &m1,const HepVector &m2)
00301 #ifdef HEP_GNU_OPTIMIZED_RETURN
00302      return mret(m1.num_row());
00303 {
00304 #else
00305 {
00306   HepVector mret(m1.num_row());
00307 #endif
00308   CHK_DIM_1(m1.num_row(),m2.num_row(),-);
00309   SIMPLE_TOP(-)
00310   return mret;
00311 }
00312 
00313 /* -----------------------------------------------------------------------
00314    This section contains support routines for matrix.h. This file contains
00315    The two argument functions *,/. They call copy constructor and then /=,*=.
00316    ----------------------------------------------------------------------- */
00317 
00318 HepVector operator/(
00319 const HepVector &m1,double t)
00320 #ifdef HEP_GNU_OPTIMIZED_RETURN
00321      return mret(m1);
00322 {
00323 #else
00324 {
00325   HepVector mret(m1);
00326 #endif
00327   mret /= t;
00328   return mret;
00329 }
00330 
00331 HepVector operator*(const HepVector &m1,double t)
00332 #ifdef HEP_GNU_OPTIMIZED_RETURN
00333      return mret(m1);
00334 {
00335 #else
00336 {
00337   HepVector mret(m1);
00338 #endif
00339   mret *= t;
00340   return mret;
00341 }
00342 
00343 HepVector operator*(double t,const HepVector &m1)
00344 #ifdef HEP_GNU_OPTIMIZED_RETURN
00345      return mret(m1);
00346 {
00347 #else
00348 {
00349   HepVector mret(m1);
00350 #endif
00351   mret *= t;
00352   return mret;
00353 }
00354 
00355 HepVector operator*(const HepMatrix &m1,const HepVector &m2)
00356 #ifdef HEP_GNU_OPTIMIZED_RETURN
00357      return mret(m1.num_row());
00358 {
00359 #else
00360 {
00361   HepVector mret(m1.num_row());
00362 #endif
00363   CHK_DIM_1(m1.num_col(),m2.num_row(),*);
00364   HepGenMatrix::mcIter m1p,m2p,vp;
00365   HepGenMatrix::mIter m3p;
00366   double temp;
00367   m3p=mret.m.begin();
00368   for(m1p=m1.m.begin();m1p<m1.m.begin()+m1.num_row()*m1.num_col();m1p=m2p)
00369     {
00370       temp=0;
00371       vp=m2.m.begin();
00372       m2p=m1p;
00373       while(m2p<m1p+m1.num_col())
00374         temp+=(*(m2p++))*(*(vp++));
00375       *(m3p++)=temp;
00376     }
00377   return mret;
00378 }
00379 
00380 HepMatrix operator*(const HepVector &m1,const HepMatrix &m2)
00381 #ifdef HEP_GNU_OPTIMIZED_RETURN
00382      return mret(m1.num_row(),m2.num_col());
00383 {
00384 #else
00385 {
00386   HepMatrix mret(m1.num_row(),m2.num_col());
00387 #endif
00388   CHK_DIM_1(1,m2.num_row(),*);
00389   HepGenMatrix::mcIter m1p;
00390   HepMatrix::mcIter m2p;
00391   HepMatrix::mIter mrp=mret.m.begin();
00392   for(m1p=m1.m.begin();m1p<m1.m.begin()+m1.num_row();m1p++)
00393     for(m2p=m2.m.begin();m2p<m2.m.begin()+m2.num_col();m2p++)
00394       *(mrp++)=*m1p*(*m2p);
00395   return mret;
00396 }
00397 
00398 /* -----------------------------------------------------------------------
00399    This section contains the assignment and inplace operators =,+=,-=,*=,/=.
00400    ----------------------------------------------------------------------- */
00401 
00402 HepMatrix & HepMatrix::operator+=(const HepVector &m2)
00403 {
00404   CHK_DIM_2(num_row(),m2.num_row(),num_col(),1,+=);
00405   SIMPLE_BOP(+=)
00406   return (*this);
00407 }
00408 
00409 HepVector & HepVector::operator+=(const HepMatrix &m2)
00410 {
00411   CHK_DIM_2(num_row(),m2.num_row(),1,m2.num_col(),+=);
00412   SIMPLE_BOP(+=)
00413   return (*this);
00414 }
00415 
00416 HepVector & HepVector::operator+=(const HepVector &m2)
00417 {
00418   CHK_DIM_1(num_row(),m2.num_row(),+=);
00419   SIMPLE_BOP(+=)
00420   return (*this);
00421 }
00422 
00423 HepMatrix &  HepMatrix::operator-=(const HepVector &m2)
00424 {
00425   CHK_DIM_2(num_row(),m2.num_row(),num_col(),1,-=);
00426   SIMPLE_BOP(-=)
00427   return (*this);
00428 }
00429 
00430 HepVector & HepVector::operator-=(const HepMatrix &m2)
00431 {
00432   CHK_DIM_2(num_row(),m2.num_row(),1,m2.num_col(),-=);
00433   SIMPLE_BOP(-=)
00434   return (*this);
00435 }
00436 
00437 HepVector & HepVector::operator-=(const HepVector &m2)
00438 {
00439   CHK_DIM_1(num_row(),m2.num_row(),-=);
00440   SIMPLE_BOP(-=)
00441   return (*this);
00442 }
00443 
00444 HepVector & HepVector::operator/=(double t)
00445 {
00446   SIMPLE_UOP(/=)
00447   return (*this);
00448 }
00449 
00450 HepVector & HepVector::operator*=(double t)
00451 {
00452   SIMPLE_UOP(*=)
00453   return (*this);
00454 }
00455 
00456 HepMatrix & HepMatrix::operator=(const HepVector &m1)
00457 {
00458    if(m1.nrow != size_)
00459    {
00460       size_ = m1.nrow;
00461       m.resize(size_);
00462    }
00463    nrow = m1.nrow;
00464    ncol = 1;
00465    m = m1.m;
00466    return (*this);
00467 }
00468 
00469 HepVector & HepVector::operator=(const HepVector &m1)
00470 {
00471    if(m1.nrow != nrow)
00472    {
00473       nrow = m1.nrow;
00474       m.resize(nrow);
00475    }
00476    m = m1.m;
00477    return (*this);
00478 }
00479 
00480 HepVector & HepVector::operator=(const HepMatrix &m1)
00481 {
00482    if (m1.num_col() != 1)
00483       error("Vector::operator=(Matrix) : Matrix is not Nx1");
00484    
00485    if(m1.nrow != nrow)
00486    {
00487       nrow = m1.nrow;
00488       m.resize(nrow);
00489    }
00490    m = m1.m;
00491    return (*this);
00492 }
00493 
00494 HepVector & HepVector::operator=(const Hep3Vector &v)
00495 {
00496    if(nrow != 3)
00497    {
00498       nrow = 3;
00499       m.resize(nrow);
00500    }
00501    m[0] = v.x();
00502    m[1] = v.y();
00503    m[2] = v.z();
00504    return (*this);
00505 }
00506 
00507 //
00508 // Copy constructor from the class of other precision
00509 //
00510 
00511 
00512 // Print the Matrix.
00513 
00514 std::ostream& operator<<(std::ostream &s, const HepVector &q)
00515 {
00516   s << std::endl;
00517 /* Fixed format needs 3 extra characters for field, while scientific needs 7 */
00518   int width;
00519   if(s.flags() & std::ios::fixed)
00520     width = s.precision()+3;
00521   else
00522     width = s.precision()+7;
00523   for(int irow = 1; irow<= q.num_row(); irow++)
00524     {
00525       s.width(width);
00526       s << q(irow) << std::endl;
00527     }
00528   return s;
00529 }
00530 
00531 HepMatrix HepVector::T() const
00532 #ifdef HEP_GNU_OPTIMIZED_RETURN
00533 return mret(1,num_row());
00534 {
00535 #else
00536 {
00537   HepMatrix mret(1,num_row());
00538 #endif
00539   mret.m = m;
00540   return mret;
00541 }
00542 
00543 double dot(const HepVector &v1,const HepVector &v2)
00544 {
00545   if(v1.num_row()!=v2.num_row())
00546      HepGenMatrix::error("v1 and v2 need to be the same size in dot(HepVector, HepVector)");
00547   double d= 0;
00548   HepGenMatrix::mcIter a = v1.m.begin();
00549   HepGenMatrix::mcIter b = v2.m.begin();
00550   HepGenMatrix::mcIter e = a + v1.num_size();
00551   for(;a<e;) d += (*(a++)) * (*(b++));
00552   return d;
00553 }
00554 
00555 HepVector HepVector::
00556 apply(double (*f)(double, int)) const
00557 #ifdef HEP_GNU_OPTIMIZED_RETURN
00558 return mret(num_row());
00559 {
00560 #else
00561 {
00562   HepVector mret(num_row());
00563 #endif
00564   HepGenMatrix::mcIter a = m.begin();
00565   HepGenMatrix::mIter b = mret.m.begin();
00566   for(int ir=1;ir<=num_row();ir++) {
00567     *(b++) = (*f)(*(a++), ir);
00568   }
00569   return mret;
00570 }
00571 
00572 void HepVector::invert(int &) {
00573    error("HepVector::invert: You cannot invert a Vector");
00574 }
00575 
00576 HepVector solve(const HepMatrix &a, const HepVector &v)
00577 #ifdef HEP_GNU_OPTIMIZED_RETURN
00578      return vret(v);
00579 {
00580 #else
00581 {
00582   HepVector vret(v);
00583 #endif
00584   static int max_array = 20;
00585   static int *ir = new int [max_array+1];
00586 
00587   if(a.ncol != a.nrow)
00588      HepGenMatrix::error("Matrix::solve Matrix is not NxN");
00589   if(a.ncol != v.nrow)
00590      HepGenMatrix::error("Matrix::solve Vector has wrong number of rows");
00591 
00592   int n = a.ncol;
00593   if (n > max_array) {
00594     delete [] ir;
00595     max_array = n;
00596     ir = new int [max_array+1];
00597   }
00598   double det;
00599   HepMatrix mt(a);
00600   int i = mt.dfact_matrix(det, ir);
00601   if (i!=0) {
00602     for (i=1;i<=n;i++) vret(i) = 0;
00603     return vret;
00604   }
00605   double s21, s22;
00606   int nxch = ir[n];
00607   if (nxch!=0) {
00608     for (int mm=1;mm<=nxch;mm++) {
00609       int ij = ir[mm];
00610       i = ij >> 12;
00611       int j = ij%4096;
00612       double te = vret(i);
00613       vret(i) = vret(j);
00614       vret(j) = te;
00615     }
00616   }
00617   vret(1) = mt(1,1) * vret(1);
00618   if (n!=1) {
00619     for (i=2;i<=n;i++) {
00620       s21 = -vret(i);
00621       for (int j=1;j<i;j++) {
00622         s21 += mt(i,j) * vret(j); 
00623       }
00624       vret(i) = -mt(i,i)*s21;
00625     }
00626     for (i=1;i<n;i++) {
00627       int nmi = n-i;
00628       s22 = -vret(nmi);
00629       for (int j=1;j<=i;j++) {
00630         s22 += mt(nmi,n-j+1) * vret(n-j+1);
00631       }
00632       vret(nmi) = -s22;
00633     }
00634   }
00635   return vret;
00636 }
00637 
00638 }  // namespace CLHEP

Generated on 15 Nov 2012 for CLHEP by  doxygen 1.4.7