00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __MMX__ANALYTIC_HEURISTIC__HPP
00014 #define __MMX__ANALYTIC_HEURISTIC__HPP
00015 #include <continewz/analytic_meta.hpp>
00016
00017 namespace mmx {
00018 #define TMPL template<typename C,typename V>
00019 #define R Abs_type(C)
00020 #define Analytic analytic<C,V>
00021 #define Analytic_rep analytic_rep<C,V>
00022 #define Heuristic_rep heuristic_analytic_rep<C,V>
00023 #define Series series<C>
00024 #define Polynomial polynomial<C>
00025 #define Pol polynomial<Fast_type(C) >
00026 #define Assume assume_bound<typename unvectorize<R >::val>
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 TMPL class heuristic_analytic_rep;
00037 TMPL Analytic heuristic (const Polynomial& f);
00038 TMPL Analytic heuristic (const Heuristic_rep* prev, const Polynomial& p,
00039 const Analytic& phi, const C& t, const C& u);
00040
00041 template<typename C> polynomial<C>
00042 compose (const polynomial<C>& p, const analytic<C>& post) {
00043 nat prec = precision (promote (0, CF(p)));
00044 nat order= (nat) (mmx_order_ratio * ((double) prec));
00045 nat n= max (N(p), order);
00046 polynomial<C> q= truncate (post, n);
00047 polynomial<C> r= promote (0, CF(p));
00048 for (int i= n-1; i>=0; i--) {
00049 polynomial<C> s= q * r;
00050 r= range (s, 0, min (n, N(s))) + polynomial<C> (p[i]);
00051 }
00052 return r;
00053 }
00054
00055 template<typename C> void
00056 heuristic_change (analytic<C>& phi, analytic<C>& psi,
00057 analytic<C>& ret, const analytic<C>& src,
00058 const C& v1, const C& v2, const R& r)
00059 {
00060 C u= v2 - v1;
00061 u= (u / abs (u)) * r;
00062 analytic<C> z (polynomial<C> (promote (1, v1), (nat) 1));
00063 phi= radial (u * z / (analytic<C> (u) + z));
00064 psi= radial (u * z / (analytic<C> (u) - z));
00065 ret= radial (u * src / (analytic<C> (u) + src));
00066
00067
00068
00069
00070
00071 }
00072
00073 TMPL
00074 class heuristic_analytic_rep: public Analytic_rep {
00075 protected:
00076 const Heuristic_rep* previous;
00077 Analytic prev;
00078 Polynomial p;
00079 Pol fp;
00080 R r;
00081 Analytic phi;
00082 C t;
00083 C u;
00084 vector<C> u_path;
00085 Analytic phi_at_u;
00086
00087 void initialize () {
00088 nat order= (nat) (mmx_order_ratio * ((double) precision ((double) 0.0)));
00089 fp= fast (p);
00090 r = heuristic_radius (p, order);
00091 if (previous == NULL) {
00092 u_path= vec<C> (u);
00093 phi_at_u= radial_move (phi, u);
00094 }
00095 else {
00096 prev= Analytic (previous, true);
00097 u_path= copy (previous->u_path);
00098 u_path[N(u_path) - 1]= t - previous->t;
00099 u_path << (u - t);
00100 phi_at_u= move (phi, u_path);
00101 }
00102 }
00103
00104 nat depth () const {
00105 if (previous == NULL) return 0;
00106 else return previous->depth () + 1;
00107 }
00108
00109 bool check (const C& z, const R& alpha) const {
00110 C v2= radial_eval (phi_at_u, z-u);
00111 return abs (v2) < alpha * r;
00112 }
00113
00114 public:
00115 heuristic_analytic_rep (const Polynomial& p2):
00116 Analytic_rep (CF(p2)),
00117 previous (NULL),
00118 p (p2),
00119 phi (radial (Analytic ((Polynomial (promote (1, CF(p2)), (nat) 1))))),
00120 t (promote (0, CF(p2))),
00121 u (promote (0, CF(p2))) { initialize (); }
00122 heuristic_analytic_rep (const Heuristic_rep* previous2, const Polynomial& p2,
00123 const Analytic& phi2, const C& t2, const C& u2):
00124 Analytic_rep (CF(p2)),
00125 previous (previous2),
00126 p (p2),
00127 phi (phi2),
00128 t (t2),
00129 u (u2) { initialize (); }
00130 syntactic expression (const syntactic& z) const {
00131 return apply ("heuristic", flatten (Expand (), z)); }
00132 Series Expand () const {
00133 return compose (p, phi_at_u); }
00134 R Radius_bound (nat order) const {
00135 ERROR ("not yet implemented");
00136 return R (0); }
00137 R Tail_bound (const R& r, nat order, Assume& a) const {
00138 ERROR ("not yet implemented");
00139 return R (0); }
00140 Analytic Default_move (const C& z) const {
00141 return heuristic<C,V> (previous, p, phi, t, u + z); }
00142 Analytic Move (const C& z) const {
00143 C u2= u + z;
00144
00145 R rr= shrink (promote (1, as<R> (abs (u2))));
00146 if (previous != NULL && previous->check (u2, rr))
00147 return previous->Move (u2 - previous->u);
00148 if (depth () >= 3 || check (u2, rr))
00149 return Default_move (z);
00150 C v = phi_at_u[0];
00151 C v2= radial_eval (phi_at_u, z);
00152 Analytic phi_post, psi_post;
00153 Analytic phi2;
00154 heuristic_change (phi_post, psi_post, phi2, phi, v, v2, r);
00155 Polynomial p2= compose (p, psi_post);
00156
00157 Analytic phi2_at_u = move (phi2, u_path);
00158 Analytic phi2_at_u2= radial_move (phi2_at_u, u2 - u);
00159 nat order= (nat) (mmx_order_ratio * ((double) precision ((double) 0.0)));
00160 C w2= phi2_at_u2[0];
00161 R r2= heuristic_radius (p2, order);
00162 if (abs (w2) >= r2) return Default_move (z);
00163
00164
00165
00166 return heuristic<C,V> (this, p2, phi2, u2, u2); }
00167 Analytic Derive () const {
00168 ERROR ("not yet implemented");
00169 return Analytic (0, this->tfm ()); }
00170 C Radial_eval (const C& z) {
00171 if (!check (u+z, promote (1, as<R> (abs(z))))) return Nan (C);
00172 return slow<C> (eval (fp, fast (radial_eval (phi_at_u, z)))); }
00173 };
00174
00175 TMPL Analytic
00176 heuristic (const Polynomial& p) {
00177 return (Analytic_rep*) new heuristic_analytic_rep<C,V> (p);
00178 }
00179
00180 TMPL Analytic
00181 heuristic (const Heuristic_rep* prev, const Polynomial& p,
00182 const Analytic& phi, const C& t, const C& u) {
00183 return (Analytic_rep*) new heuristic_analytic_rep<C,V> (prev, p, phi, t, u);
00184 }
00185
00186 template<typename C> analytic<C>
00187 std_heuristic (const polynomial<C>& p) {
00188 return heuristic<C,std_analytic> (p);
00189 }
00190
00191 #undef TMPL
00192 #undef R
00193 #undef Analytic
00194 #undef Analytic_rep
00195 #undef Heuristic_rep
00196 #undef Series
00197 #undef Polynomial
00198 #undef Pol
00199 #undef Assume
00200 }
00201
00202 #endif //__MMX__ANALYTIC_HEURISTIC__HPP