realroot_doc 0.1.1
/Users/mourrain/Devel/mmx/realroot/include/realroot/array.hpp
Go to the documentation of this file.
00001 /*********************************************************************
00002 *      This file is part of the source code of realroot kernel.        *
00003 *   Author(s): B. Mourrain, GALAAD, INRIA                            *
00004 **********************************************************************/
00006 #ifndef realroot_array_hpp
00007 #define realroot_array_hpp
00008 //------------------------------------------------------------------------
00009 #include <cassert>
00010 #include <realroot/assign.hpp>
00011 //======================================================================
00012 namespace mmx {
00013 //======================================================================
00014 
00036 namespace array {
00037   //----------------------------------------------------------------------
00039   template <class OS, class R>
00040   inline OS & print(OS & os, const R & v) {
00041     os <<"[";
00042     typename R::const_iterator i=v.begin();
00043     if (v.size()){
00044       os<<*i; ++i;
00045       for(; i != v.end(); ++i) {os <<", "; os<<*i;}
00046     }
00047     os <<"]";
00048     return os;
00049   }
00050   //----------------------------------------------------------------------
00052   template <class OS, class R>
00053   inline OS & print(OS & os, const R & v, unsigned sz) {
00054     os <<"[";
00055     unsigned i=0;
00056     if (sz){
00057       os<<v[i]; ++i;
00058       for(; i <sz; ++i) os <<","<<v[i];
00059     }
00060     os <<"]";
00061     return os;
00062   }
00063   //----------------------------------------------------------------------
00068   template <class IS, class R>
00069   inline IS & read(IS & is, R & V) {
00070     typedef typename R::size_type size_type;
00071     size_type s;
00072     is >> s;
00073     V.rep().resize(s);
00074     for(size_type i=0; i< s; ++i) is >> V[i];
00075     return(is);
00076   }
00077   //----------------------------------------------------------------------
00078   
00079   template <class V1, class V2> inline
00080   bool equal_n( const V1& v1, const V2 & v2, int n )
00081   {
00082     int i=0;
00083     while(i < n && v1[i] == v2[i]) i++;
00084     return i == n;
00085   };
00086   
00088   template <class V1, class V2> inline
00089   bool equal(const V1 & v1, const V2 & v2) 
00090   { return (v1.size() == v2.size()) && equal_n(v1,v2,v1.size()); }
00091 
00092   
00093   //---------------------------------------------------------------------- 
00094   template <class V, class C> inline
00095   void init_n(V & a, const C & v, int n ) { 
00096     for ( int i = 0; i < n; a[i] = v, i ++ ) {} };
00097 
00099   template <class V, class C>
00100   void set_cst(V & a, const C & v ) { init_n(a,v,(int)a.size()); };
00101 
00102 
00103   template <class V, class W>
00104   void set(V & a, const W & b ) {for ( int i = 0; i < (int)a.size(); a[i] = b[i], i ++ ) {} };
00105   
00106   //---------------------------------------------------------------------- 
00108   template <class V>
00109   void reverse_n( V & v, int a, int n )
00110   {
00111     int k = n - a;
00112     for ( int i = 0; i < k/2; std::swap(v[a+i],v[k-1-i]), i ++ ) {}
00113   };
00114   
00115   template <class V>
00116   void reverse( V & v, int n ) { reverse_n( v, 0, n ); };
00117   
00119   template <class V,class I>
00120   void reverse(V & v, I d) { 
00121     for(I i=0;i<d/2; std::swap(v[i],v[d-1-i]),++i) {}
00122   }
00123   
00124   //----------------------------------------------------------------------
00125   template<class V, class W> inline
00126   void neg_range( V & r, const W & w, int a, int b ) { 
00127     for ( int i = a; i < b; r[i] = -w[i], i++ ) {}
00128   }
00129   template<class V, class W> inline
00130   void neg_range( V & r, int a, int b )
00131   { for ( int i = a; i < b; r[i] = -r[i], i++ ){} };
00132   
00133   template<class VI> inline
00134   void neg_i( VI a, VI eda ) { for ( ; a != eda; *a = -(*a), a++ ){} };
00135   template<class VI> inline
00136   void neg_i( VI a, VI eda, VI b ) { for ( ; a != eda; *a = -(*b), a++, b++  ){} };
00137   template<class V> inline
00138   void neg( V & v ) { neg_i(v.begin(),v.end()); };
00139   template<class V> inline
00140   void neg( V & a, const V & b )
00141   { 
00142     a.resize( b.size() );
00143     neg_i( a.begin(), a.end(), b.begin() ); 
00144   };
00145   
00146   template<class V, class W> inline
00147   void copy_range( V & v, const W & w, int a, int b ) { for ( int i = a; i < b; v[i] = w[i], i ++ ){} }
00148   template< class V, class W >
00149   void add_n(V & a, const W & b, int n ) {for ( int i = 0; i < n; a[i] += b[i], i ++ ){} }
00150   template<class VI, class WI>
00151   void add_i( VI a, VI ea, WI b ) { for ( ; a != ea; *a += *b, ++a, ++b ){} };
00152   //----------------------------------------------------------------------
00154   template <class V, class W>
00155   void add(V & a, const W & b)
00156   {
00157     int asz, bsz;
00158     asz = a.size(), bsz = b.size();
00159     if ( asz < bsz  ) 
00160       { 
00161         a.resize(bsz);
00162         add_i(a.begin(),a.end(),b.begin()); 
00163         copy_range(a,b,asz,bsz);
00164       }
00165     else 
00166       {
00167         //      PRINT_DEBUG("add");
00168         add_n(a,b,bsz);
00169         //      add_i(a.begin(),a.begin()+bsz,b.begin());
00170       }
00171   }
00172 
00173   template< class V, class W, class X > inline
00174   void add_n(V & a, const W & b, const X& c, int n ) { for ( int i = 0; i < n; a[i] = b[i]+c[i], i ++ ){} };
00175 
00176   //--------------------------------------------------------------------
00179   template <class V, class W,class X>
00180   void add_g(V & r, const W & a, const X & b)
00181   {  
00182     int asz, bsz, rsz;
00183     asz = a.size(), bsz = b.size(), rsz = r.size();
00184     if ( asz > bsz ) 
00185       {
00186         if ( asz > rsz ) r.resize(asz);
00187         add_n(r,a,b,bsz);
00188         copy_range(r,a,bsz,asz);
00189       }
00190     else
00191       { 
00192         if ( bsz > rsz ) r.resize(bsz);
00193         add_n(r,a,b,asz); 
00194         copy_range(r,b,asz,bsz); 
00195       };
00196   }
00197   //--------------------------------------------------------------------
00200   template <class V, class W,class X> inline
00201   void add(V & r, const W & a, const X & b)
00202   {
00203     add_g(r,a,b);
00204   }
00205   //--------------------------------------------------------------------
00208   template <class V> inline
00209   void add(V & r, const V & a, const V & b)
00210   {
00211     if(&r==&a) { add(r,b); return; };
00212     if(&r==&b) { add(r,a); return; };
00213     add_g(r,a,b);
00214   }
00215   //====================================================================
00216   template< class V, class W >
00217   void sub_n(V & a, const W & b, int n ) { for ( int i = 0; i < n; a[i] -= b[i], i ++ ){} };
00218 
00219   //----------------------------------------------------------------------
00221   template <class V, class W>
00222   void sub(V & a, const W & b)
00223   {
00224     int asz, bsz;
00225     asz = a.size(), bsz = b.size();
00226     if ( asz < bsz  ) 
00227       { 
00228         a.resize(bsz);
00229         sub_n(a,b,asz);
00230         neg_range(a,b,asz,bsz); 
00231       }
00232     else  
00233       sub_n(a,b,bsz);
00234   }
00235   //--------------------------------------------------------------------
00236   template< class V, class W, class X > inline
00237   void sub_n(V & a, const W & b, const X& c, int n ) { for ( int i = 0; i < n; a[i] = b[i]-c[i], i ++ ){} };
00238   
00239   //--------------------------------------------------------------------
00240   template <class V, class W,class X>
00241   void sub_g(V & r, const W & a, const X & b)
00242   { 
00243     int asz, bsz, rsz;
00244     asz = a.size(), bsz = b.size(), rsz = r.size();
00245     
00246     if ( asz > bsz ) 
00247       {
00248         if ( asz > rsz ) r.resize(asz);
00249         sub_n(r,a,b,bsz);
00250         copy_range(r,a,bsz,asz);
00251       }
00252     else
00253       { 
00254         if ( bsz > rsz ) r.resize(bsz);
00255         sub_n(r,a,b,asz);
00256         neg_range(r,b,asz,bsz);
00257       };
00258   }
00261   template <class V, class W,class X>
00262   void sub(V & r, const W & a, const X & b)
00263   {
00264     sub_g(r,a,b);
00265   }
00266   //--------------------------------------------------------------------
00269   template <class V>
00270   void sub(V & r, const V & a, const V & b)
00271   {
00272     if(&r==&a) { sub(r,b); return; };
00273     //    if(&r==&b) { sub(r,a); mul_ext(r,-1); return; };
00274     sub_g(r,a,b);
00275   }
00276   //----------------------------------------------------------------------
00277   template<class V, class W> inline
00278   void mul_ext_n( V & a, const W & c, int n )
00279   { for ( int i = 0; i < n; a[i] = a[i]*c, i ++ ){} };
00280   template<class V, class W, class S> inline
00281   void mul_ext_n( V & a, const W & b, const S& c, int n ) 
00282   { for ( int i = 0; i < n; a[i] = b[i]*c, i++ ){} };
00283   template<class VI, class W> inline
00284   void mul_ext_i( VI bga, VI eda, const W & c )
00285     { for ( VI i = bga; i != eda; *i *= c, ++i  ){} };
00286   template<class VI, class VII, class W> inline
00287   void mul_ext_i( VI bga, VI eda, VII bgb, const W & c )
00288   { for ( VI a = bga; a != eda; *a = *bgb * c, ++bgb, ++a ){} };
00289 
00291   template <class V,class W>
00292   void mul_ext(V & a,  const V & b, const W & c)
00293   {
00294     if(&a != &b) {
00295       a.resize( b.size() );
00296       mul_ext_i(a.begin(),a.end(),b.begin(),c);
00297     }
00298     else 
00299       mul_ext_i(a.begin(),a.end(),c);
00300   }
00301   template <class V,class W>
00302   void mul_ext(V & a,  const W & c) {
00303     mul_ext_i(a.begin(),a.end(),c);
00304   }
00305   //----------------------------------------------------------------------
00306   template<class V, class SC> inline
00307   void div_ext_n( V & a, const SC & sc, int n )
00308   { for ( int i = 0; i < n; a[i] /= sc, i++){} }
00309   template<class V1, class V2, class SC>
00310   void div_ext_n( V1 & a, const V2 & b, const SC& sc, int n )
00311   { for ( int i = 0; i < n; a[i] = b[i]/sc, i ++ ){} };
00312   template<class VI, class SC> inline
00313   void div_ext_i( VI  bga, VI eda, const SC & sc )
00314   { for ( ; bga < eda; *bga /= sc, bga++){} }
00315   template<class VI, class SC> inline
00316   void div_ext_i( VI a, VI eda, VI b, const SC & sc )
00317   { for ( ; a < eda; *a = *b / sc, a++, b ++ ){} };
00319   template <class V, class SC>
00320   void div_ext( V & a,  const V & b, const SC & sc)
00321   {
00322     if(&a != &b) {
00323       a.resize( b.size() );
00324       div_ext_i(a.begin(),a.end(),b.begin(),sc);
00325     }
00326     else         div_ext_i(a.begin(),a.end(),sc);
00327   }
00329   template <class V, class W>
00330   void div_ext(V & a,  const W & c)
00331   { div_ext_i(a.begin(),a.end(),c); }
00332   //----------------------------------------------------------------------
00334   template <class V, class W>
00335   void div(V & a, const W & c)
00336   {
00337     div_ext(a,c);
00338     //W tmp(c); for(typename V::iterator it=a.begin(); it !=a.end(); ++it) (*it)/=tmp;
00339   }
00340   
00341   //----------------------------------------------------------------------
00342   template <class R, class S, class C> inline
00343   void apply_mult(R & result, const S& a, const C & m)
00344   { 
00345     typedef typename S::const_iterator  const_iterator;
00346     typedef typename R::iterator        iterator;
00347     result.resize(a.size());
00348     const_iterator b=a.begin(); iterator i=result.begin();
00349     for(; b!=a.end(); ++i, ++b) *i = (*b) * m;
00350   }
00351   //----------------------------------------------------------------------
00353   template <class C, class R>
00354   C  norm(const R & v)
00355   {
00356     C r=0;
00357     for(typename R::const_iterator it=v.begin(); it !=v.end(); ++it) r+=(*it)*(*it);
00358     return sqrt(r);
00359   }
00360   //----------------------------------------------------------------------
00362   template <class C,class R>
00363   C norm(const R & v, int p)
00364   {
00365     C r=0;
00366     for(typename R::const_iterator it=v.begin(); it !=v.end(); ++it) r+=pow(*it,p);
00367     return pow(r,1/p);
00368   }
00369   //----------------------------------------------------------------------
00371   template <class R, class S>
00372   typename R::value_type innerprod_n( const S & v, const R & w, unsigned n )
00373   {
00374     typename R::value_type r = 0;
00375     for ( unsigned i = 0; i < n; r += v[i]*w[i], i++ ) {}
00376     return r;
00377   };
00378   
00379   template <class R, class S>
00380   typename R::value_type innerprod(const S & v, const R & w)
00381   {
00382     typename R::value_type r =0;
00383     for(unsigned int i=0; i <v.size(); i++){r += (v[i]*w[i]);}
00384     return r;
00385   }
00386   //--------------------------------------------------------------------
00387   template<class R>
00388   typename R::value_type max_abs(const R& v)
00389   {
00390     typename R::value_type r=0;
00391     for(unsigned i=0; i <(unsigned)v.size(); i++)
00392       {
00393         if(r>v[i]) r=v[i];
00394         else if(r>-v[i]) r=-v[i];
00395       }
00396     return r;
00397   }
00398 
00399   //--------------------------------------------------------------------
00400   template<class U, class R>
00401   void lcm_denominator(U& r, const R& v)
00402   {
00403     for(unsigned i=0; i <v.size(); i++)
00404       {
00405         r = lcm(r,denominator(v[i]));
00406       }
00407   }
00408   //----------------------------------------------------------------------
00409   /* Replace R by its reverse */
00410   template < typename V> inline 
00411   void  reverse(V & v)
00412   { 
00413     unsigned sz = v.size();
00414     V temp(v);
00415     for (unsigned i = 0; i < sz; ++i)
00416       v[i] = temp[sz-1-i];
00417 }
00418 
00419   template<class Ia, class Ib> inline
00420   void assign_i( Ia a, Ia eda, Ib b )
00421   {
00422     for ( ; a != eda; ++a, ++b  ) let::assign(*a,*b);
00423   };
00424   
00425   template<class Ra, class Rb> inline
00426   void assign( Ra & a, const Rb & b )
00427   {
00428     a.resize( b.size() );
00429     assign_i( a.begin(), a.end(), b.begin() );
00430   };
00431 
00432   template<class R, class C> inline
00433   void vaddsc( R & r, const C & x )
00434   { for ( typename R::iterator i = r.begin(); i != r.end(); *i += x, i ++ ){} };
00435   
00436 } //CLOSE
00437 
00438 
00439 //======================================================================
00440 } // namespace mmx
00441 //======================================================================
00442 #endif // realroot_LINALG_VECTOR_H
00443