00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef __MMX_ANALYTIC_META_HPP
00016 #define __MMX_ANALYTIC_META_HPP
00017 #include <continewz/analytic.hpp>
00018
00019 namespace mmx {
00020 #define TMPL template<typename C, typename V>
00021 #define Analytic analytic<C,V>
00022 #define Analytic_rep analytic_rep<C,V>
00023 #define Assume assume_bound<typename unvectorize<R >::val>
00024 #define Scalar typename unvectorize<C>::val
00025 #define Radius Abs_type(Scalar)
00026 #define Series series<C>
00027 #define Series_rep series_rep<C>
00028 #define Polynomial polynomial<C>
00029 #define R Abs_type(C)
00030
00031
00032
00033
00034
00035 TMPL
00036 class fast_eval_analytic_rep: public Analytic_rep {
00037 protected:
00038 typedef Fast_type(C) FC;
00039 typedef typename unvectorize<FC>::val FScalar;
00040
00041 Analytic f;
00042 polynomial<FC>* fp;
00043
00044 public:
00045 inline fast_eval_analytic_rep (const Analytic& f2):
00046 Analytic_rep (CF(f2)), f (f2), fp (NULL) {}
00047 inline ~fast_eval_analytic_rep () {
00048 if (fp != NULL) mmx_delete_one (fp); }
00049 void Clear_cache (nat which) const {
00050 Analytic_rep::Clear_cache (which);
00051 clear_cache (f, which); }
00052 syntactic expression (const syntactic& z) const {
00053 return apply ("fast_eval", flatten (f, z)); }
00054 Series Expand () const {
00055 return expand (f); }
00056 Radius Radius_bound (nat order) const {
00057 return radius_bound (f, order); }
00058 R Tail_bound (const Radius& r, nat order, Assume& a) const {
00059 return tail_bound (f, r, order, a); }
00060 Analytic Move (const Scalar& z) const {
00061 return fast_eval (move (f, z)); }
00062 C Eval (const Scalar& z) const {
00063 nat prec = precision (as<FScalar> (promote (0, z)));
00064 nat order= (nat) (mmx_order_ratio * ((double) prec));
00065 if (fp == NULL) {
00066 fast_eval_analytic_rep<C,V>* me=
00067 const_cast<fast_eval_analytic_rep<C,V>*> (this);
00068 polynomial<C> p= truncate (f, order);
00069 me->fp= mmx_new_one<polynomial<FC> > (fast (p));
00070 }
00071 FScalar fz= fast (z);
00072 FC sum= (*fp)[order-1];
00073 for (int i= order-2; i>=0; i--)
00074 sum= sum * fz + (*fp)[i];
00075 return slow<C> (sum); }
00076 Analytic Derive () const {
00077 return fast_eval (derive (f)); }
00078 };
00079
00080 TMPL Analytic
00081 fast_eval (const Analytic& f) {
00082
00083
00084 return (Analytic_rep*) new fast_eval_analytic_rep<C,V> (f);
00085 }
00086
00087
00088
00089
00090
00091 TMPL
00092 class analytic_next {
00093 MMX_ALLOCATORS
00094 public:
00095 Scalar next_point;
00096 Radius next_radius;
00097 Analytic next_function;
00098 };
00099
00100 TMPL
00101 class cache_last_analytic_rep: public Analytic_rep {
00102 protected:
00103 Analytic f;
00104 analytic_next<C,V>* next;
00105
00106 protected:
00107 void Set_next (const Scalar& z1) const {
00108
00109 typedef cache_last_analytic_rep<C,V> Me;
00110 Me* me= const_cast<Me* > (this);
00111 if (next == NULL) me->next= mmx_new_one<analytic_next<C,V> > ();
00112 me->next->next_point = z1;
00113 me->next->next_function= cache_last (move (f, z1));
00114 me->next->next_radius = radius_bound (next->next_function);
00115 }
00116
00117 public:
00118 inline cache_last_analytic_rep (const Analytic& f2):
00119 Analytic_rep (CF(f2)), f (f2), next (NULL) {}
00120 inline ~cache_last_analytic_rep () {
00121 if (next != NULL) mmx_delete_one (next); }
00122 void Clear_cache (nat which) const {
00123 Analytic_rep::Clear_cache (which);
00124 clear_cache (f, which); }
00125 syntactic expression (const syntactic& z) const {
00126 return apply ("cache_last", flatten (f, z)); }
00127 Series Expand () const {
00128 return expand (f); }
00129 Radius Radius_bound (nat order) const {
00130 return radius_bound (f, order); }
00131 R Tail_bound (const Radius& r, nat order, Assume& a) const {
00132 return tail_bound (f, r, order, a); }
00133 Analytic Move (const Scalar& z) const {
00134 return cache_last (move (f, z)); }
00135 C Eval (const Scalar& z) const {
00136 return eval (f, z); }
00137 Analytic Move (const list<Scalar >& l2) const {
00138
00139 if (is_nil (l2)) return this->me ();
00140 Radius r1= shrink (radius_bound (f));
00141 list<Scalar > l= simplify (l2, r1);
00142
00143 Scalar z1= car (l);
00144 if (next == NULL) Set_next (z1);
00145 if (hard_eq (z1, next->next_point))
00146 return move (next->next_function, cdr (l));
00147 Scalar z2= next->next_point;
00148 Radius r2= shrink (next->next_radius);
00149 if (is_nil (cdr (l)) || abs (z2 - z1) >= r2) {
00150
00151
00152
00153
00154 Set_next (z1);
00155 return move (next->next_function, cdr (l));
00156 }
00157 else return move (next->next_function, cons (z1 - z2, cdr (l))); }
00158 C Eval (const list<Scalar >& l2) const {
00159 if (is_nil (l2)) return this->me () [0];
00160 Radius r1= shrink (radius_bound (f));
00161 list<Scalar > l= simplify (l2, r1);
00162 Scalar z1= car (l);
00163 if (is_nil (cdr (l))) return eval (f, z1);
00164 if (next == NULL) Set_next (z1);
00165 if (hard_eq (z1, next->next_point))
00166 return eval (next->next_function, cdr (l));
00167 Scalar z2= next->next_point;
00168 Radius r2= shrink (next->next_radius);
00169 if (is_nil (cdr (l)) || abs (z2 - z1) >= r2) {
00170 Set_next (z1);
00171 return eval (next->next_function, cdr (l));
00172 }
00173 else return eval (next->next_function, cons (z1 - z2, cdr (l))); }
00174 Analytic Derive () const {
00175 return cache_last (derive (f)); }
00176 };
00177
00178 TMPL Analytic
00179 cache_last (const Analytic& f) {
00180
00181
00182
00183 return (Analytic_rep*) new cache_last_analytic_rep<C,V> (f);
00184 }
00185
00186 TMPL Analytic
00187 radial (const Analytic& f) {
00188 return cache_last (fast_eval (f));
00189 }
00190
00191
00192
00193
00194
00195
00196 TMPL
00197 class rough_analytic_rep: public Analytic_rep {
00198 Analytic f;
00199
00200 public:
00201 inline rough_analytic_rep (const Analytic& f2):
00202 Analytic_rep (CF(f2)), f (f2) {}
00203 void Clear_cache (nat which) const {
00204 Analytic_rep::Clear_cache (which);
00205 clear_cache (f, which); }
00206 syntactic expression (const syntactic& z) const {
00207 return apply ("rough", flatten (f, z)); }
00208 Series Expand () const {
00209 return expand (f); }
00210 Radius Radius_bound (nat order) const {
00211 return heuristic_radius (truncate (f, order), order); }
00212 R Tail_bound (const Radius& r, nat order, Assume& a) const {
00213 return tail_bound (f, r, order, a); }
00214 Analytic Move (const Scalar& z) const {
00215 return rough (move (f, z)); }
00216 Analytic Derive () const {
00217 return rough (derive (f)); }
00218 };
00219
00220 TMPL Analytic
00221 rough (const Analytic& f) {
00222 return (Analytic_rep*) new rough_analytic_rep<C,V> (f);
00223 }
00224
00225 #undef TMPL
00226 #undef Analytic
00227 #undef Analytic_rep
00228 #undef Assume
00229 #undef Scalar
00230 #undef Radius
00231 #undef Series
00232 #undef Series_rep
00233 #undef Polynomial
00234 #undef R
00235 }
00236 #endif // __MMX_ANALYTIC_META_HPP