00001
00002
00003
00004
00005
00006
00007 #ifndef SYNAPS_ARITHM_SIGN_H_
00008 #define SYNAPS_ARITHM_SIGN_H_
00009
00010 #include <synaps/init.h>
00011 #include <iterator>
00012
00013
00014 __BEGIN_NAMESPACE_SYNAPS
00015
00016 template<class T>
00017 inline bool with_plus_sign(const T& c) { return false; }
00018
00019 inline bool with_plus_sign(int c) { return (c>0);}
00020 inline bool with_plus_sign(long int c) { return (c>0);}
00021 inline bool with_plus_sign(unsigned ) { return true;}
00022 inline bool with_plus_sign(double c) { return (c>0);}
00023
00024 template<typename T> inline
00025 int sign(const T& x)
00026 {
00027 return ( x < T(0) ? -1 : (T(0) < x ? 1 : 0) );
00028 }
00029
00030
00033 template<typename Iterator>
00034 unsigned sign_variation( Iterator b, Iterator e )
00035 {
00036 unsigned c = 0;
00037
00038 while ( *b == 0 && b != e ) b++;
00039
00040 if ( b != e )
00041 {
00042 Iterator p = b;
00043 bool v = (*b<0);
00044 for( ++b; b != e; ++b )
00045 if ( (*b != 0) && ( (*b<0) != v ) ) { c++; p = b; v = !v; };
00046 };
00047
00048 return c;
00049 }
00050
00051 template<typename Iterator>
00052 unsigned sign_variation( Iterator b, Iterator e, unsigned maxv )
00053 {
00054 unsigned c = 0;
00055
00056 while ( *b == 0 && b != e ) b++;
00057
00058 if ( b != e )
00059 {
00060 Iterator p = b;
00061 bool v = (*b<0);
00062 for( ++b; c < maxv && b != e; ++b )
00063 if ( (*b != 0) && ( (*b<0) != v ) ) { c++; p = b; v = !v; };
00064 };
00065
00066 return c;
00067 }
00068
00069
00070
00075 template<typename T> inline
00076 int sign_variation(const T &v)
00077 { return sign_variation(v.begin(),v.end()); }
00078 template<typename T> inline
00079 int sign_variation(const T &v, unsigned maxv )
00080 { return sign_variation(v.begin(),v.end(),maxv); };
00081
00082 template<typename C, unsigned N>
00083 inline unsigned sign_variation( const C (&t)[N] )
00084 { return sign_variation(t,t+N); };
00085
00086 template<typename C, unsigned N> inline
00087 unsigned sign_variation( const C (&t)[N], unsigned maxv )
00088 { return sign_variation(t,t+N,maxv); };
00089
00090 template<typename C> inline
00091 unsigned sign_variation( const C * t, unsigned size )
00092 { return sign_variation(t,t+size); };
00093
00094 template<typename C> inline
00095 unsigned sign_variation( const C * t, unsigned size, unsigned maxv )
00096 { return sign_variation(t,t+size,maxv); };
00097
00098
00102 template<typename T>
00103 int Var(const T &v) { return sign_variation(v); }
00104
00105
00107 template<typename T>
00108 int Per(const T &v)
00109 {
00110 typedef typename T::const_iterator iter;
00111 int per=0;
00112 iter it0=v.begin(),it1=it0;++it1;
00113 for(;it1!=v.end();++it0,++it1)
00114 {
00115 if(sign(*it0)*sign(*it1)>0) per++;
00116 }
00117 return (per);
00118 }
00119
00120
00121 template<typename T>
00122 int Eps(const T &v)
00123 {
00124 typedef typename T::const_iterator iter;
00125 int result=0;
00126 iter iti, itj=v.begin()+1;
00127 iti=itj;
00128
00129 while (itj!=v.end())
00130 {
00131
00132 if ((*itj)==0)
00133 {
00134 iti=itj+1;
00135 while(iti!=v.end() && (*iti==0)) ++iti;
00136 if (iti!=v.end())
00137 {
00138
00139 if (std::distance(itj,iti)%2==0)
00140 {
00141 int val;
00142 if (sign(*(itj-1))*sign(*iti)>0) val=1; else val=-1;
00143 result += val*pow(-1,std::distance(itj,iti)/2);
00144 }
00145 itj=iti+1;
00146 }
00147 else
00148 return result;
00149 }
00150 else ++itj;
00151 }
00152 return result;
00153 }
00154
00155
00156 template<typename T>
00157 int Count(const T &v)
00158 {
00159 return (Per(v)-Var(v)+Eps(v));
00160 }
00161
00162 __END_NAMESPACE_SYNAPS
00163
00164 #endif // SYNAPS_ARITHM_SIGN_H_
00165