basix_doc 0.1
/Users/mourrain/Devel/mmx/basix/src/generic.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : generic.cpp
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 #include <basix/compound.hpp>
00014 #include <basix/evaluator.hpp>
00015 #include <basix/vector.hpp>
00016 #include <basix/tuple.hpp>
00017 #include <basix/mmx_syntax.hpp>
00018 #include <basix/memoize.hpp>
00019 #include <basix/string.hpp>
00020 #include <basix/table.hpp>
00021 #include <basix/routine.hpp>
00022 namespace mmx {
00023 
00024 /******************************************************************************
00025 * Automatic addition of new types
00026 ******************************************************************************/
00027 
00028 nat type_id (const generic& name);
00029 
00030 nat
00031 new_type_id () {
00032   static nat counter= 2;
00033   ASSERT (counter < 65000, "too many types");
00034   return counter++;
00035 }
00036 
00037 nat
00038 new_type_id (const char* s) {
00039   static table<nat, string> t;
00040   if (!contains (t, s)) {
00041     nat id= new_type_id ();
00042     inside_set (t, s, id);
00043     return id;
00044   }
00045   return t[s];
00046 }
00047 
00048 nat type_information<generic>::id= 0;
00049 // type identifier 1 for unknown type
00050 
00051 /******************************************************************************
00052 * Binary input/output
00053 ******************************************************************************/
00054 
00055 static table<generic,string> binary_readers;
00056 
00057 generic gen_vec () {
00058   return as<generic> (vec<generic> ()); }
00059 generic gen_vec (const generic& g1) {
00060   return as<generic> (vec<generic> (g1)); }
00061 generic gen_vec (const generic& g1, const generic& g2) {
00062   return as<generic> (vec<generic> (g1, g2)); }
00063 generic gen_vec (const generic& g1, const generic& g2, const generic& g3) {
00064   return as<generic> (vec<generic> (g1, g2, g3)); }
00065 generic vector_size (const generic& g) {
00066   if (!is<vector<generic> > (g)) return 0;
00067   else return N(as<vector<generic> > (g)); }
00068 generic vector_access (const generic& g, nat i) {
00069   return as<vector<generic> > (g) [i]; }
00070 
00071 void
00072 attach_generic_binary_assembler (const generic& tp, unary_generic r) {
00073   if (!is<string> (tp) || as<string> (tp) != "?")
00074     current_ev->set (gen ("assembler", tp),
00075                      as<generic> (unary_routine ("binary_assembler", r)));
00076 }
00077 
00078 generic
00079 binary_type_generic (const generic& g) {
00080   return g->binary_type ();
00081 }
00082 
00083 generic
00084 binary_disassemble_generic (const generic& g) {
00085   return g->binary_disassemble ();
00086 }
00087 
00088 generic
00089 binary_assemble_generic (const generic& tp, const generic& val) {
00090   if (!current_ev->contains (gen ("assembler", tp)))
00091     mmerr << "val= " << val << "\n";
00092   ASSERT (current_ev->contains (gen ("assembler", tp)),
00093           "unsupported type for generic binary assemble");
00094   routine r= as<routine> (current_ev->get (gen ("assembler", tp)));
00095   return r->apply (val);
00096 }
00097 
00098 void
00099 attach_generic_binary_reader (const string& s, unary_generic r) {
00100   if (s != "?")
00101     binary_readers[s]= as<generic> (unary_routine ("binary_reader", r));
00102 }
00103 
00104 void
00105 binary_write_generic (const port& out, const generic& g) {
00106   g->binary_write (out);
00107 }
00108 
00109 generic
00110 binary_read_generic (const port& in) {
00111   string name;
00112   char buf[1];
00113   while (true) {
00114     mmx::read (in, buf, 1);
00115     if (buf[0] == ':') break;
00116     name << buf[0];
00117   }
00118   if (!binary_readers->contains (name))
00119     mmerr << "name= " << name << "\n";
00120   ASSERT (binary_readers->contains (name),
00121           "unsupported type for generic binary read");
00122   routine r= as<routine> (binary_readers[name]);
00123   return r->apply (as<generic> (in));
00124 }
00125 
00126 /******************************************************************************
00127 * Different copying routines and printing generic expressions
00128 ******************************************************************************/
00129 
00130 generic
00131 duplicate (const generic& x1) {
00132   return x1->duplicate_me ();
00133 }
00134 
00135 syntactic
00136 flatten (const generic& g) {
00137   MEMOIZE_UNARY (std_memoizer,syntactic,generic,flatten,g,
00138                  g->expression());
00139 }
00140 
00141 /******************************************************************************
00142 * N-ary operations
00143 ******************************************************************************/
00144 
00145 generic
00146 void_value () {
00147   static generic val= as<generic> (tuple<generic> (gen (GEN_TUPLE)));
00148   return val;
00149 }
00150 
00151 void
00152 xgen_sub (vector<generic>& v, const generic& g) {
00153   if (is<compound> (g) && N(g) >= 1 && exact_eq (g[0], GEN_COMMA)) {
00154     int i, n= N(g);
00155     for (i=1; i<n; i++)
00156       xgen_sub (v, g[i]);
00157   }
00158   else v << g;
00159 }
00160 
00161 generic
00162 xgen (const generic& f, const generic& args) {
00163   vector<generic> v;
00164   v << f;
00165   xgen_sub (v, args);
00166   return vector_to_compound (v);
00167 }
00168 
00169 generic comma () {
00170   return gen (generic (GEN_COMMA)); }
00171 generic comma (const generic& g1, const generic& g2) {
00172   return gen (GEN_COMMA, g1, g2); }
00173 generic xaccess (const generic& f, const generic& args) {
00174   return xgen (GEN_ACCESS, comma (f, args)); }
00175 generic xtuple (const generic& g) {
00176   return xgen (GEN_TUPLE, g); }
00177 generic xsqtuple (const generic& g) {
00178   return xgen (GEN_SQTUPLE, g); }
00179 generic xrow (const generic& g) {
00180   return xgen (GEN_ROW, g); }
00181 generic access (const generic& g, const generic& x) {
00182   return gen (GEN_ACCESS, g, x); }
00183 generic access (const generic& g, const generic& x, const generic& y) {
00184   return gen (GEN_ACCESS, g, x, y); }
00185 generic access (const generic& g, const vector<generic>& args) {
00186   vector<generic> v= vec<generic> (generic (GEN_ACCESS), g);
00187   return vector_to_compound (append (v, args)); }
00188 
00189 /******************************************************************************
00190 * Evaluation
00191 ******************************************************************************/
00192 
00193 generic
00194 construct (const int& i) {
00195   return current_ev->construct (as<generic> (i));
00196 }
00197 
00198 generic
00199 construct (const nat& i) {
00200   return current_ev->construct (as<generic> ((int) i));
00201 }
00202 
00203 generic
00204 construct (const double& x) {
00205   return current_ev->construct (as<generic> (x));
00206 }
00207 
00208 generic
00209 construct (const float& x) {
00210   return current_ev->construct (as<generic> ((double) x));
00211 }
00212 
00213 generic
00214 construct (const generic& x) {
00215   return current_ev->construct (x);
00216 }
00217 
00218 generic
00219 eval (const generic& x) {
00220   return current_ev->eval (x);
00221 }
00222 
00223 /******************************************************************************
00224 * Constructors
00225 ******************************************************************************/
00226 
00227 generic::generic (int i):
00228   rep (new generic_concrete_rep<int> (i))
00229 {
00230   if (inside (current_ev) != NULL)
00231     // FIXME: fixes initialization bug in algebramix when --enable-embedded
00232     *this= current_ev->construct (*this);
00233 }
00234 
00235 generic::generic (nat i):
00236   rep (new generic_concrete_rep<int> ((int) i))
00237 {
00238   ASSERT (((int) i) >= 0, "nat does not fit inside an int");
00239   if (inside (current_ev) != NULL)
00240     // FIXME: fixes initialization bug in algebramix when --enable-embedded
00241     *this= current_ev->construct (*this);
00242 }
00243 
00244 /******************************************************************************
00245 * Constants
00246 ******************************************************************************/
00247 
00248 void set_smallest (generic& x) { x= GEN_SMALLEST; }
00249 void set_largest (generic& x) { x= GEN_LARGEST; }
00250 void set_accuracy (generic& x) { x= GEN_ACCURACY; }
00251 void set_pi (generic& x) { x= GEN_PI; }
00252 void set_log2 (generic& x) { x= log (generic (2)); }
00253 void set_euler (generic& x) { x= GEN_EULER; }
00254 void set_catalan (generic& x) { x= GEN_CATALAN; }
00255 void set_imaginary (generic& x) { x= GEN_I; }
00256 void set_nan (generic& x) { x= GEN_NAN; }
00257 void set_fuzz (generic& x) { x= GEN_FUZZ; }
00258 void set_infinity (generic& x) { x= GEN_INFINITY; }
00259 void set_maximal (generic& x) { x= GEN_INFINITY; }
00260 void set_minimal (generic& x) { x= -GEN_INFINITY; }
00261 
00262 /******************************************************************************
00263 * Function application
00264 ******************************************************************************/
00265 
00266 generic apply (const generic& g, const generic& x) {
00267   return current_ev->apply (g, x); }
00268 generic apply (const generic& g, const generic& x, const generic& y) {
00269   return current_ev->apply (g, x, y); }
00270 generic apply (const generic& g, const generic& x,
00271                const generic& y, const generic& z) {
00272   return current_ev->apply (g, vec (x, y, z)); }
00273 generic apply (const generic& g, const vector<generic>& args) {
00274   return current_ev->apply (g, args); }
00275 
00276 /******************************************************************************
00277 * Accelerator management
00278 ******************************************************************************/
00279 
00280 nat generic_rep::acc_id () const { return -1; }
00281 routine* generic_rep::acc_construct (nat id) const { return NULL; }
00282 routine* generic_rep::acc_apply (nat code) const { return NULL; }
00283 
00284 generic
00285 convert (const generic& from, const generic& to) {
00286   if (same_type (from, to)) return from;
00287   routine* cv= to->acc_construct (from->acc_id ());
00288   if (cv != NULL && !is_nil (*cv)) return (*cv) (from);
00289   return current_ev->apply (GEN_CONVERT, from, type_name (to));
00290 }
00291 
00292 inline bool as_bool (const generic& g) {
00293   return is<bool> (g) && as<bool> (g); }
00294 
00295 #define ACC_UNARY(code,x1)                              \
00296   routine* r= x1->acc_apply (code);                     \
00297   if (r != NULL && !is_nil (*r)) return (*r) (x1);
00298 
00299 #define ACC_BINARY(code,x1,x2)                          \
00300   if (same_type (x1, x2)) {                             \
00301     routine* r= x1->acc_apply (code);                   \
00302     if (r != NULL && !is_nil (*r))                      \
00303       return (*r) (x1, x2);                             \
00304   }                                                     \
00305   else {                                                \
00306     routine* cv= x1->acc_construct (x2->acc_id ());     \
00307     if (cv != NULL && !is_nil (*cv)) {                  \
00308       routine* r= x1->acc_apply (code);                 \
00309       if (r != NULL && !is_nil (*r))                    \
00310         return (*r) (x1, (*cv) (x2));                   \
00311     }                                                   \
00312     cv= x2->acc_construct (x1->acc_id ());              \
00313     if (cv != NULL && !is_nil (*cv)) {                  \
00314       routine* r= x2->acc_apply (code);                 \
00315       if (r != NULL && !is_nil (*r))                    \
00316         return (*r) ((*cv) (x1), x2);                   \
00317     }                                                   \
00318   }
00319 
00320 #define ACC_TEST(code,x1,x2)                            \
00321   if (same_type (x1, x2)) {                             \
00322     routine* r= x1->acc_apply (code);                   \
00323     if (r != NULL && !is_nil (*r))                      \
00324       return as_bool ((*r) (x1, x2));                   \
00325   }                                                     \
00326   else {                                                \
00327     routine* cv= x1->acc_construct (x2->acc_id ());     \
00328     if (cv != NULL && !is_nil (*cv)) {                  \
00329       routine* r= x1->acc_apply (code);                 \
00330       if (r != NULL && !is_nil (*r))                    \
00331         return as_bool ((*r) (x1, (*cv) (x2)));         \
00332     }                                                   \
00333     cv= x2->acc_construct (x1->acc_id ());              \
00334     if (cv != NULL && !is_nil (*cv)) {                  \
00335       routine* r= x2->acc_apply (code);                 \
00336       if (r != NULL && !is_nil (*r))                    \
00337         return as_bool ((*r) ((*cv) (x1), x2));         \
00338     }                                                   \
00339   }
00340 
00341 #define ACC_BINARY_SCALAR(code,x1,x2)                   \
00342   routine* r= x1->acc_apply (code);                     \
00343   if (r != NULL && !is_nil (*r)) return (*r) (x1, x2);
00344 
00345 void
00346 fill_out (vec_routine& v, nat& n, nat i, const routine& r) {
00347   if (i >= n) {
00348     nat      new_n= (nat) (1.2 * ((double) (i + 2)));
00349     routine* new_v= mmx_new<routine> (new_n, routine ());
00350     for (nat j=0; j<n; j++) new_v[j]= v[j];
00351     if (v != NULL) mmx_delete<routine> (v, n);
00352     n= new_n;
00353     v= new_v;
00354   }
00355   v[i]= r;
00356 }
00357 
00358 /******************************************************************************
00359 * Basic arithmetic
00360 ******************************************************************************/
00361 
00362 generic
00363 operator - (const generic& x1) {
00364   ACC_UNARY (ACC_NEGATE, x1);
00365   return current_ev->apply (GEN_MINUS, x1);
00366 }
00367 
00368 generic
00369 square (const generic& x1) {
00370   ACC_UNARY (ACC_SQUARE, x1);
00371   return current_ev->apply (GEN_TIMES, x1, x1);
00372 }
00373 
00374 generic
00375 invert (const generic& x1) {
00376   ACC_UNARY (ACC_INVERT, x1);
00377   return current_ev->apply (GEN_OVER, 1, x1);
00378 }
00379 
00380 generic
00381 operator + (const generic& x1, const generic& x2) {
00382   ACC_BINARY (ACC_ADD, x1, x2);
00383   return current_ev->apply (GEN_PLUS, x1, x2);
00384 }
00385 
00386 generic
00387 operator - (const generic& x1, const generic& x2) {
00388   ACC_BINARY (ACC_SUB, x1, x2);
00389   return current_ev->apply (GEN_MINUS, x1, x2);
00390 }
00391 
00392 generic
00393 operator * (const generic& x1, const generic& x2) {
00394   ACC_BINARY (ACC_MUL, x1, x2);
00395   return current_ev->apply (GEN_TIMES, x1, x2);
00396 }
00397 
00398 generic
00399 operator / (const generic& x1, const generic& x2) {
00400   ACC_BINARY (ACC_DIV, x1, x2);
00401   return current_ev->apply (GEN_OVER, x1, x2);
00402 }
00403 
00404 generic operator + (const generic& x1, const int& x2) {
00405   return x1 + generic (x2); }
00406 generic operator - (const generic& x1, const int& x2) {
00407   return x1 - generic (x2); }
00408 generic operator * (const generic& x1, const int& x2) {
00409   return x1 * generic (x2); }
00410 generic operator / (const generic& x1, const int& x2) {
00411   return x1 / generic (x2); }
00412 generic operator + (const int& x1, const generic& x2) {
00413   return generic (x1) + x2; }
00414 generic operator - (const int& x1, const generic& x2) {
00415   return generic (x1) - x2; }
00416 generic operator * (const int& x1, const generic& x2) {
00417   return generic (x1) * x2; }
00418 generic operator / (const int& x1, const generic& x2) {
00419   return generic (x1) / x2; }
00420 
00421 /******************************************************************************
00422 * Elementary functions
00423 ******************************************************************************/
00424 
00425 generic
00426 sqrt (const generic& x1) {
00427   ACC_UNARY (ACC_SQRT, x1);
00428   return current_ev->apply (GEN_SQRT, x1);
00429 }
00430 
00431 generic
00432 exp (const generic& x1) {
00433   ACC_UNARY (ACC_EXP, x1);
00434   return current_ev->apply (GEN_EXP, x1);
00435 }
00436 
00437 generic
00438 log (const generic& x1) {
00439   ACC_UNARY (ACC_LOG, x1);
00440   return current_ev->apply (GEN_LOG, x1);
00441 }
00442 
00443 generic
00444 cos (const generic& x1) {
00445   ACC_UNARY (ACC_COS, x1);
00446   return current_ev->apply (GEN_COS, x1);
00447 }
00448 
00449 generic
00450 sin (const generic& x1) {
00451   ACC_UNARY (ACC_SIN, x1);
00452   return current_ev->apply (GEN_SIN, x1);
00453 }
00454 
00455 generic
00456 tan (const generic& x1) {
00457   ACC_UNARY (ACC_TAN, x1);
00458   return current_ev->apply (GEN_TAN, x1);
00459 }
00460 
00461 generic
00462 acos (const generic& x1) {
00463   ACC_UNARY (ACC_ACOS, x1);
00464   return current_ev->apply (GEN_ARCCOS, x1);
00465 }
00466 
00467 generic
00468 asin (const generic& x1) {
00469   ACC_UNARY (ACC_ASIN, x1);
00470   return current_ev->apply (GEN_ARCSIN, x1);
00471 }
00472 
00473 generic
00474 atan (const generic& x1) {
00475   ACC_UNARY (ACC_ATAN, x1);
00476   return current_ev->apply (GEN_ARCTAN, x1);
00477 }
00478 
00479 generic
00480 cosh (const generic& x1) {
00481   ACC_UNARY (ACC_COSH, x1);
00482   return (exp (x1) + exp (-x1)) / 2;
00483 }
00484 
00485 generic
00486 sinh (const generic& x1) {
00487   ACC_UNARY (ACC_SINH, x1);
00488   return (exp (x1) - exp (-x1)) / 2;
00489 }
00490 
00491 generic
00492 tanh (const generic& x1) {
00493   ACC_UNARY (ACC_TANH, x1);
00494   return (exp (x1) - exp (-x1)) / (exp (x1) + exp (-x1));
00495 }
00496 
00497 generic
00498 acosh (const generic& x1) {
00499   ACC_UNARY (ACC_ACOSH, x1);
00500   return log (x1 + sqrt (square (x1) - 1));
00501 }
00502 
00503 generic
00504 asinh (const generic& x1) {
00505   ACC_UNARY (ACC_ASINH, x1);
00506   return log (x1 + sqrt (square (x1) + 1));
00507 }
00508 
00509 generic
00510 atanh (const generic& x1) {
00511   ACC_UNARY (ACC_ATANH, x1);
00512   return log ((1 + x1) / (1 - x1)) / 2;
00513 }
00514 
00515 generic
00516 hypot (const generic& x, const generic& y) {
00517   ACC_BINARY (ACC_HYPOT, x, y);
00518   return sqrt (square (x) + square (y));
00519 }
00520 
00521 generic
00522 atan2 (const generic& x, const generic& y) {
00523   ACC_BINARY (ACC_ATAN2, x, y);
00524   if (x > 0) return atan (y/x);
00525   else if (y == 0)
00526     return x == 0? generic (0): generic (-4) * atan (generic (1));
00527   else if (x == 0)
00528     return generic (2 * sign (y)) * atan (generic (1));
00529   else return sign (y) * (4 * atan (generic (1)) - atan (abs (y/x)));
00530 }
00531 
00532 generic
00533 pow (const generic& x1, const generic& x2) {
00534   ACC_BINARY (ACC_POW, x1, x2);
00535   return current_ev->apply (GEN_POWER, x1, x2);
00536 }
00537 
00538 generic pow (const generic& x1, const int& x2) {
00539   return pow (x1, generic (x2)); }
00540 generic pow (const int& x1, const generic& x2) {
00541   return pow (generic (x1), x2); }
00542 generic pow (const generic& x1, const nat& x2) {
00543   return pow (x1, generic (x2)); }
00544 generic pow (const nat& x1, const generic& x2) {
00545   return pow (generic (x1), x2); }
00546 generic trig (const generic& x1) {
00547   return xsqtuple (comma (cos (x1), sin (x1))); }
00548 
00549 /******************************************************************************
00550 * Predicates
00551 ******************************************************************************/
00552 
00553 bool
00554 operator == (const generic& x1, const generic& x2) {
00555   if (same_type (x1, x2))
00556     return x1->is_equal (x2);
00557   else {
00558     routine* cv= x1->acc_construct (x2->acc_id ());
00559     if (cv != NULL && !is_nil (*cv))
00560       return x1 -> is_equal ((*cv) (x2));
00561     cv= x2->acc_construct (x1->acc_id ());
00562     if (cv != NULL && !is_nil (*cv))
00563       return (*cv) (x1) -> is_equal (x2);
00564   }
00565   return as_bool (current_ev->apply (GEN_EQUAL, x1, x2));
00566 }
00567 
00568 bool
00569 operator == (const generic& x1, const int& x2) {
00570   if (is<int> (x1)) return as<int> (x1) == x2;
00571   else {
00572     routine* cv= x1->acc_construct (accelerator<int>::id);
00573     if (cv != NULL && !is_nil (*cv))
00574       return x1 -> is_equal ((*cv) (as<generic> (x2)));
00575   }
00576   return x1 == generic (x2);
00577 }
00578 
00579 bool operator != (const generic& x1, const generic& x2) { return !(x1 == x2); }
00580 bool operator != (const generic& x1, const int& x2) { return !(x1 == x2); }
00581 bool operator == (const int& x1, const generic& x2) { return x2 == x1; }
00582 bool operator != (const int& x1, const generic& x2) { return x2 != x1; }
00583 
00584 bool
00585 exact_eq (const generic& x1, const generic& x2) {
00586   if (same_type (x1, x2))
00587     return x1->is_exact_eq (x2);
00588   else {
00589     routine* cv= x1->acc_construct (x2->acc_id ());
00590     if (cv != NULL && !is_nil (*cv))
00591       return x1 -> is_exact_eq ((*cv) (x2));
00592     cv= x2->acc_construct (x1->acc_id ());
00593     if (cv != NULL && !is_nil (*cv))
00594       return (*cv) (x1) -> is_exact_eq (x2);
00595   }
00596   return false;
00597 }
00598 
00599 bool
00600 exact_eq (const generic& x1, const int& x2) {
00601   if (is<int> (x1)) return as<int> (x1) == x2;
00602   else {
00603     routine* cv= x1->acc_construct (accelerator<int>::id);
00604     if (cv != NULL && !is_nil (*cv))
00605       return x1 -> is_exact_eq ((*cv) (as<generic> (x2)));
00606   }
00607   return false;
00608 }
00609 
00610 bool exact_neq (const generic& x1, const generic& x2) {
00611   return !exact_eq (x1, x2); }
00612 bool exact_neq (const generic& x1, const int& x2) {
00613   return !exact_eq (x1, x2); }
00614 bool exact_eq (const int& x1, const generic& x2) {
00615   return exact_eq (x2, x1); }
00616 bool exact_neq (const int& x1, const generic& x2) {
00617   return exact_neq (x2, x1); }
00618 
00619 /******************************************************************************
00620 * Ordering
00621 ******************************************************************************/
00622 
00623 bool
00624 operator < (const generic& x1, const generic& x2) {
00625   ACC_TEST (ACC_LESS, x1, x2);
00626   return as_bool (current_ev->apply (GEN_LESS, x1, x2));
00627 }
00628 
00629 bool
00630 operator <= (const generic& x1, const generic& x2) {
00631   ACC_TEST (ACC_LESSEQ, x1, x2);
00632   return as_bool (current_ev->apply (GEN_LESSEQ, x1, x2));
00633 }
00634 
00635 bool
00636 operator > (const generic& x1, const generic& x2) {
00637   ACC_TEST (ACC_GTR, x1, x2);
00638   return as_bool (current_ev->apply (GEN_GTR, x1, x2));
00639 }
00640 
00641 bool
00642 operator >= (const generic& x1, const generic& x2) {
00643   ACC_TEST (ACC_GTREQ, x1, x2);
00644   return as_bool (current_ev->apply (GEN_GTREQ, x1, x2));
00645 }
00646 
00647 bool operator < (const generic& x1, const int& x2) {
00648   return x1 < generic (x2); }
00649 bool operator <= (const generic& x1, const int& x2) {
00650   return x1 <= generic (x2); }
00651 bool operator > (const generic& x1, const int& x2) {
00652   return x1 > generic (x2); }
00653 bool operator >= (const generic& x1, const int& x2) {
00654   return x1 >= generic (x2); }
00655 bool operator < (const int& x1, const generic& x2) {
00656   return generic (x1) < x2; }
00657 bool operator <= (const int& x1, const generic& x2) {
00658   return generic (x1) <= x2; }
00659 bool operator > (const int& x1, const generic& x2) {
00660   return generic (x1) > x2; }
00661 bool operator >= (const int& x1, const generic& x2) {
00662   return generic (x1) >= x2; }
00663 
00664 /******************************************************************************
00665 * Calculus
00666 ******************************************************************************/
00667 
00668 generic
00669 derive (const generic& x1) {
00670   ACC_UNARY (ACC_DERIVE, x1);
00671   return current_ev->apply (GEN_CACHED_DERIVE, x1);
00672 }
00673 
00674 generic
00675 integrate (const generic& x1) {
00676   ACC_UNARY (ACC_INTEGRATE, x1);
00677   return current_ev->apply (GEN_INTEGRATE, x1);
00678 }
00679 
00680 generic
00681 derive (const generic& x1, const generic& v) {
00682   ACC_BINARY_SCALAR (ACC_DERIVE_WRT, x1, v);
00683   MEMOIZE_BINARY (std_memoizer,generic,generic,generic,derive,x1,v,
00684                   current_ev->apply (GEN_CACHED_DERIVE, x1, v));
00685 }
00686 
00687 generic
00688 integrate (const generic& x1, const generic& v) {
00689   ACC_BINARY_SCALAR (ACC_DERIVE_WRT, x1, v);
00690   return current_ev->apply (GEN_INTEGRATE, x1, v);
00691 }
00692 
00693 generic prime (const generic& x1) {
00694   return current_ev->apply ("'", x1); }
00695 generic substitute (const generic& x1, const generic& x2) {
00696   return current_ev->apply (GEN_SUBSTITUTE, x1, x2); }
00697 generic compose (const generic& x1, const generic& x2) {
00698   return current_ev->apply (GEN_COMPOSE, x1, x2); }
00699 generic dilate (const generic& x1, const generic& x2) {
00700   return current_ev->apply ("dilate", x1, x2); }
00701 generic solve (const generic& x1, const generic& x2) {
00702   return current_ev->apply (GEN_SOLVE, x1, x2); }
00703 
00704 /******************************************************************************
00705 * Further arithmetic
00706 ******************************************************************************/
00707 
00708 generic quo (const generic& x1, const generic& x2) {
00709   return current_ev->apply (GEN_DIV, x1, x2); }
00710 generic rem (const generic& x1, const generic& x2) {
00711   return current_ev->apply (GEN_MOD, x1, x2); }
00712 generic numerator (const generic& x) {
00713   return current_ev->apply (GEN_NUMERATOR, x); }
00714 generic denominator (const generic& x) {
00715   return current_ev->apply (GEN_DENOMINATOR, x); }
00716 generic gcd (const generic& x1, const generic& x2) {
00717   return current_ev->apply (GEN_GCD, x1, x2); }
00718 generic lcm (const generic& x1, const generic& x2) {
00719   return current_ev->apply (GEN_LCM, x1, x2); }
00720 
00721 /******************************************************************************
00722 * Real and complex structures
00723 ******************************************************************************/
00724 
00725 generic min (const generic& x1, const generic& x2) {
00726   return current_ev->apply (GEN_MIN, x1, x2); }
00727 generic max (const generic& x1, const generic& x2) {
00728   return current_ev->apply (GEN_MAX, x1, x2); }
00729 generic abs (const generic& x1) {
00730   return current_ev->apply (GEN_ABS, x1); }
00731 generic arg (const generic& x1) {
00732   return current_ev->apply (GEN_ARG, x1); }
00733 generic Re (const generic& x1) {
00734   return current_ev->apply (GEN_RE, x1); }
00735 generic Im (const generic& x1) {
00736   return current_ev->apply (GEN_IM, x1); }
00737 generic conj (const generic& x1) {
00738   return current_ev->apply (GEN_CONJ, x1); }
00739 generic gaussian (const generic& x1, const generic& x2) {
00740   return x1 + x2 * Imaginary (generic); }
00741 generic polar (const generic& x1, const generic& x2) {
00742   return x1 * exp (x2 * Imaginary (generic)); }
00743 
00744 /******************************************************************************
00745 * Rounding towards nearest integers
00746 ******************************************************************************/
00747 
00748 generic floor (const generic& x) {
00749   return current_ev->apply (GEN_FLOOR, x); }
00750 generic trunc (const generic& x) {
00751   return current_ev->apply (GEN_TRUNC, x); }
00752 generic ceil (const generic& x) {
00753   return current_ev->apply (GEN_CEIL, x); }
00754 generic round (const generic& x) {
00755   return current_ev->apply (GEN_ROUND, x); }
00756 
00757 /******************************************************************************
00758 * Miscellaneous routines for numerics
00759 ******************************************************************************/
00760 
00761 generic change_precision (const generic& x, xnat p) {
00762   return current_ev->apply (GEN_CHANGE_PRECISION, x, as<generic> ((int) p)); }
00763 xnat precision (const generic& x) {
00764   generic r= current_ev->apply (GEN_PRECISION, x);
00765   ASSERT (is<int> (r), "Int return value expected");
00766   return as<int> (r); }
00767 generic next_above (const generic& x) {
00768   return current_ev->apply (GEN_NEXT_ABOVE, x); }
00769 generic next_below (const generic& x) {
00770   return current_ev->apply (GEN_NEXT_BELOW, x); }
00771 generic rounding_error (const generic& x) {
00772   return current_ev->apply (GEN_ROUNDING_ERROR, x); }
00773 generic additive_error (const generic& x) {
00774   return current_ev->apply (GEN_ADDITIVE_ERROR, x); }
00775 generic multiplicative_error (const generic& x) {
00776   return current_ev->apply (GEN_MULTIPLICATIVE_ERROR, x); }
00777 generic elementary_error (const generic& x) {
00778   return current_ev->apply (GEN_ELEMENTARY_ERROR, x); }
00779 
00780 xint exponent (const generic& x) {
00781   generic r= current_ev->apply (GEN_EXPONENT, x);
00782   ASSERT (is<int> (r), "Int return value expected");
00783   return as<int> (r); }
00784 double magnitude (const generic& x) {
00785   generic r= current_ev->apply (GEN_MAGNITUDE, x);
00786   ASSERT (is<double> (r), "Double return value expected");
00787   return as<double> (r); }
00788 generic incexp2 (const generic& x1, const xint& x2) {
00789   return current_ev->apply ("increase_exponent", x1, as<generic> ((int) x2)); }
00790 generic decexp2 (const generic& x1, const xint& x2) {
00791   return current_ev->apply ("decrease_exponent", x1, as<generic> ((int) x2)); }
00792 generic operator << (const generic& x1, const generic& x2) {
00793   return current_ev->apply (GEN_LESSLESS, x1, x2); }
00794 generic operator >> (const generic& x1, const generic& x2) {
00795   return current_ev->apply (GEN_GTRGTR, x1, x2); }
00796 
00797 /******************************************************************************
00798 * Analytic continuation
00799 ******************************************************************************/
00800 
00801 generic sqrt_init (const generic& x1, const generic& x2) {
00802   return current_ev->apply ("sqrt_init", x1, x2); }
00803 generic log_init (const generic& x1, const generic& x2) {
00804   return current_ev->apply ("log_init", x1, x2); }
00805 generic acos_init (const generic& x1, const generic& x2) {
00806   return current_ev->apply ("acos_init", x1, x2); }
00807 generic asin_init (const generic& x1, const generic& x2) {
00808   return current_ev->apply ("asin_init", x1, x2); }
00809 generic atan_init (const generic& x1, const generic& x2) {
00810   return current_ev->apply ("atan_init", x1, x2); }
00811 generic integrate_init (const generic& x1, const generic& x2) {
00812   return current_ev->apply ("integrate_init", x1, x2); }
00813 generic solve_lde_init (const generic& x1, const generic& x2) {
00814   return current_ev->apply ("solve_lde_init", x1, x2); }
00815 
00816 /******************************************************************************
00817 * Ball arithmetic
00818 ******************************************************************************/
00819 
00820 generic center (const generic& x1) {
00821   return current_ev->apply ("center", x1); }  
00822 generic radius (const generic& x1) {
00823   return current_ev->apply ("radius", x1); }
00824 generic sharpen (const generic& x1) {
00825   return current_ev->apply ("sharpen", x1); }
00826 generic blur (const generic& x1, const generic& x2) {
00827   return current_ev->apply ("blur", x1, x2); }
00828 
00829 /******************************************************************************
00830 * Miscellaneous
00831 ******************************************************************************/
00832 
00833 generic lshiftz (const generic& x1, const generic& x2) {
00834   return current_ev->apply ("lshiftz", x1, x2); }
00835 generic rshiftz (const generic& x1, const generic& x2) {
00836   return current_ev->apply ("rshiftz", x1, x2); }
00837 generic operator | (const generic& x1, const generic& x2) {
00838   return current_ev->apply (GEN_OR, x1, x2); }
00839 generic operator & (const generic& x1, const generic& x2) {
00840   return current_ev->apply (GEN_AND, x1, x2); }
00841 generic lres (const generic& x1, const generic& x2) {
00842   return current_ev->apply ("lres", x1, x2); }
00843 generic rres (const generic& x1, const generic& x2) {
00844   return current_ev->apply ("rres", x1, x2); }
00845 generic uniform (const generic& x1, const generic& x2) {
00846   return current_ev->apply ("uniform", x1, x2); }
00847 generic specialize (const generic& x1, const generic& x2) {
00848   return current_ev->apply ("specialize", x1, x2); }
00849 
00850 } // namespace mmx
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines