00001
00002
00003
00004
00005
00007 #ifndef SYNAPS_UPOL_BOUND_H
00008 #define SYNAPS_UPOL_BOUND_H
00009
00010 #include <synaps/init.h>
00011 #include <synaps/base/Debug_util.h>
00012 #include <synaps/base/type.h>
00013 #include <synaps/arithm/gmp.h>
00014 #include <synaps/arithm/double.h>
00015 #include <vector>
00016
00017 __BEGIN_NAMESPACE_SYNAPS
00018
00020 struct NISP{};
00021
00023 struct NISN{};
00024
00026 struct Cauchy {};
00027
00028
00036 template < typename POLY,
00037 typename M,
00038 typename T >
00039 T bound(const POLY& p, const M& mth, type::As<T>)
00040 {
00041 return T(0);
00042 }
00043
00044
00045
00046
00047
00048
00049
00050
00051 template < typename T >
00052 struct abs_max : public std::unary_function<T, void>
00053 {
00054 abs_max() : max(T(-1)) {}
00055 void operator() (const T& x)
00056 {
00057 using std::abs;
00058 T temp = abs(x);
00059 if (temp > max) max = temp;
00060 }
00061 T max;
00062 };
00063
00064
00084 template <typename FT, typename POLY>
00085 FT bound(const POLY& p, Cauchy)
00086 {
00087 using std::abs;
00088 DEBUG::print("Cauchy");
00089
00090 typedef typename POLY::value_type RT;
00091
00092 abs_max<RT> M = std::for_each(p.begin(), p.end()-1, abs_max<RT>());
00093 RT an = abs(UPOLDAR::lcoeff(p));
00094 return let::convert(RT(M.max + an), an, type::As<FT>());
00095 }
00096
00097
00098 template < typename FT, typename POLY>
00099 FT
00100 max_bound(const POLY& p, Cauchy)
00101 {
00102 return bound< FT >(p, Cauchy());
00103 }
00104
00105 template < typename FT, typename POLY>
00106 FT
00107 min_bound(const POLY& p, Cauchy)
00108 {
00109 POLY f(p);
00110 UPOLDAR::reverse(f, UPOLDAR::degree(p));
00111 FT tmp = bound<FT>(f, Cauchy());
00112 return let::convert(denominator(tmp), numerator(tmp), type::As<FT>());
00113 }
00114
00123 template <typename FT, typename POLY>
00124 FT bound(const POLY& p, NISP )
00125 {
00126 typedef typename POLY::value_type RT;
00127
00128
00129
00130 FT max(0);
00131 FT sum(0);
00132
00133 unsigned i;
00134 unsigned n = p.size();
00135
00136
00137 i = n; while ( p[--i] == 0 ); n = i+1;
00138 if ( p[i] > 0 )
00139 {
00140 i = 0;
00141 while ( p[i] > 0 && i < n ) i++;
00142 if ( i == n ) return 0;
00143
00144 for ( unsigned k = i+1; k < n; k ++ )
00145 if ( p[k] > 0 ) sum += p[k];
00146
00147 for ( unsigned k = i; k < n; k ++ )
00148 {
00149 if ( p[k] < 0 )
00150 { FT tmp = -p[k]/sum; if ( tmp > max ) max = tmp; }
00151 else
00152 sum -= p[k];
00153 };
00154 }
00155 else
00156 {
00157 i = 0;
00158 while ( p[i] < 0 && i < n ) i++;
00159 if ( i == n ) return 0;
00160 for ( unsigned k = i+1; k < n; k ++ )
00161 if ( p[k] < 0 ) sum += p[k];
00162 for ( unsigned k = i; k < n; k ++ )
00163 if ( p[k] > 0 ) { FT tmp = -p[k]/sum; if ( tmp > max ) max = tmp; }
00164 else sum -= p[k];
00165 };
00166 max += 1;
00167 return max;
00168 }
00169
00178 template <typename FT, typename POLY>
00179 FT bound(const POLY& p, NISN )
00180 {
00181 typedef typename POLY::value_type RT;
00182
00183 POLY tmp = p;
00184 for ( unsigned i = 1; i < p.size(); i += 2 )
00185 tmp[i] = -tmp[i];
00186 return -bound<FT>(tmp,NISP());
00187 };
00188
00189 __END_NAMESPACE_SYNAPS
00190
00191 #endif // SYNAPS_UPOL_BOUND_H
00192