basix_doc 0.1
|
00001 00002 /****************************************************************************** 00003 * MODULE : generic.hpp 00004 * DESCRIPTION: Generic expressions 00005 * COPYRIGHT : (C) 2005 Joris van der Hoeven 00006 ******************************************************************************* 00007 * This software falls under the GNU general public license and comes WITHOUT 00008 * ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details. 00009 * If you don't have this file, write to the Free Software Foundation, Inc., 00010 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00011 ******************************************************************************/ 00012 00013 #ifndef __GENERIC_HPP 00014 #define __GENERIC_HPP 00015 #include <typeinfo> 00016 #include <basix/defaults.hpp> 00017 00019 00020 namespace mmx { 00021 #define TMPL template<typename C> 00022 #define Acc accelerator<C> 00023 class generic; 00024 class syntactic; 00025 class port; 00026 class string; 00027 class routine; 00028 class routine_rep; 00029 struct exact_eq_table; 00030 template<typename T,typename F> struct as_helper; 00031 template<typename T,typename F> inline T as (const F& x); 00032 template<typename C> struct vector_as_helper; 00033 TMPL struct inspector; 00034 TMPL struct binary_helper; 00035 generic gen_vec (); 00036 generic gen_vec (const generic& g1); 00037 generic gen_vec (const generic& g1, const generic& g2); 00038 generic gen_vec (const generic& g1, const generic& g2, const generic& g3); 00039 generic vector_access (const generic& g, nat i); 00040 TMPL generic binary_disassemble (const C& x); 00041 TMPL void binary_write (const port& out, const C& x); 00042 TMPL inline port operator << (const port& out, const C& x); 00043 void write (const port& p, const char* s, nat n); 00044 void write (const port& p, const string& s); 00045 extern port mmout; 00046 extern port mmerr; 00047 extern bool booting_done; 00048 extern generic GEN_CONVERT; 00049 00050 /****************************************************************************** 00051 * Accelerated methods 00052 ******************************************************************************/ 00053 00054 #define ACC_NEGATE 0 00055 #define ACC_SQUARE 1 00056 #define ACC_INVERT 2 00057 #define ACC_ADD 3 00058 #define ACC_SUB 4 00059 #define ACC_MUL 5 00060 #define ACC_DIV 6 00061 #define ACC_SQRT 8 00062 #define ACC_EXP 9 00063 #define ACC_LOG 10 00064 #define ACC_COS 11 00065 #define ACC_SIN 12 00066 #define ACC_TAN 13 00067 #define ACC_ACOS 14 00068 #define ACC_ASIN 15 00069 #define ACC_ATAN 16 00070 #define ACC_COSH 17 00071 #define ACC_SINH 18 00072 #define ACC_TANH 19 00073 #define ACC_ACOSH 20 00074 #define ACC_ASINH 21 00075 #define ACC_ATANH 22 00076 #define ACC_HYPOT 23 00077 #define ACC_ATAN2 24 00078 #define ACC_POW 25 00079 #define ACC_LESS 26 00080 #define ACC_LESSEQ 27 00081 #define ACC_GTR 28 00082 #define ACC_GTREQ 29 00083 #define ACC_DERIVE 30 00084 #define ACC_DERIVE_WRT 31 00085 #define ACC_INTEGRATE 32 00086 #define ACC_INTEGRATE_WRT 33 00087 00088 /****************************************************************************** 00089 * The generic class 00090 ******************************************************************************/ 00091 00092 class generic_rep: public rep_struct { 00093 public: 00094 virtual nat get_type () const = 0; 00095 virtual bool same_type (const generic& g) const = 0; 00096 virtual nat get_symbolic_type () const = 0; 00097 virtual nat get_species_type () const = 0; 00098 virtual nat get_length () const = 0; 00099 virtual generic get_child (nat i) const = 0; 00100 virtual nat get_hard_hash_value () const = 0; 00101 virtual nat get_exact_hash_value () const = 0; 00102 virtual nat get_hash_value () const = 0; 00103 virtual bool is_hard_eq (const generic& rep) const = 0; 00104 virtual bool is_exact_eq (const generic& rep) const = 0; 00105 virtual bool is_equal (const generic& rep) const = 0; 00106 virtual generic duplicate_me () const = 0; 00107 virtual syntactic expression () const = 0; 00108 virtual generic binary_type () const = 0; 00109 virtual generic binary_disassemble () const = 0; 00110 virtual void binary_write (const port& p) const = 0; 00111 virtual generic make_abstract_vector () const = 0; 00112 virtual generic make_concrete_vector (const generic& v) const = 0; 00113 00114 virtual nat acc_id () const; 00115 virtual routine* acc_construct (nat id) const; 00116 virtual routine* acc_apply (nat code) const; 00117 00118 public: 00119 inline generic_rep () {} 00120 inline virtual ~generic_rep () {} 00121 inline generic me () const; 00122 00123 friend class generic; 00124 }; 00125 00126 class generic { 00127 INDIRECT_PROTO (generic, generic_rep) 00128 public: 00129 generic (); 00130 generic (const char* s); 00131 generic (const string& s); 00132 generic (int i); 00133 generic (nat i); 00134 generic operator () () const; 00135 generic operator () (const generic& g1) const; 00136 generic operator () (const generic& g1, const generic& g2) const; 00137 generic operator () (const generic& g1, const generic& g2, 00138 const generic& g3) const; 00139 00140 inline generic operator [] (nat i) const { return rep->get_child (i); } 00141 inline friend generic_rep* inspect (const generic& g) { return g.rep; }; 00142 friend syntactic flatten (const generic& g); 00143 00144 friend class generic_rep; 00145 }; 00146 INDIRECT_IMPL (generic, generic_rep) 00147 00148 inline generic generic_rep::me () const { 00149 return generic (this, true); } 00150 inline nat type (const generic& g) { 00151 return g->get_type (); } 00152 inline nat symbolic_type (const generic& g) { 00153 return g->get_symbolic_type (); } 00154 inline nat species_type (const generic& g) { 00155 return g->get_species_type (); } 00156 inline nat N (const generic& g) { 00157 return g->get_length (); } 00158 inline nat gen_hash (const generic& g) { 00159 return g->get_hard_hash_value (); } 00160 inline nat exact_hash (const generic& g) { 00161 return g->get_exact_hash_value (); } 00162 inline nat hash (const generic& g) { 00163 return g->get_hash_value (); } 00164 inline bool gen_eq (const generic& g1, const generic& g2) { 00165 return g1->is_hard_eq (g2); } 00166 inline bool gen_neq (const generic& g1, const generic& g2) { 00167 return !g1->is_hard_eq (g2); } 00168 00169 /****************************************************************************** 00170 * Type information 00171 ******************************************************************************/ 00172 00173 nat new_type_id (); 00174 nat new_type_id (const char*); 00175 00176 template<typename T> 00177 inline nat global_type_id () { return new_type_id (typeid (T ()).name()); } 00178 inline nat binary_id (nat id1, nat id2) { return id1 ^ (0x10115 * id2); } 00179 template<typename T> struct type_information { static nat id; }; 00180 template<typename T> nat type_information<T>::id= global_type_id<T> (); 00181 STMPL struct type_information<generic> { static nat id; }; 00182 TMPL inline bool is (const generic& x) { 00183 return type (x) == type_information<C>::id; } 00184 inline bool same_type (const generic& x1, const generic& x2) { 00185 return x1->same_type (x2); } 00186 vector<generic> all_type_names (); 00187 void define_type_sub (const generic& name, nat id); 00188 nat type_id (const generic& name); 00189 generic type_name (nat id); 00190 generic type_name (const generic& g); 00191 template<typename C> inline nat type_id () { 00192 return type_information<C>::id; } 00193 template<typename C> inline generic type_name () { 00194 return type_name (type_id<C> ()); } 00195 00196 #define SYMBOLIC_UNSPECIFIED 0 00197 #define SYMBOLIC_INTEGER 1 00198 #define SYMBOLIC_RATIONAL 2 00199 #define SYMBOLIC_FLOATING 3 00200 #define SYMBOLIC_BALL 4 00201 #define SYMBOLIC_REAL 5 00202 #define SYMBOLIC_LITERAL 6 00203 #define SYMBOLIC_COMPOUND 7 00204 #define SYMBOLIC_SUM 8 00205 #define SYMBOLIC_PRODUCT 9 00206 #define SYMBOLIC_DERIVATIVE 10 00207 #define SYMBOLIC_FUNCTION 11 00208 00209 template<typename T> struct symbolic_type_information { 00210 static const nat id= SYMBOLIC_UNSPECIFIED; }; 00211 00212 #define SPECIES_DEFAULT 0 00213 #define SPECIES_VECTOR 1 00214 #define SPECIES_LIST 2 00215 #define SPECIES_TABLE 3 00216 00217 template<typename T> struct species_type_information { 00218 static const nat id= SPECIES_DEFAULT; }; 00219 inline bool is_vector (const generic& x) { 00220 return species_type (x) == SPECIES_VECTOR; } 00221 inline bool is_list (const generic& x) { 00222 return species_type (x) == SPECIES_LIST; } 00223 inline bool is_table (const generic& x) { 00224 return species_type (x) == SPECIES_TABLE; } 00225 00226 /****************************************************************************** 00227 * Syntactic manipulation of generic objects 00228 ******************************************************************************/ 00229 00230 generic lit (const char* s); 00231 generic lit (const string& s); 00232 00233 generic gen (const generic& x1, const vector<generic>& v); 00234 generic gen (); 00235 generic gen (const generic& x1); 00236 generic gen (const generic& x1, const string& x2); 00237 generic gen (const generic& x1, const generic& x2); 00238 generic gen (const generic& x1, const generic& x2, const generic& x3); 00239 generic gen (const generic& x1, const generic& x2, 00240 const generic& x3, const generic& x4); 00241 generic gen (const generic& x1, const generic& x2, 00242 const generic& x3, const generic& x4, const generic& x5); 00243 generic gen (const generic& x1, const generic& x2, 00244 const generic& x3, const generic& x4, 00245 const generic& x5, const generic& x6); 00246 00247 generic void_value (); 00248 generic comma (); 00249 generic comma (const generic& x1, const generic& x2); 00250 generic xgen (const generic& f, const generic& args); 00251 generic xaccess (const generic& f, const generic& args); 00252 generic xtuple (const generic& args); 00253 generic xsqtuple (const generic& args); 00254 generic xrow (const generic& args); 00255 generic access (const generic& f, const generic& x); 00256 generic access (const generic& f, const generic& x, const generic& y); 00257 generic access (const generic& f, const vector<generic>& x); 00258 00259 generic as_object (const generic& v, nat tp_id); 00260 generic as_object (const generic& v, const generic& tp); 00261 generic as_generic (const generic& obj, nat tp_id); 00262 generic as_generic (const generic& obj, const generic& tp); 00263 00264 generic range (const generic& g, nat start, nat end); 00265 generic append (const generic& g1, const generic& g2); 00266 generic cons (const generic& g1, const generic& g2); 00267 generic cons (const generic& g1, const generic& g2, const generic& g3); 00268 generic car (const generic& g); 00269 generic cdr (const generic& g); 00270 00271 bool is_func (const generic& g, const char* f); 00272 bool is_func (const generic& g, const char* f, nat n); 00273 bool is_func (const generic& g, const generic& f); 00274 bool is_func (const generic& g, const generic& f, nat n); 00275 nat size (const generic& g); 00276 int big_small_compare (const generic& g1, const generic& g2); 00277 int small_big_compare (const generic& g1, const generic& g2); 00278 00279 /****************************************************************************** 00280 * Generic functions 00281 ******************************************************************************/ 00282 00283 generic convert (const generic& from, const generic& to); 00284 00285 void set_smallest (generic& x); 00286 void set_largest (generic& x); 00287 void set_accuracy (generic& x); 00288 void set_pi (generic& x); 00289 void set_log2 (generic& x); 00290 void set_euler (generic& x); 00291 void set_catalan (generic& x); 00292 void set_imaginary (generic& x); 00293 void set_nan (generic& x); 00294 void set_fuzz (generic& x); 00295 void set_infinity (generic& x); 00296 void set_maximal (generic& x); 00297 void set_minimal (generic& x); 00298 00299 generic operator - (const generic& x1); 00300 generic square (const generic &x1); 00301 generic invert (const generic &x1); 00302 generic operator + (const generic& x1, const generic& x2); 00303 generic operator - (const generic& x1, const generic& x2); 00304 generic operator * (const generic& x1, const generic& x2); 00305 generic operator / (const generic& x1, const generic& x2); 00306 generic operator + (const generic& x1, const int& x2); 00307 generic operator - (const generic& x1, const int& x2); 00308 generic operator * (const generic& x1, const int& x2); 00309 generic operator / (const generic& x1, const int& x2); 00310 generic operator + (const int& x1, const generic& x2); 00311 generic operator - (const int& x1, const generic& x2); 00312 generic operator * (const int& x1, const generic& x2); 00313 generic operator / (const int& x1, const generic& x2); 00314 00315 generic sqrt (const generic& x1); 00316 generic exp (const generic& x1); 00317 generic log (const generic& x1); 00318 generic cos (const generic& x1); 00319 generic sin (const generic& x1); 00320 generic tan (const generic& x1); 00321 generic acos (const generic& x1); 00322 generic asin (const generic& x1); 00323 generic atan (const generic& x1); 00324 generic cosh (const generic& x1); 00325 generic sinh (const generic& x1); 00326 generic tanh (const generic& x1); 00327 generic acosh (const generic& x1); 00328 generic asinh (const generic& x1); 00329 generic atanh (const generic& x1); 00330 generic hypot (const generic& x1, const generic& x2); 00331 generic atan2 (const generic& x1, const generic& x2); 00332 generic pow (const generic& x1, const generic& x2); 00333 generic pow (const generic& x1, const int& x2); 00334 generic pow (const int& x1, const generic& x2); 00335 00336 bool operator == (const generic& x1, const generic& x2); 00337 bool operator != (const generic& x1, const generic& x2); 00338 bool operator == (const generic& x1, const int& x2); 00339 bool operator != (const generic& x1, const int& x2); 00340 bool operator == (const int& x1, const generic& x2); 00341 bool operator != (const int& x1, const generic& x2); 00342 bool exact_eq (const generic& x1, const generic& x2); 00343 bool exact_neq (const generic& x1, const generic& x2); 00344 bool exact_eq (const generic& x1, const int& x2); 00345 bool exact_neq (const generic& x1, const int& x2); 00346 bool exact_eq (const int& x1, const generic& x2); 00347 bool exact_neq (const int& x1, const generic& x2); 00348 inline bool is_exact_zero (const generic& g1) { return exact_eq (g1, 0); } 00349 00350 bool operator < (const generic& x1, const generic& x2); 00351 bool operator <= (const generic& x1, const generic& x2); 00352 bool operator > (const generic& x1, const generic& x2); 00353 bool operator >= (const generic& x1, const generic& x2); 00354 bool operator < (const generic& x1, const int& x2); 00355 bool operator <= (const generic& x1, const int& x2); 00356 bool operator > (const generic& x1, const int& x2); 00357 bool operator >= (const generic& x1, const int& x2); 00358 bool operator < (const int& x1, const generic& x2); 00359 bool operator <= (const int& x1, const generic& x2); 00360 bool operator > (const int& x1, const generic& x2); 00361 bool operator >= (const int& x1, const generic& x2); 00362 00363 generic derive (const generic& x1); 00364 generic integrate (const generic& x1); 00365 generic derive (const generic& x1, const generic& x2); 00366 generic integrate (const generic& x1, const generic& x2); 00367 00368 /****************************************************************************** 00369 * Routines based on the current evaluator 00370 ******************************************************************************/ 00371 00372 generic construct (const int& i); 00373 generic construct (const nat& i); 00374 generic construct (const double& x); 00375 generic construct (const float& x); 00376 generic construct (const generic& x); 00377 generic eval (const generic& x); 00378 00379 generic apply (const generic& f, const generic& x); 00380 generic apply (const generic& f, const generic& x, const generic& y); 00381 generic apply (const generic& f, const generic& x, 00382 const generic& y, const generic& z); 00383 generic apply (const generic& f, const vector<generic>& x); 00384 00385 generic quo (const generic& x1, const generic& x2); 00386 generic rem (const generic& x1, const generic& x2); 00387 generic numerator (const generic& x); 00388 generic denominator (const generic& x); 00389 generic gcd (const generic& x1, const generic& x2); 00390 generic lcm (const generic& x1, const generic& x2); 00391 TMPL struct xgcd_matrix; 00392 xgcd_matrix<generic> xgcd (const generic& x1, const generic& x2); 00393 00394 generic pow (const generic& x1, const nat& x2); 00395 generic pow (const nat& x1, const generic& x2); 00396 generic trig (const generic& x1); 00397 00398 generic min (const generic& x1, const generic& x2); 00399 generic max (const generic& x1, const generic& x2); 00400 generic abs (const generic& x1); 00401 generic arg (const generic& x1); 00402 generic Re (const generic& x1); 00403 generic Im (const generic& x1); 00404 generic conj (const generic& x1); 00405 generic gaussian (const generic& x1, const generic& x2); 00406 generic polar (const generic& x1, const generic& x2); 00407 00408 generic floor (const generic& x); 00409 generic trunc (const generic& x); 00410 generic ceil (const generic& x); 00411 generic round (const generic& x); 00412 00413 generic prime (const generic& x1); 00414 generic substitute (const generic& x1, const generic& x2); 00415 generic compose (const generic& x1, const generic& x2); 00416 generic dilate (const generic& x1, const generic& x2); 00417 generic solve (const generic& x1, const generic& x2); 00418 00419 generic sqrt_init (const generic& x, const generic& c); 00420 generic log_init (const generic& x, const generic& c); 00421 generic acos_init (const generic& x, const generic& c); 00422 generic asin_init (const generic& x, const generic& c); 00423 generic atan_init (const generic& x, const generic& c); 00424 generic integrate_init (const generic& x, const generic& c); 00425 generic solve_lde_init (const generic& x, const generic& c); 00426 00427 generic change_precision (const generic& x, xnat p); 00428 xnat precision (const generic& x); 00429 generic next_above (const generic& x); 00430 generic next_below (const generic& x); 00431 generic rounding_error (const generic& x); 00432 generic additive_error (const generic& x); 00433 generic multiplicative_error (const generic& x); 00434 generic elementary_error (const generic& x); 00435 xint exponent (const generic& x); 00436 double magnitude (const generic& x); 00437 generic incexp2 (const generic& x1, const xint& x2); 00438 generic decexp2 (const generic& x1, const xint& x2); 00439 generic operator << (const generic& x1, const generic& x2); 00440 generic operator >> (const generic& x1, const generic& x2); 00441 00442 generic lshiftz (const generic& x1, const generic& x2); 00443 generic rshiftz (const generic& x1, const generic& x2); 00444 generic operator | (const generic& x1, const generic& x2); 00445 generic operator & (const generic& x1, const generic& x2); 00446 generic lres (const generic& x1, const generic& x2); 00447 generic rres (const generic& x1, const generic& x2); 00448 generic uniform (const generic& x1, const generic& x2); 00449 generic specialize (const generic& x1, const generic& x2); 00450 00451 generic center (const generic& x1); 00452 generic radius (const generic& x1); 00453 generic sharpen (const generic& x1); 00454 generic blur (const generic& x1, const generic& x2); 00455 00456 /****************************************************************************** 00457 * Accelerators 00458 ******************************************************************************/ 00459 00460 TMPL 00461 struct accelerator { 00462 static nat id; 00463 static routine *construct; 00464 static nat nr_construct; 00465 static routine *apply; 00466 static nat nr_apply; 00467 static void set_construct (nat id, const routine& r); 00468 static void set_apply (nat code, const routine& r); 00469 }; 00470 00471 TMPL nat Acc::id= (nat) -1; 00472 TMPL routine *Acc::construct= NULL; 00473 TMPL nat Acc::nr_construct= (nat) 0; 00474 TMPL routine *Acc::apply= NULL; 00475 TMPL nat Acc::nr_apply= (nat) 0; 00476 00477 typedef routine* vec_routine; 00478 void fill_out (vec_routine& v, nat& n, nat i, const routine& r); 00479 00480 /****************************************************************************** 00481 * Concrete instances 00482 ******************************************************************************/ 00483 00484 TMPL 00485 class generic_concrete_rep: public generic_rep { 00486 public: 00487 C rep; 00488 00489 protected: 00490 nat get_type () const { return type_information<C>::id; } 00491 bool same_type (const generic& g) const { return is<C> (g); } 00492 nat get_symbolic_type () const { return symbolic_type_information<C>::id; } 00493 nat get_species_type () const { return species_type_information<C>::id; } 00494 nat get_length () const { return inspector<C>::length (rep); } 00495 generic get_child (nat i) const { return inspector<C>::access (rep, i); } 00496 nat get_hard_hash_value () const { return hard_hash (rep); } 00497 nat get_exact_hash_value () const { return exact_hash (rep); } 00498 nat get_hash_value () const { return hash (rep); } 00499 bool is_hard_eq (const generic& g) const { 00500 if (type (g) != type_information<C>::id) return false; 00501 return hard_eq (rep, ((generic_concrete_rep<C>*) inspect (g)) -> rep); } 00502 bool is_exact_eq (const generic& g) const { 00503 if (type (g) != type_information<C>::id) return false; 00504 return exact_eq (rep, ((generic_concrete_rep<C>*) inspect (g)) -> rep); } 00505 bool is_equal (const generic& g) const { 00506 if (type (g) != type_information<C>::id) return false; 00507 return rep == ((generic_concrete_rep<C>*) inspect (g)) -> rep; } 00508 generic duplicate_me () const { return as<generic> (duplicate (rep)); } 00509 syntactic expression () const; // definition in syntactic.hpp 00510 generic binary_type () const { 00511 return binary_helper<C>::full_type_name (); } 00512 generic binary_disassemble () const { 00513 return mmx::binary_disassemble (rep); } 00514 void binary_write (const port& out) const { 00515 mmx::write (out, binary_helper<C>::short_type_name ()); 00516 mmx::write (out, ":", 1); 00517 mmx::binary_write (out, rep); } 00518 generic make_abstract_vector () const { 00519 return vector_as_helper<C>::abstract (rep); } 00520 generic make_concrete_vector (const generic& v) const { 00521 return as<generic> (vector_as_helper<C>::concrete (v)); } 00522 00523 inline nat acc_id () const { 00524 return Acc::id; } 00525 inline routine* acc_construct (nat id) const { 00526 if (id < Acc::nr_construct) 00527 return (routine*) (void*) 00528 (((routine_rep**) (void*) Acc::construct) + id); 00529 else return NULL; } 00530 inline routine* acc_apply (nat code) const { 00531 if (code < Acc::nr_apply) 00532 return (routine*) (void*) 00533 (((routine_rep**) (void*) Acc::apply) + code); 00534 else return NULL; } 00535 00536 public: 00537 generic_concrete_rep (const C& rep2): rep (rep2) {} 00538 }; 00539 00540 TMPL 00541 struct as_helper<generic,C> { 00542 static inline generic cv (const C& x) { 00543 return new generic_concrete_rep<C> (x); } 00544 }; 00545 00546 TMPL 00547 struct as_helper<C,generic> { 00548 static inline C cv (const generic& x) { 00549 return ((generic_concrete_rep<C>*) inspect(x)) -> rep; } 00550 }; 00551 00552 STMPL 00553 struct as_helper<generic,generic> { 00554 static inline generic cv (const generic& x) { return x; } 00555 }; 00556 00557 TMPL generic 00558 as_generic (const C& c) { 00559 return construct (new generic_concrete_rep<C> (c)); 00560 } 00561 00562 TMPL inline void 00563 set_as (generic& r, const C& x) { 00564 r= new generic_concrete_rep<C> (x); 00565 } 00566 00567 TMPL inline void 00568 set_as (C& r, const generic& x) { 00569 r= ((generic_concrete_rep<C>*) inspect(x)) -> rep; 00570 } 00571 00572 inline void 00573 set_as (generic& r, const generic& x) { 00574 r= x; 00575 } 00576 00577 #undef TMPL 00578 #undef Acc 00579 } // namespace mmx 00580 #endif // __GENERIC_HPP