realroot_doc 0.1.1
|
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