realroot_doc 0.1.1
/Users/mourrain/Devel/mmx/realroot/include/realroot/sign_variation.hpp
Go to the documentation of this file.
00001 /********************************************************************
00002  *   This file is part of the source code of the realroot kernel.
00003  *   Author(s): B. Mourrain, GALAAD, INRIA
00004  *              Fernando Carreras, Univ. Santander
00005  *   $Id: sign.h,v 1.2 2005/09/28 06:40:43 mourrain Exp $
00006  ********************************************************************/
00007 #ifndef mmx_sign_variation_hpp
00008 #define mmx_sign_variation_hpp
00009 /********************************************************************/
00010 #include <iterator>
00011 
00012 namespace mmx {
00013 
00014 #ifndef MMX_SIGN_FCT
00015 #define MMX_SIGN_FCT
00016 template<typename T> inline
00017 int sign(const T& x)
00018 {
00019   return ( x < T(0) ? -1 : (T(0) < x ? 1 : 0) );
00020 }
00021 #endif
00022 
00023 //--------------------------------------------------------------------
00026 template<typename Iterator>
00027 unsigned sign_variation( Iterator  b, Iterator  e )
00028 {
00029   unsigned c = 0;
00030  
00031   while (  *b == 0 && b != e ) b++;
00032   
00033   if ( b != e )
00034     {
00035       Iterator p = b;
00036       bool v = (*b<0);
00037       for( ++b; b != e;  ++b )
00038         if ( (*b != 0) && ( (*b<0) != v ) ) { c++; p = b; v = !v; };
00039     };
00040   
00041   return c;
00042 }
00043 
00044 template<typename Iterator>
00045 unsigned sign_variation( Iterator  b, Iterator  e, unsigned maxv )
00046 {
00047   unsigned c = 0;
00048  
00049   while (  *b == 0 && b != e ) b++;
00050 
00051   if ( b != e )
00052     {
00053       Iterator p = b;
00054       bool v = (*b<0);
00055       for( ++b; c < maxv && b != e;  ++b ) {
00056         if ( (*b != 0) && ( (*b<0) != v ) ) {
00057           c++; p = b; v = !v; };
00058       }
00059     };
00060   
00061   return c;
00062 }
00063 
00064 template<typename Vector>
00065 unsigned sign_variation_n( const Vector& t, unsigned l, unsigned maxv )
00066 {
00067  
00068   unsigned c = 0, i=0;
00069  
00070   while (  t[i] == 0 && i< l ) i++;
00071   if ( i<l )
00072     {
00073       unsigned p = i;
00074       bool v = (t[i]<0);
00075       for( ++i; c < maxv && i<l;  ++i ) {
00076         if ( (t[i] != 0) && ( (t[i]<0) != v ) ) {
00077           c++; p = i; v = !v; };
00078       }
00079     };
00080   return c;
00081 }
00082 
00083 template<typename Iterator>
00084 bool has_sign_variation( Iterator  b, Iterator  e)
00085 {
00086   return (sign_variation(b,e,1)>0);
00087 }
00088 
00089 template<typename Vector>
00090 bool has_sign_variation( const Vector& t)
00091 {
00092   return (sign_variation_n(t,t.size(),1)>0);
00093 }
00094 
00095 
00096 template<typename Vector>
00097 int sign_of( const Vector& t) {
00098   int i;
00099   for (i=0; (i<t.size() && t[i]==0); i++) ;
00100   if(i==t.size()) return 0;
00101 
00102   bool ng;
00103   for (ng=(t[i]<=0); i<t.size(); i++) 
00104     if(ng !=(t[i]<=0)) return 0;
00105   
00106   return (ng?-1:1);
00107 }
00108 
00109 //--------------------------------------------------------------------
00114 template<typename T> inline
00115 int sign_variation(const T &v) 
00116 { return sign_variation(v.begin(),v.end()); }
00117 template<typename T> inline
00118 int sign_variation(const T &v, unsigned maxv ) 
00119 { return sign_variation(v.begin(),v.end(),maxv); };
00120 
00121 template<typename C, unsigned N> 
00122 inline unsigned sign_variation( const C (&t)[N] ) 
00123 { return sign_variation(t,t+N); };
00124 
00125 template<typename C, unsigned N> inline
00126 unsigned sign_variation( const C (&t)[N], unsigned maxv ) 
00127 { return sign_variation(t,t+N,maxv); };
00128 
00129 template<typename C> inline
00130 unsigned sign_variation( const C * t, unsigned size )
00131 { return sign_variation(t,t+size); };
00132 
00133 template<typename C> inline 
00134 unsigned sign_variation( const C * t, unsigned size, unsigned maxv ) 
00135 { return sign_variation(t,t+size,maxv); };
00136 
00137 /********************************************************************/
00141 template<typename T>
00142 int Var(const T &v) { return sign_variation(v); }
00143 
00144 
00146 template<typename T>
00147 int Per(const T &v)
00148 {
00149   typedef typename T::const_iterator iter;
00150   int per=0;
00151   iter it0=v.begin(),it1=it0;++it1;
00152   for(;it1!=v.end();++it0,++it1)
00153   {
00154         if(sign(*it0)*sign(*it1)>0) per++;
00155   }
00156   return (per);
00157 }
00158 
00159 
00160 template<typename T>
00161 int Eps(const T &v)
00162 {
00163   typedef typename T::const_iterator iter;
00164   int result=0;
00165   iter iti, itj=v.begin()+1;
00166   iti=itj;
00167   //  std::cout<<(*iti)<<" "<<(*itj)<<std::endl;
00168   while (itj!=v.end())
00169   {
00170     //    std::cout<<"L "<<(*iti)<<" "<<(*itj)<<std::endl;
00171     if ((*itj)==0)
00172       {
00173         iti=itj+1;
00174         while(iti!=v.end() && (*iti==0)) ++iti;
00175         if (iti!=v.end())
00176         {
00177           //      std::cout<<*iti<<" "<<*itj<<std::endl;          
00178           if (std::distance(itj,iti)%2==0)
00179             { 
00180               int val;
00181               if (sign(*(itj-1))*sign(*iti)>0) val=1; else val=-1;
00182               result += val*pow(-1,std::distance(itj,iti)/2);
00183             }
00184           itj=iti+1;
00185         }
00186         else
00187           return result;
00188       }
00189     else ++itj;
00190   }
00191   return result;
00192 }
00193 
00194 
00195 template<typename T>
00196 int Count(const T &v)
00197 {
00198   return (Per(v)-Var(v)+Eps(v));
00199 }
00200 
00201 } // namespace mmx 
00202 
00203 #endif // realroot_ARITHM_SIGN_H_
00204