basix_doc 0.1
|
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