HelperOps.h

Go to the documentation of this file.
00001 // @(#)root/smatrix:$Id: HelperOps.h 34742 2010-08-06 09:25:40Z moneta $
00002 // Authors: J. Palacios    2006  
00003 
00004 #ifndef ROOT_Math_HelperOps
00005 #define ROOT_Math_HelperOps 1
00006 
00007 // Include files
00008 
00009 /** @class HelperOps HelperOps.h Math/HelperOps.h
00010  *  
00011  *
00012  *  @author Juan PALACIOS
00013  *  @date   2006-01-11
00014  *
00015  *  Specialised helper classes for binary operators =, +=, -=
00016  *  between SMatrices and Expressions with arbitrary representations.
00017  *  Specialisations at the moment only for Symmetric LHS and Generic RHS
00018  *  and used to throw static assert.
00019  */
00020 #include "Math/StaticCheck.h"
00021 #include <algorithm>  // required by std::copy
00022 
00023 namespace ROOT { 
00024 
00025 namespace Math {
00026 
00027    template <class T, unsigned int D1, unsigned int D2, class R>
00028    class SMatrix;
00029 
00030    template <class A, class T, unsigned int D1, unsigned int D2, class R>
00031    class Expr;
00032 
00033    //=========================================================================
00034    /** 
00035        Structure to assign from an expression based to general matrix to general matrix
00036    */
00037    template <class T, 
00038              unsigned int D1, unsigned int D2, 
00039              class A, class R1, class R2>
00040 
00041    struct Assign
00042    {
00043       /** 
00044           Evaluate the expression from general to general matrices.
00045           If the matrix to assign the value is in use in the expression, 
00046           a temporary object is created to store the value (case A = B * A)
00047       */
00048       static void Evaluate(SMatrix<T,D1,D2,R1>& lhs,  const Expr<A,T,D1,D2,R2>& rhs) 
00049       {
00050          if (! rhs.IsInUse(lhs.begin() )  ) { 
00051             unsigned int l = 0; 
00052             for(unsigned int i=0; i<D1; ++i) 
00053                for(unsigned int j=0; j<D2; ++j) { 
00054                   lhs.fRep[l] = rhs(i,j);
00055                   l++;
00056                }
00057          }
00058          // lhs is in use in expression, need to create a temporary with the result
00059          else { 
00060             // std::cout << "create temp  for " << typeid(rhs).name() << std::endl;
00061             T tmp[D1*D2]; 
00062             unsigned int l = 0; 
00063             for(unsigned int i=0; i<D1; ++i) 
00064                for(unsigned int j=0; j<D2; ++j) { 
00065                   tmp[l] = rhs(i,j);
00066                   l++;
00067                }
00068             // copy now the temp object 
00069             for(unsigned int i=0; i<D1*D2; ++i) lhs.fRep[i] = tmp[i];
00070          }
00071 
00072       }
00073             
00074    };
00075 
00076    /** 
00077        Structure to assign from an expression based to symmetric matrix to symmetric matrix
00078    */
00079    template <class T, 
00080              unsigned int D1, unsigned int D2, 
00081              class A>
00082 
00083    struct Assign<T, D1, D2, A, MatRepSym<T,D1>, MatRepSym<T,D1> > 
00084    {
00085       /** 
00086           Evaluate the expression from  symmetric to symmetric matrices.
00087           If the matrix to assign the value is in use in the expression, 
00088           a temporary object is created to store the value (case A = B * A)
00089       */
00090       static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >& lhs,  
00091                            const Expr<A,T,D1,D2,MatRepSym<T,D1> >& rhs) 
00092       {
00093          if (! rhs.IsInUse(lhs.begin() ) ) { 
00094             unsigned int l = 0; 
00095             for(unsigned int i=0; i<D1; ++i)
00096                // storage of symmetric matrix is in lower block
00097                for(unsigned int j=0; j<=i; ++j) { 
00098                   lhs.fRep.Array()[l] = rhs(i,j);
00099                   l++;
00100                }
00101          }
00102          // create a temporary object to store result
00103          else { 
00104             T tmp[MatRepSym<T,D1>::kSize]; 
00105             unsigned int l = 0; 
00106             for(unsigned int i=0; i<D1; ++i) 
00107                for(unsigned int j=0; j<=i; ++j) { 
00108                   tmp[l] = rhs(i,j);
00109                   l++;
00110                }
00111             // copy now the temp object 
00112             for(unsigned int i=0; i<MatRepSym<T,D1>::kSize; ++i) lhs.fRep.Array()[i] = tmp[i];
00113          }
00114       }
00115    };
00116 
00117     
00118 
00119    /** 
00120        Dummy Structure which flags an error to avoid assigment from expression based on a 
00121        general matrix to a symmetric matrix
00122    */
00123    template <class T, unsigned int D1, unsigned int D2, class A>
00124    struct Assign<T, D1, D2, A, MatRepSym<T,D1>, MatRepStd<T,D1,D2> > 
00125    {
00126       static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >&,  
00127                            const Expr<A,T,D1,D2,MatRepStd<T,D1,D2> >&) 
00128       {
00129          STATIC_CHECK(0==1, Cannot_assign_general_to_symmetric_matrix);
00130       }
00131       
00132    }; // struct Assign
00133 
00134 
00135    /** 
00136        Force Expression evaluation from general to symmetric. 
00137        To be used when is known (like in similarity products) that the result 
00138        is symmetric
00139        Note this is function used in the simmilarity product: no check for temporary is 
00140        done since in that case is not needed
00141    */
00142    struct AssignSym
00143    {
00144       /// assign a symmetric matrix from an expression
00145       template <class T, 
00146                 unsigned int D,
00147                 class A, 
00148                 class R>
00149       static void Evaluate(SMatrix<T,D,D,MatRepSym<T,D> >& lhs,  const Expr<A,T,D,D,R>& rhs) 
00150       {
00151          //for(unsigned int i=0; i<D1*D2; ++i) lhs.fRep[i] = rhs.apply(i);
00152          unsigned int l = 0; 
00153          for(unsigned int i=0; i<D; ++i)
00154             // storage of symmetric matrix is in lower block
00155             for(unsigned int j=0; j<=i; ++j) { 
00156                lhs.fRep.Array()[l] = rhs(i,j);
00157                l++;
00158             }
00159       }
00160       /// assign the symmetric matric  from a general matrix  
00161       template <class T, 
00162                 unsigned int D,
00163                 class R>
00164       static void Evaluate(SMatrix<T,D,D,MatRepSym<T,D> >& lhs,  const SMatrix<T,D,D,R>& rhs) 
00165       {
00166          //for(unsigned int i=0; i<D1*D2; ++i) lhs.fRep[i] = rhs.apply(i);
00167          unsigned int l = 0; 
00168          for(unsigned int i=0; i<D; ++i)
00169             // storage of symmetric matrix is in lower block
00170             for(unsigned int j=0; j<=i; ++j) { 
00171                lhs.fRep.Array()[l] = rhs(i,j);
00172                l++;
00173             }
00174       }
00175 
00176 
00177    }; // struct AssignSym 
00178     
00179 
00180    //=========================================================================
00181    /** 
00182        Evaluate the expression performing a += operation
00183        Need to check whether creating a temporary object with the expression result
00184        (like in op:  A += A * B )
00185    */
00186    template <class T, unsigned int D1, unsigned int D2, class A,
00187              class R1, class R2>
00188    struct PlusEquals
00189    {
00190       static void Evaluate(SMatrix<T,D1,D2,R1>& lhs,  const Expr<A,T,D1,D2,R2>& rhs) 
00191       {
00192          if (! rhs.IsInUse(lhs.begin() )  ) { 
00193             unsigned int l = 0; 
00194             for(unsigned int i=0; i<D1; ++i) 
00195                for(unsigned int j=0; j<D2; ++j) { 
00196                   lhs.fRep[l] += rhs(i,j);
00197                   l++;
00198                }
00199          }
00200          else { 
00201             T tmp[D1*D2]; 
00202             unsigned int l = 0; 
00203             for(unsigned int i=0; i<D1; ++i) 
00204                for(unsigned int j=0; j<D2; ++j) { 
00205                   tmp[l] = rhs(i,j);
00206                   l++;
00207                }
00208             // += now using the temp object 
00209             for(unsigned int i=0; i<D1*D2; ++i) lhs.fRep[i] += tmp[i];
00210          }
00211       }
00212    };
00213 
00214    /** 
00215        Specialization for symmetric matrices
00216        Evaluate the expression performing a += operation for symmetric matrices
00217        Need to have a separate functions to avoid to modify two times the off-diagonal 
00218        elements (i.e applying two times the expression)
00219        Need to check whether creating a temporary object with the expression result
00220        (like in op:  A += A * B )
00221    */
00222    template <class T, 
00223              unsigned int D1, unsigned int D2, 
00224              class A>
00225    struct PlusEquals<T, D1, D2, A, MatRepSym<T,D1>, MatRepSym<T,D1> > 
00226    {
00227       static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >& lhs,  const Expr<A,T,D1,D2, MatRepSym<T,D1> >& rhs) 
00228       {
00229          if (! rhs.IsInUse(lhs.begin() )  ) { 
00230             unsigned int l = 0;  // l span storage of sym matrices
00231             for(unsigned int i=0; i<D1; ++i) 
00232                for(unsigned int j=0; j<=i; ++j) { 
00233                   lhs.fRep.Array()[l] += rhs(i,j);
00234                   l++;
00235                }
00236          }
00237          else { 
00238             T tmp[MatRepSym<T,D1>::kSize]; 
00239             unsigned int l = 0; 
00240             for(unsigned int i=0; i<D1; ++i) 
00241                for(unsigned int j=0; j<=i; ++j) { 
00242                   tmp[l] = rhs(i,j);
00243                   l++;
00244                }
00245             // += now using the temp object 
00246             for(unsigned int i=0; i<MatRepSym<T,D1>::kSize; ++i) lhs.fRep.Array()[i] += tmp[i];
00247          }
00248       }
00249    };
00250    /**
00251       Specialization for symmetrix += general : NOT Allowed operation 
00252     */    
00253    template <class T, unsigned int D1, unsigned int D2, class A>
00254    struct PlusEquals<T, D1, D2, A, MatRepSym<T,D1>, MatRepStd<T,D1,D2> > 
00255    {
00256       static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >&,  
00257                            const Expr<A,T,D1,D2,MatRepStd<T,D1,D2> >&) 
00258       {        
00259          STATIC_CHECK(0==1, Cannot_plusEqual_general_to_symmetric_matrix);
00260       }
00261    }; // struct PlusEquals
00262 
00263    //=========================================================================
00264 
00265    /** 
00266        Evaluate the expression performing a -= operation
00267        Need to check whether creating a temporary object with the expression result
00268        (like in op:  A -= A * B )
00269    */
00270    template <class T, unsigned int D1, unsigned int D2, class A,
00271              class R1, class R2>
00272    struct MinusEquals
00273    {
00274       static void Evaluate(SMatrix<T,D1,D2,R1>& lhs,  const Expr<A,T,D1,D2,R2>& rhs) 
00275       {
00276          if (! rhs.IsInUse(lhs.begin() )  ) { 
00277             unsigned int l = 0; 
00278             for(unsigned int i=0; i<D1; ++i) 
00279                for(unsigned int j=0; j<D2; ++j) { 
00280                   lhs.fRep[l] -= rhs(i,j);
00281                   l++;
00282                }
00283          }
00284          else { 
00285             T tmp[D1*D2]; 
00286             unsigned int l = 0; 
00287             for(unsigned int i=0; i<D1; ++i) 
00288                for(unsigned int j=0; j<D2; ++j) { 
00289                   tmp[l] = rhs(i,j);
00290                   l++;
00291                }
00292             // -= now using the temp object 
00293             for(unsigned int i=0; i<D1*D2; ++i) lhs.fRep[i] -= tmp[i];
00294          }
00295       }
00296    };
00297    /** 
00298        Specialization for symmetric matrices.
00299        Evaluate the expression performing a -= operation for symmetric matrices
00300        Need to have a separate functions to avoid to modify two times the off-diagonal 
00301        elements (i.e applying two times the expression)
00302        Need to check whether creating a temporary object with the expression result
00303        (like in op:  A -= A + B )
00304    */
00305    template <class T, 
00306              unsigned int D1, unsigned int D2, 
00307              class A>
00308    struct MinusEquals<T, D1, D2, A, MatRepSym<T,D1>, MatRepSym<T,D1> > 
00309    {
00310       static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >& lhs,  const Expr<A,T,D1,D2, MatRepSym<T,D1> >& rhs) 
00311       {
00312          if (! rhs.IsInUse(lhs.begin() )  ) { 
00313             unsigned int l = 0;  // l span storage of sym matrices
00314             for(unsigned int i=0; i<D1; ++i) 
00315                for(unsigned int j=0; j<=i; ++j) { 
00316                   lhs.fRep.Array()[l] -= rhs(i,j);
00317                   l++;
00318                }
00319          }
00320          else { 
00321             T tmp[MatRepSym<T,D1>::kSize]; 
00322             unsigned int l = 0; 
00323             for(unsigned int i=0; i<D1; ++i) 
00324                for(unsigned int j=0; j<=i; ++j) { 
00325                   tmp[l] = rhs(i,j);
00326                   l++;
00327                }
00328             // -= now using the temp object 
00329             for(unsigned int i=0; i<MatRepSym<T,D1>::kSize; ++i) lhs.fRep.Array()[i] -= tmp[i];
00330          }
00331       }
00332    };
00333 
00334    /**
00335       Specialization for symmetrix -= general : NOT Allowed operation 
00336     */
00337    template <class T, unsigned int D1, unsigned int D2, class A>
00338    struct MinusEquals<T, D1, D2, A, MatRepSym<T,D1>, MatRepStd<T,D1,D2> > 
00339    {
00340       static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >&,  
00341                            const Expr<A,T,D1,D2,MatRepStd<T,D1,D2> >&) 
00342       {        
00343          STATIC_CHECK(0==1, Cannot_minusEqual_general_to_symmetric_matrix);
00344       }
00345    }; // struct MinusEquals
00346 
00347 
00348    /** Structure to deal when a submatrix is placed in a matrix.  
00349        We have different cases according to the matrix representation
00350    */
00351    template <class T, unsigned int D1, unsigned int D2,   
00352              unsigned int D3, unsigned int D4, 
00353              class R1, class R2>
00354    struct PlaceMatrix
00355    {
00356       static void Evaluate(SMatrix<T,D1,D2,R1>& lhs,  const SMatrix<T,D3,D4,R2>& rhs, 
00357                            unsigned int row, unsigned int col) {
00358 
00359          assert(row+D3 <= D1 && col+D4 <= D2);
00360          const unsigned int offset = row*D2+col;
00361 
00362          for(unsigned int i=0; i<D3*D4; ++i) {
00363             lhs.fRep[offset+(i/D4)*D2+i%D4] = rhs.apply(i);
00364          }
00365 
00366       }
00367    }; // struct PlaceMatrix
00368 
00369    template <class T, unsigned int D1, unsigned int D2,   
00370              unsigned int D3, unsigned int D4, 
00371              class A, class R1, class R2>
00372    struct PlaceExpr { 
00373       static void Evaluate(SMatrix<T,D1,D2,R1>& lhs,  const Expr<A,T,D3,D4,R2>& rhs, 
00374                            unsigned int row, unsigned int col) { 
00375 
00376          assert(row+D3 <= D1 && col+D4 <= D2);
00377          const unsigned int offset = row*D2+col;
00378 
00379          for(unsigned int i=0; i<D3*D4; ++i) {
00380             lhs.fRep[offset+(i/D4)*D2+i%D4] = rhs.apply(i);
00381          }
00382       }
00383    };  // struct PlaceExpr 
00384 
00385    // specialization for general matrix in symmetric matrices
00386    template <class T, unsigned int D1, unsigned int D2, 
00387              unsigned int D3, unsigned int D4 >
00388    struct PlaceMatrix<T, D1, D2, D3, D4, MatRepSym<T,D1>, MatRepStd<T,D3,D4> > { 
00389       static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >& ,  
00390                            const SMatrix<T,D3,D4,MatRepStd<T,D3,D4> >& , 
00391                            unsigned int , unsigned int ) 
00392       {        
00393          STATIC_CHECK(0==1, Cannot_Place_Matrix_general_in_symmetric_matrix);
00394       }
00395    }; // struct PlaceMatrix
00396 
00397    // specialization for general expression in symmetric matrices
00398    template <class T, unsigned int D1, unsigned int D2, 
00399              unsigned int D3, unsigned int D4, class A >
00400    struct PlaceExpr<T, D1, D2, D3, D4, A, MatRepSym<T,D1>, MatRepStd<T,D3,D4> > { 
00401       static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >& ,  
00402                            const Expr<A,T,D3,D4,MatRepStd<T,D3,D4> >& , 
00403                            unsigned int , unsigned int ) 
00404       {        
00405          STATIC_CHECK(0==1, Cannot_Place_Matrix_general_in_symmetric_matrix);
00406       }
00407    }; // struct PlaceExpr
00408 
00409    // specialization for symmetric matrix in symmetric matrices
00410 
00411    template <class T, unsigned int D1, unsigned int D2, 
00412              unsigned int D3, unsigned int D4 >
00413    struct PlaceMatrix<T, D1, D2, D3, D4, MatRepSym<T,D1>, MatRepSym<T,D3> > { 
00414       static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >& lhs,  
00415                            const SMatrix<T,D3,D4,MatRepSym<T,D3> >& rhs, 
00416                            unsigned int row, unsigned int col ) 
00417       {        
00418          // can work only if placed on the diagonal
00419          assert(row == col); 
00420 
00421          for(unsigned int i=0; i<D3; ++i) {
00422             for(unsigned int j=0; j<=i; ++j) 
00423                lhs.fRep(row+i,col+j) = rhs(i,j);
00424          }        
00425       }
00426    }; // struct PlaceMatrix
00427 
00428    // specialization for symmetric expression in symmetric matrices
00429    template <class T, unsigned int D1, unsigned int D2, 
00430              unsigned int D3, unsigned int D4, class A >
00431    struct PlaceExpr<T, D1, D2, D3, D4, A, MatRepSym<T,D1>, MatRepSym<T,D3> > { 
00432       static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >& lhs,  
00433                            const Expr<A,T,D3,D4,MatRepSym<T,D3> >& rhs, 
00434                            unsigned int row, unsigned int col ) 
00435       {        
00436          // can work only if placed on the diagonal
00437          assert(row == col); 
00438 
00439          for(unsigned int i=0; i<D3; ++i) {
00440             for(unsigned int j=0; j<=i; ++j) 
00441                lhs.fRep(row+i,col+j) = rhs(i,j);
00442          }
00443       }
00444    }; // struct PlaceExpr
00445 
00446 
00447 
00448    /** Structure for getting sub matrices 
00449        We have different cases according to the matrix representations
00450    */
00451    template <class T, unsigned int D1, unsigned int D2,   
00452              unsigned int D3, unsigned int D4, 
00453              class R1, class R2>
00454    struct RetrieveMatrix
00455    {
00456       static void Evaluate(SMatrix<T,D1,D2,R1>& lhs,  const SMatrix<T,D3,D4,R2>& rhs, 
00457                            unsigned int row, unsigned int col) {
00458          STATIC_CHECK( D1 <= D3,Smatrix_nrows_too_small); 
00459          STATIC_CHECK( D2 <= D4,Smatrix_ncols_too_small); 
00460 
00461          assert(row + D1 <= D3);
00462          assert(col + D2 <= D4);
00463 
00464          for(unsigned int i=0; i<D1; ++i) { 
00465             for(unsigned int j=0; j<D2; ++j) 
00466                lhs(i,j) = rhs(i+row,j+col);
00467          }
00468       }
00469    };   // struct RetrieveMatrix
00470 
00471    // specialization for getting symmetric matrices from  general matrices (MUST fail)
00472    template <class T, unsigned int D1, unsigned int D2, 
00473              unsigned int D3, unsigned int D4 >
00474    struct RetrieveMatrix<T, D1, D2, D3, D4, MatRepSym<T,D1>, MatRepStd<T,D3,D4> > { 
00475       static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >& ,  
00476                            const SMatrix<T,D3,D4,MatRepStd<T,D3,D4> >& , 
00477                            unsigned int , unsigned int ) 
00478       {        
00479          STATIC_CHECK(0==1, Cannot_Sub_Matrix_symmetric_in_general_matrix);
00480       }
00481    }; // struct RetrieveMatrix
00482 
00483    // specialization for getting symmetric matrices from  symmetric matrices (OK if row == col)
00484    template <class T, unsigned int D1, unsigned int D2, 
00485              unsigned int D3, unsigned int D4 >
00486    struct RetrieveMatrix<T, D1, D2, D3, D4, MatRepSym<T,D1>, MatRepSym<T,D3> > { 
00487       static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >& lhs,  
00488                            const SMatrix<T,D3,D4,MatRepSym<T,D3> >& rhs, 
00489                            unsigned int row, unsigned int col ) 
00490       {        
00491          STATIC_CHECK(  D1 <= D3,Smatrix_dimension1_too_small); 
00492          // can work only if placed on the diagonal
00493          assert(row == col); 
00494          assert(row + D1 <= D3);
00495 
00496          for(unsigned int i=0; i<D1; ++i) {
00497             for(unsigned int j=0; j<=i; ++j) 
00498                lhs(i,j) = rhs(i+row,j+col );    
00499          }
00500       }
00501 
00502    }; // struct RetrieveMatrix
00503     
00504    /**
00505       Structure for assignment to a general matrix from iterator. 
00506       Optionally a check is done that iterator size 
00507       is not larger than matrix size  
00508     */
00509    template <class T, unsigned int D1, unsigned int D2, class R>  
00510    struct AssignItr { 
00511       template<class Iterator> 
00512       static void Evaluate(SMatrix<T,D1,D2,R>& lhs, Iterator begin, Iterator end, 
00513                            bool triang, bool lower,bool check=true) { 
00514          // require size match exactly (better)
00515 
00516          if (triang) { 
00517             Iterator itr = begin; 
00518             if (lower) { 
00519                for (unsigned int i = 0; i < D1; ++i) 
00520                   for (unsigned int j =0; j <= i; ++j) { 
00521                      // we assume iterator is well bounded within matrix
00522                      lhs.fRep[i*D2+j] = *itr++;
00523                   }
00524               
00525             }
00526             else { // upper 
00527                for (unsigned int i = 0; i < D1; ++i) 
00528                   for (unsigned int j = i; j <D2; ++j) { 
00529                      if (itr != end)  
00530                         lhs.fRep[i*D2+j] = *itr++;
00531                      else
00532                         return;
00533                   }
00534           
00535             }
00536          }
00537          // case of filling the full matrix
00538          else { 
00539             if (check) assert( begin + R::kSize == end);
00540             // copy directly the elements 
00541             std::copy(begin, end, lhs.fRep.Array() );
00542          }
00543       }
00544         
00545    }; // struct AssignItr
00546 
00547    /**
00548       Specialized structure for assignment to a symmetrix matrix from iterator. 
00549       Optionally a check isdone that iterator size 
00550       is the same as the matrix size  
00551     */
00552    template <class T, unsigned int D1, unsigned int D2>  
00553    struct AssignItr<T, D1, D2, MatRepSym<T,D1> >  { 
00554       template<class Iterator> 
00555       static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >& lhs, Iterator begin, Iterator end, bool , bool lower, bool check = true) { 
00556 
00557          if (lower) { 
00558             if (check) { 
00559                const int size =  MatRepSym<T,D1>::kSize; 
00560                assert( begin + size == end);
00561             }
00562             std::copy(begin, end, lhs.fRep.Array() );
00563          }
00564          else { 
00565             Iterator itr = begin; 
00566             for (unsigned int i = 0; i < D1; ++i) 
00567                for (unsigned int j = i; j <D2; ++j) { 
00568                   if (itr != end) 
00569                      lhs(i,j) = *itr++;
00570                   else 
00571                      return; 
00572                }
00573          }
00574       }
00575 
00576    }; // struct AssignItr
00577     
00578 
00579 }  // namespace Math
00580   
00581 }  // namespace ROOT
00582 
00583 #endif // MATH_HELPEROPS_H

Generated on Tue Jul 5 14:25:28 2011 for ROOT_528-00b_version by  doxygen 1.5.1