synaps/arithm/sign.h

00001 /********************************************************************
00002  *   This file is part of the source code of the SYNAPS 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 SYNAPS_ARITHM_SIGN_H_
00008 #define SYNAPS_ARITHM_SIGN_H_
00009 /********************************************************************/
00010 #include <synaps/init.h>
00011 #include <iterator>
00012 //#include <synaps/upol/UPOLDAR.h>
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   //  std::cout<<(*iti)<<" "<<(*itj)<<std::endl;
00129   while (itj!=v.end())
00130   {
00131     //    std::cout<<"L "<<(*iti)<<" "<<(*itj)<<std::endl;
00132     if ((*itj)==0)
00133       {
00134         iti=itj+1;
00135         while(iti!=v.end() && (*iti==0)) ++iti;
00136         if (iti!=v.end())
00137         {
00138           //      std::cout<<*iti<<" "<<*itj<<std::endl;          
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 

SYNAPS DOCUMENTATION
logo