00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
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
00050
00051
00052
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
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
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
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
00225
00226
00227 generic::generic (int i):
00228 rep (new generic_concrete_rep<int> (i))
00229 {
00230 if (inside (current_ev) != NULL)
00231
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
00241 *this= current_ev->construct (*this);
00242 }
00243
00244
00245
00246
00247
00248 void set_default (generic& x) { x= as<generic> (false); }
00249 void set_smallest (generic& x) { x= GEN_SMALLEST; }
00250 void set_largest (generic& x) { x= GEN_LARGEST; }
00251 void set_accuracy (generic& x) { x= GEN_ACCURACY; }
00252 void set_pi (generic& x) { x= GEN_PI; }
00253 void set_log2 (generic& x) { x= log (generic (2)); }
00254 void set_euler (generic& x) { x= GEN_EULER; }
00255 void set_catalan (generic& x) { x= GEN_CATALAN; }
00256 void set_imaginary (generic& x) { x= GEN_I; }
00257 void set_nan (generic& x) { x= GEN_NAN; }
00258 void set_fuzz (generic& x) { x= GEN_FUZZ; }
00259 void set_infinity (generic& x) { x= GEN_INFINITY; }
00260 void set_maximal (generic& x) { x= GEN_INFINITY; }
00261 void set_minimal (generic& x) { x= -GEN_INFINITY; }
00262
00263
00264
00265
00266
00267 generic apply (const generic& g, const generic& x) {
00268 return current_ev->apply (g, x); }
00269 generic apply (const generic& g, const generic& x, const generic& y) {
00270 return current_ev->apply (g, x, y); }
00271 generic apply (const generic& g, const generic& x,
00272 const generic& y, const generic& z) {
00273 return current_ev->apply (g, vec (x, y, z)); }
00274 generic apply (const generic& g, const vector<generic>& args) {
00275 return current_ev->apply (g, args); }
00276
00277
00278
00279
00280
00281 nat generic_rep::acc_id () const { return -1; }
00282 routine* generic_rep::acc_construct (nat id) const { return NULL; }
00283 routine* generic_rep::acc_apply (nat code) const { return NULL; }
00284
00285 generic
00286 convert (const generic& from, const generic& to) {
00287 if (same_type (from, to)) return from;
00288 routine* cv= to->acc_construct (from->acc_id ());
00289 if (cv != NULL && !is_nil (*cv)) return (*cv) (from);
00290 return current_ev->apply (GEN_CONVERT, from, type_name (to));
00291 }
00292
00293 inline bool as_bool (const generic& g) {
00294 return is<bool> (g) && as<bool> (g); }
00295
00296 #define ACC_UNARY(code,x1) \
00297 routine* r= x1->acc_apply (code); \
00298 if (r != NULL && !is_nil (*r)) return (*r) (x1);
00299
00300 #define ACC_BINARY(code,x1,x2) \
00301 if (same_type (x1, x2)) { \
00302 routine* r= x1->acc_apply (code); \
00303 if (r != NULL && !is_nil (*r)) \
00304 return (*r) (x1, x2); \
00305 } \
00306 else { \
00307 routine* cv= x1->acc_construct (x2->acc_id ()); \
00308 if (cv != NULL && !is_nil (*cv)) { \
00309 routine* r= x1->acc_apply (code); \
00310 if (r != NULL && !is_nil (*r)) \
00311 return (*r) (x1, (*cv) (x2)); \
00312 } \
00313 cv= x2->acc_construct (x1->acc_id ()); \
00314 if (cv != NULL && !is_nil (*cv)) { \
00315 routine* r= x2->acc_apply (code); \
00316 if (r != NULL && !is_nil (*r)) \
00317 return (*r) ((*cv) (x1), x2); \
00318 } \
00319 }
00320
00321 #define ACC_TEST(code,x1,x2) \
00322 if (same_type (x1, x2)) { \
00323 routine* r= x1->acc_apply (code); \
00324 if (r != NULL && !is_nil (*r)) \
00325 return as_bool ((*r) (x1, x2)); \
00326 } \
00327 else { \
00328 routine* cv= x1->acc_construct (x2->acc_id ()); \
00329 if (cv != NULL && !is_nil (*cv)) { \
00330 routine* r= x1->acc_apply (code); \
00331 if (r != NULL && !is_nil (*r)) \
00332 return as_bool ((*r) (x1, (*cv) (x2))); \
00333 } \
00334 cv= x2->acc_construct (x1->acc_id ()); \
00335 if (cv != NULL && !is_nil (*cv)) { \
00336 routine* r= x2->acc_apply (code); \
00337 if (r != NULL && !is_nil (*r)) \
00338 return as_bool ((*r) ((*cv) (x1), x2)); \
00339 } \
00340 }
00341
00342 #define ACC_BINARY_SCALAR(code,x1,x2) \
00343 routine* r= x1->acc_apply (code); \
00344 if (r != NULL && !is_nil (*r)) return (*r) (x1, x2);
00345
00346 void
00347 fill_out (vec_routine& v, nat& n, nat i, const routine& r) {
00348 if (i >= n) {
00349 nat new_n= (nat) (1.2 * ((double) (i + 2)));
00350 routine* new_v= mmx_new<routine> (new_n, routine ());
00351 for (nat j=0; j<n; j++) new_v[j]= v[j];
00352 if (v != NULL) mmx_delete<routine> (v, n);
00353 n= new_n;
00354 v= new_v;
00355 }
00356 v[i]= r;
00357 }
00358
00359
00360
00361
00362
00363 generic
00364 operator - (const generic& x1) {
00365 ACC_UNARY (ACC_NEGATE, x1);
00366 return current_ev->apply (GEN_MINUS, x1);
00367 }
00368
00369 generic
00370 square (const generic& x1) {
00371 ACC_UNARY (ACC_SQUARE, x1);
00372 return current_ev->apply (GEN_TIMES, x1, x1);
00373 }
00374
00375 generic
00376 invert (const generic& x1) {
00377 ACC_UNARY (ACC_INVERT, x1);
00378 return current_ev->apply (GEN_OVER, 1, x1);
00379 }
00380
00381 generic
00382 operator + (const generic& x1, const generic& x2) {
00383 ACC_BINARY (ACC_ADD, x1, x2);
00384 return current_ev->apply (GEN_PLUS, x1, x2);
00385 }
00386
00387 generic
00388 operator - (const generic& x1, const generic& x2) {
00389 ACC_BINARY (ACC_SUB, x1, x2);
00390 return current_ev->apply (GEN_MINUS, x1, x2);
00391 }
00392
00393 generic
00394 operator * (const generic& x1, const generic& x2) {
00395 ACC_BINARY (ACC_MUL, x1, x2);
00396 return current_ev->apply (GEN_TIMES, x1, x2);
00397 }
00398
00399 generic
00400 operator / (const generic& x1, const generic& x2) {
00401 ACC_BINARY (ACC_DIV, x1, x2);
00402 return current_ev->apply (GEN_OVER, x1, x2);
00403 }
00404
00405 generic operator + (const generic& x1, const int& x2) {
00406 return x1 + generic (x2); }
00407 generic operator - (const generic& x1, const int& x2) {
00408 return x1 - generic (x2); }
00409 generic operator * (const generic& x1, const int& x2) {
00410 return x1 * generic (x2); }
00411 generic operator / (const generic& x1, const int& x2) {
00412 return x1 / generic (x2); }
00413 generic operator + (const int& x1, const generic& x2) {
00414 return generic (x1) + x2; }
00415 generic operator - (const int& x1, const generic& x2) {
00416 return generic (x1) - x2; }
00417 generic operator * (const int& x1, const generic& x2) {
00418 return generic (x1) * x2; }
00419 generic operator / (const int& x1, const generic& x2) {
00420 return generic (x1) / x2; }
00421
00422
00423
00424
00425
00426 generic
00427 sqrt (const generic& x1) {
00428 ACC_UNARY (ACC_SQRT, x1);
00429 return current_ev->apply (GEN_SQRT, x1);
00430 }
00431
00432 generic
00433 exp (const generic& x1) {
00434 ACC_UNARY (ACC_EXP, x1);
00435 return current_ev->apply (GEN_EXP, x1);
00436 }
00437
00438 generic
00439 log (const generic& x1) {
00440 ACC_UNARY (ACC_LOG, x1);
00441 return current_ev->apply (GEN_LOG, x1);
00442 }
00443
00444 generic
00445 cos (const generic& x1) {
00446 ACC_UNARY (ACC_COS, x1);
00447 return current_ev->apply (GEN_COS, x1);
00448 }
00449
00450 generic
00451 sin (const generic& x1) {
00452 ACC_UNARY (ACC_SIN, x1);
00453 return current_ev->apply (GEN_SIN, x1);
00454 }
00455
00456 generic
00457 tan (const generic& x1) {
00458 ACC_UNARY (ACC_TAN, x1);
00459 return current_ev->apply (GEN_TAN, x1);
00460 }
00461
00462 generic
00463 acos (const generic& x1) {
00464 ACC_UNARY (ACC_ACOS, x1);
00465 return current_ev->apply (GEN_ARCCOS, x1);
00466 }
00467
00468 generic
00469 asin (const generic& x1) {
00470 ACC_UNARY (ACC_ASIN, x1);
00471 return current_ev->apply (GEN_ARCSIN, x1);
00472 }
00473
00474 generic
00475 atan (const generic& x1) {
00476 ACC_UNARY (ACC_ATAN, x1);
00477 return current_ev->apply (GEN_ARCTAN, x1);
00478 }
00479
00480 generic
00481 cosh (const generic& x1) {
00482 ACC_UNARY (ACC_COSH, x1);
00483 return (exp (x1) + exp (-x1)) / 2;
00484 }
00485
00486 generic
00487 sinh (const generic& x1) {
00488 ACC_UNARY (ACC_SINH, x1);
00489 return (exp (x1) - exp (-x1)) / 2;
00490 }
00491
00492 generic
00493 tanh (const generic& x1) {
00494 ACC_UNARY (ACC_TANH, x1);
00495 return (exp (x1) - exp (-x1)) / (exp (x1) + exp (-x1));
00496 }
00497
00498 generic
00499 acosh (const generic& x1) {
00500 ACC_UNARY (ACC_ACOSH, x1);
00501 return log (x1 + sqrt (square (x1) - 1));
00502 }
00503
00504 generic
00505 asinh (const generic& x1) {
00506 ACC_UNARY (ACC_ASINH, x1);
00507 return log (x1 + sqrt (square (x1) + 1));
00508 }
00509
00510 generic
00511 atanh (const generic& x1) {
00512 ACC_UNARY (ACC_ATANH, x1);
00513 return log ((1 + x1) / (1 - x1)) / 2;
00514 }
00515
00516 generic
00517 hypot (const generic& x, const generic& y) {
00518 ACC_BINARY (ACC_HYPOT, x, y);
00519 return sqrt (square (x) + square (y));
00520 }
00521
00522 generic
00523 atan2 (const generic& x, const generic& y) {
00524 ACC_BINARY (ACC_ATAN2, x, y);
00525 if (x > 0) return atan (y/x);
00526 else if (y == 0)
00527 return x == 0? generic (0): generic (-4) * atan (generic (1));
00528 else if (x == 0)
00529 return generic (2 * sign (y)) * atan (generic (1));
00530 else return sign (y) * (4 * atan (generic (1)) - atan (abs (y/x)));
00531 }
00532
00533 generic
00534 pow (const generic& x1, const generic& x2) {
00535 ACC_BINARY (ACC_POW, x1, x2);
00536 return current_ev->apply (GEN_POWER, x1, x2);
00537 }
00538
00539 generic pow (const generic& x1, const int& x2) {
00540 return pow (x1, generic (x2)); }
00541 generic pow (const int& x1, const generic& x2) {
00542 return pow (generic (x1), x2); }
00543 generic pow (const generic& x1, const nat& x2) {
00544 return pow (x1, generic (x2)); }
00545 generic pow (const nat& x1, const generic& x2) {
00546 return pow (generic (x1), x2); }
00547 generic trig (const generic& x1) {
00548 return xsqtuple (comma (cos (x1), sin (x1))); }
00549
00550
00551
00552
00553
00554 bool
00555 operator == (const generic& x1, const generic& x2) {
00556 if (same_type (x1, x2))
00557 return x1->is_equal (x2);
00558 else {
00559 routine* cv= x1->acc_construct (x2->acc_id ());
00560 if (cv != NULL && !is_nil (*cv))
00561 return x1 -> is_equal ((*cv) (x2));
00562 cv= x2->acc_construct (x1->acc_id ());
00563 if (cv != NULL && !is_nil (*cv))
00564 return (*cv) (x1) -> is_equal (x2);
00565 }
00566 return as_bool (current_ev->apply (GEN_EQUAL, x1, x2));
00567 }
00568
00569 bool
00570 operator == (const generic& x1, const int& x2) {
00571 if (is<int> (x1)) return as<int> (x1) == x2;
00572 else {
00573 routine* cv= x1->acc_construct (accelerator<int>::id);
00574 if (cv != NULL && !is_nil (*cv))
00575 return x1 -> is_equal ((*cv) (as<generic> (x2)));
00576 }
00577 return x1 == generic (x2);
00578 }
00579
00580 bool operator != (const generic& x1, const generic& x2) { return !(x1 == x2); }
00581 bool operator != (const generic& x1, const int& x2) { return !(x1 == x2); }
00582 bool operator == (const int& x1, const generic& x2) { return x2 == x1; }
00583 bool operator != (const int& x1, const generic& x2) { return x2 != x1; }
00584
00585 bool
00586 exact_eq (const generic& x1, const generic& x2) {
00587 if (same_type (x1, x2))
00588 return x1->is_exact_eq (x2);
00589 else {
00590 routine* cv= x1->acc_construct (x2->acc_id ());
00591 if (cv != NULL && !is_nil (*cv))
00592 return x1 -> is_exact_eq ((*cv) (x2));
00593 cv= x2->acc_construct (x1->acc_id ());
00594 if (cv != NULL && !is_nil (*cv))
00595 return (*cv) (x1) -> is_exact_eq (x2);
00596 }
00597 return false;
00598 }
00599
00600 bool
00601 exact_eq (const generic& x1, const int& x2) {
00602 if (is<int> (x1)) return as<int> (x1) == x2;
00603 else {
00604 routine* cv= x1->acc_construct (accelerator<int>::id);
00605 if (cv != NULL && !is_nil (*cv))
00606 return x1 -> is_exact_eq ((*cv) (as<generic> (x2)));
00607 }
00608 return false;
00609 }
00610
00611 bool exact_neq (const generic& x1, const generic& x2) {
00612 return !exact_eq (x1, x2); }
00613 bool exact_neq (const generic& x1, const int& x2) {
00614 return !exact_eq (x1, x2); }
00615 bool exact_eq (const int& x1, const generic& x2) {
00616 return exact_eq (x2, x1); }
00617 bool exact_neq (const int& x1, const generic& x2) {
00618 return exact_neq (x2, x1); }
00619
00620
00621
00622
00623
00624 bool
00625 operator < (const generic& x1, const generic& x2) {
00626 ACC_TEST (ACC_LESS, x1, x2);
00627 return as_bool (current_ev->apply (GEN_LESS, x1, x2));
00628 }
00629
00630 bool
00631 operator <= (const generic& x1, const generic& x2) {
00632 ACC_TEST (ACC_LESSEQ, x1, x2);
00633 return as_bool (current_ev->apply (GEN_LESSEQ, x1, x2));
00634 }
00635
00636 bool
00637 operator > (const generic& x1, const generic& x2) {
00638 ACC_TEST (ACC_GTR, x1, x2);
00639 return as_bool (current_ev->apply (GEN_GTR, x1, x2));
00640 }
00641
00642 bool
00643 operator >= (const generic& x1, const generic& x2) {
00644 ACC_TEST (ACC_GTREQ, x1, x2);
00645 return as_bool (current_ev->apply (GEN_GTREQ, x1, x2));
00646 }
00647
00648 bool operator < (const generic& x1, const int& x2) {
00649 return x1 < generic (x2); }
00650 bool operator <= (const generic& x1, const int& x2) {
00651 return x1 <= generic (x2); }
00652 bool operator > (const generic& x1, const int& x2) {
00653 return x1 > generic (x2); }
00654 bool operator >= (const generic& x1, const int& x2) {
00655 return x1 >= generic (x2); }
00656 bool operator < (const int& x1, const generic& x2) {
00657 return generic (x1) < x2; }
00658 bool operator <= (const int& x1, const generic& x2) {
00659 return generic (x1) <= x2; }
00660 bool operator > (const int& x1, const generic& x2) {
00661 return generic (x1) > x2; }
00662 bool operator >= (const int& x1, const generic& x2) {
00663 return generic (x1) >= x2; }
00664
00665
00666
00667
00668
00669 generic
00670 derive (const generic& x1) {
00671 ACC_UNARY (ACC_DERIVE, x1);
00672 return current_ev->apply (GEN_CACHED_DERIVE, x1);
00673 }
00674
00675 generic
00676 integrate (const generic& x1) {
00677 ACC_UNARY (ACC_INTEGRATE, x1);
00678 return current_ev->apply (GEN_INTEGRATE, x1);
00679 }
00680
00681 generic
00682 derive (const generic& x1, const generic& v) {
00683 ACC_BINARY_SCALAR (ACC_DERIVE_WRT, x1, v);
00684 MEMOIZE_BINARY (std_memoizer,generic,generic,generic,derive,x1,v,
00685 current_ev->apply (GEN_CACHED_DERIVE, x1, v));
00686 }
00687
00688 generic
00689 integrate (const generic& x1, const generic& v) {
00690 ACC_BINARY_SCALAR (ACC_DERIVE_WRT, x1, v);
00691 return current_ev->apply (GEN_INTEGRATE, x1, v);
00692 }
00693
00694 generic prime (const generic& x1) {
00695 return current_ev->apply ("'", x1); }
00696 generic substitute (const generic& x1, const generic& x2) {
00697 return current_ev->apply (GEN_SUBSTITUTE, x1, x2); }
00698 generic compose (const generic& x1, const generic& x2) {
00699 return current_ev->apply (GEN_COMPOSE, x1, x2); }
00700 generic dilate (const generic& x1, const generic& x2) {
00701 return current_ev->apply ("dilate", x1, x2); }
00702 generic solve (const generic& x1, const generic& x2) {
00703 return current_ev->apply (GEN_SOLVE, x1, x2); }
00704
00705
00706
00707
00708
00709 generic quo (const generic& x1, const generic& x2) {
00710 return current_ev->apply (GEN_DIV, x1, x2); }
00711 generic rem (const generic& x1, const generic& x2) {
00712 return current_ev->apply (GEN_MOD, x1, x2); }
00713 generic numerator (const generic& x) {
00714 return current_ev->apply (GEN_NUMERATOR, x); }
00715 generic denominator (const generic& x) {
00716 return current_ev->apply (GEN_DENOMINATOR, x); }
00717 generic gcd (const generic& x1, const generic& x2) {
00718 return current_ev->apply (GEN_GCD, x1, x2); }
00719 generic lcm (const generic& x1, const generic& x2) {
00720 return current_ev->apply (GEN_LCM, x1, x2); }
00721
00722
00723
00724
00725
00726 generic min (const generic& x1, const generic& x2) {
00727 return current_ev->apply (GEN_MIN, x1, x2); }
00728 generic max (const generic& x1, const generic& x2) {
00729 return current_ev->apply (GEN_MAX, x1, x2); }
00730 generic abs (const generic& x1) {
00731 return current_ev->apply (GEN_ABS, x1); }
00732 generic arg (const generic& x1) {
00733 return current_ev->apply (GEN_ARG, x1); }
00734 generic Re (const generic& x1) {
00735 return current_ev->apply (GEN_RE, x1); }
00736 generic Im (const generic& x1) {
00737 return current_ev->apply (GEN_IM, x1); }
00738 generic conj (const generic& x1) {
00739 return current_ev->apply (GEN_CONJ, x1); }
00740 generic gaussian (const generic& x1, const generic& x2) {
00741 return x1 + x2 * Imaginary (generic); }
00742 generic polar (const generic& x1, const generic& x2) {
00743 return x1 * exp (x2 * Imaginary (generic)); }
00744
00745
00746
00747
00748
00749 generic floor (const generic& x) {
00750 return current_ev->apply (GEN_FLOOR, x); }
00751 generic trunc (const generic& x) {
00752 return current_ev->apply (GEN_TRUNC, x); }
00753 generic ceil (const generic& x) {
00754 return current_ev->apply (GEN_CEIL, x); }
00755 generic round (const generic& x) {
00756 return current_ev->apply (GEN_ROUND, x); }
00757
00758
00759
00760
00761
00762 generic change_precision (const generic& x, xnat p) {
00763 return current_ev->apply (GEN_CHANGE_PRECISION, x, as<generic> ((int) p)); }
00764 xnat precision (const generic& x) {
00765 generic r= current_ev->apply (GEN_PRECISION, x);
00766 ASSERT (is<int> (r), "Int return value expected");
00767 return as<int> (r); }
00768 generic next_above (const generic& x) {
00769 return current_ev->apply (GEN_NEXT_ABOVE, x); }
00770 generic next_below (const generic& x) {
00771 return current_ev->apply (GEN_NEXT_BELOW, x); }
00772 generic rounding_error (const generic& x) {
00773 return current_ev->apply (GEN_ROUNDING_ERROR, x); }
00774 generic additive_error (const generic& x) {
00775 return current_ev->apply (GEN_ADDITIVE_ERROR, x); }
00776 generic multiplicative_error (const generic& x) {
00777 return current_ev->apply (GEN_MULTIPLICATIVE_ERROR, x); }
00778 generic elementary_error (const generic& x) {
00779 return current_ev->apply (GEN_ELEMENTARY_ERROR, x); }
00780
00781 xint exponent (const generic& x) {
00782 generic r= current_ev->apply (GEN_EXPONENT, x);
00783 ASSERT (is<int> (r), "Int return value expected");
00784 return as<int> (r); }
00785 double magnitude (const generic& x) {
00786 generic r= current_ev->apply (GEN_MAGNITUDE, x);
00787 ASSERT (is<double> (r), "Double return value expected");
00788 return as<double> (r); }
00789 generic incexp2 (const generic& x1, const xint& x2) {
00790 return current_ev->apply ("increase_exponent", x1, as<generic> ((int) x2)); }
00791 generic decexp2 (const generic& x1, const xint& x2) {
00792 return current_ev->apply ("decrease_exponent", x1, as<generic> ((int) x2)); }
00793 generic operator << (const generic& x1, const generic& x2) {
00794 return current_ev->apply (GEN_LESSLESS, x1, x2); }
00795 generic operator >> (const generic& x1, const generic& x2) {
00796 return current_ev->apply (GEN_GTRGTR, x1, x2); }
00797
00798
00799
00800
00801
00802 generic sqrt_init (const generic& x1, const generic& x2) {
00803 return current_ev->apply ("sqrt_init", x1, x2); }
00804 generic log_init (const generic& x1, const generic& x2) {
00805 return current_ev->apply ("log_init", x1, x2); }
00806 generic acos_init (const generic& x1, const generic& x2) {
00807 return current_ev->apply ("acos_init", x1, x2); }
00808 generic asin_init (const generic& x1, const generic& x2) {
00809 return current_ev->apply ("asin_init", x1, x2); }
00810 generic atan_init (const generic& x1, const generic& x2) {
00811 return current_ev->apply ("atan_init", x1, x2); }
00812 generic integrate_init (const generic& x1, const generic& x2) {
00813 return current_ev->apply ("integrate_init", x1, x2); }
00814 generic solve_lde_init (const generic& x1, const generic& x2) {
00815 return current_ev->apply ("solve_lde_init", x1, x2); }
00816
00817
00818
00819
00820
00821 generic center (const generic& x1) {
00822 return current_ev->apply ("center", x1); }
00823 generic radius (const generic& x1) {
00824 return current_ev->apply ("radius", x1); }
00825 generic sharpen (const generic& x1) {
00826 return current_ev->apply ("sharpen", x1); }
00827 generic blur (const generic& x1, const generic& x2) {
00828 return current_ev->apply ("blur", x1, x2); }
00829
00830
00831
00832
00833
00834 generic lshiftz (const generic& x1, const generic& x2) {
00835 return current_ev->apply ("lshiftz", x1, x2); }
00836 generic rshiftz (const generic& x1, const generic& x2) {
00837 return current_ev->apply ("rshiftz", x1, x2); }
00838 generic operator | (const generic& x1, const generic& x2) {
00839 return current_ev->apply (GEN_OR, x1, x2); }
00840 generic operator & (const generic& x1, const generic& x2) {
00841 return current_ev->apply (GEN_AND, x1, x2); }
00842 generic lres (const generic& x1, const generic& x2) {
00843 return current_ev->apply ("lres", x1, x2); }
00844 generic rres (const generic& x1, const generic& x2) {
00845 return current_ev->apply ("rres", x1, x2); }
00846 generic uniform (const generic& x1, const generic& x2) {
00847 return current_ev->apply ("uniform", x1, x2); }
00848 generic specialize (const generic& x1, const generic& x2) {
00849 return current_ev->apply ("specialize", x1, x2); }
00850
00851 }