basix_doc 0.1
|
00001 00002 /****************************************************************************** 00003 * MODULE : operators.hpp 00004 * DESCRIPTION: Templates and default implementations of several operations 00005 * COPYRIGHT : (C) 2003 Joris van der Hoeven 00006 ******************************************************************************* 00007 * This software falls under the GNU general public license and comes WITHOUT 00008 * ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details. 00009 * If you don't have this file, write to the Free Software Foundation, Inc., 00010 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00011 ******************************************************************************/ 00012 00013 #ifndef __MMX_OPERATORS_HPP 00014 #define __MMX_OPERATORS_HPP 00015 #include <basix/port.hpp> 00016 #include <basix/identifiers.hpp> 00017 00019 00020 namespace mmx { 00021 00022 /****************************************************************************** 00023 * Refer to standard C++ operators by another name 00024 ******************************************************************************/ 00025 00026 #define TMPL template<typename T> 00027 00028 TMPL T neg_operator (const T& x) { return -x; } 00029 TMPL T add_operator (const T& x, const T& y) { return x+y; } 00030 TMPL T sub_operator (const T& x, const T& y) { return x-y; } 00031 TMPL T mul_operator (const T& x, const T& y) { return x*y; } 00032 TMPL T div_operator (const T& x, const T& y) { return x/y; } 00033 00034 TMPL bool equal_operator (const T& x, const T& y) { return x==y; } 00035 TMPL bool unequal_operator (const T& x, const T& y) { return x!=y; } 00036 TMPL bool less_operator (const T& x, const T& y) { return x<y; } 00037 TMPL bool lesseq_operator (const T& x, const T& y) { return x<=y; } 00038 TMPL bool gtr_operator (const T& x, const T& y) { return x>y; } 00039 TMPL bool gtreq_operator (const T& x, const T& y) { return x>=y; } 00040 00041 #undef TMPL 00042 00043 /****************************************************************************** 00044 * Default versions of in place operators 00045 ******************************************************************************/ 00046 00047 template<typename R> inline void 00048 neg (R& x) { x= -x; } 00049 template<typename R, typename C1> inline void 00050 neg (R& x, const C1& y1) { x= -y1; } 00051 template<typename R, typename C1, typename C2> inline void 00052 add (R& x, const C1& y1, const C2& y2) { x= y1 + y2; } 00053 template<typename R, typename C1, typename C2> inline void 00054 sub (R& x, const C1& y1, const C2& y2) { x= y1 - y2; } 00055 template<typename R, typename C1, typename C2> inline void 00056 mul (R& x, const C1& y1, const C2& y2) { x= y1 * y2; } 00057 template<typename R, typename C1, typename C2> inline void 00058 div (R& x, const C1& y1, const C2& y2) { x= y1 / y2; } 00059 template<typename R, typename C1, typename C2> inline void 00060 mul_add (R& x, const C1& y1, const C2& y2) { x += y1 * y2; } 00061 template<typename R, typename C1, typename C2> inline void 00062 mul_sub (R& x, const C1& y1, const C2& y2) { x -= y1 * y2; } 00063 00064 /****************************************************************************** 00065 * Consider arbitrary routines as operators 00066 ******************************************************************************/ 00067 00068 template<typename C, C (*fun) (const C&)> 00069 struct unary_op { 00070 static inline C 00071 op (const C& x) { return fun (x); } 00072 }; 00073 00074 template<typename C, C (*fun) (const C&, const C&)> 00075 struct binary_op { 00076 static inline C 00077 op (const C& x, const C& y) { return fun (x, y); } 00078 }; 00079 00080 /****************************************************************************** 00081 * Specify the return type for operators which perform a cast 00082 ******************************************************************************/ 00083 00084 template<typename Op, typename R> 00085 struct replace_return_op { 00086 static inline R 00087 op () { return Op::template op<R> (); } 00088 template<typename X1> static inline R 00089 op (const X1& x1) { return Op::template op<R> (x1); } 00090 template<typename X1, typename X2> static inline R 00091 op (const X1& x1, const X2& x2) { return Op::template op<R> (x1, x2); } 00092 static inline void 00093 set_op (R& r) { Op::set_op (r); } 00094 template<typename X1> static inline void 00095 set_op (R& r, const X1& x1) { Op::set_op (r, x1); } 00096 template<typename X1, typename X2> static inline void 00097 set_op (R& r, const X1& x1, const X2& x2) { Op::set_op (r, x1, x2); } 00098 }; 00099 00100 template<typename Op, typename R> 00101 struct return_op_helper { 00102 typedef Op Rop; 00103 }; 00104 00105 #define REPLACEABLE_RETURN(Op) \ 00106 template<typename R> \ 00107 struct return_op_helper<Op,R> { \ 00108 typedef replace_return_op<Op,R> Rop; \ 00109 }; 00110 00111 #define Return_op(Op,R) \ 00112 typename return_op_helper<Op,R>::Rop 00113 00114 /****************************************************************************** 00115 * Get the in-place variant of an operator 00116 ******************************************************************************/ 00117 00118 template<typename Op> 00119 struct in_place_op { 00120 template<typename R> static inline void 00121 op (R& r) { (void) Op::set_op (r); } 00122 template<typename R, typename S1> static inline void 00123 op (R& r, const S1& s1) { (void) Op::set_op (r, s1); } 00124 template<typename R, typename S1, typename S2> static inline void 00125 op (R& r, const S1& s1, const S2& s2) { (void) Op::set_op (r, s1, s2); } 00126 static inline syntactic 00127 op (const syntactic& s1) { 00128 return apply (Op::set_name (), s1); } 00129 static inline syntactic 00130 op (const syntactic& s1, const syntactic& s2) { 00131 return apply (Op::set_name (), s1, s2); } 00132 static inline syntactic 00133 op (const syntactic& s1, const syntactic& s2, const syntactic& s3) { 00134 return apply (Op::set_name (), s1, s2, s3); } 00135 }; 00136 00137 /****************************************************************************** 00138 * Constructors and copying 00139 ******************************************************************************/ 00140 00141 struct no_op { 00142 static generic set_name () { return GEN_NOOP; } 00143 template<typename C1> static inline void 00144 set_op (C1& x1) { (void) x1; } 00145 template<typename C1, typename C2> static inline void 00146 set_op (C1& x1, C2& x2) { (void) x1; (void) x2; } 00147 template<typename C1, typename C2, typename C3> static inline void 00148 set_op (C1& x1, C2& x2, C3& x3) { (void) x1; (void) x2; (void) x3; } 00149 }; 00150 00151 struct id_op { 00152 static generic name () { return GEN_IDENTITY; } 00153 static generic set_name () { return GEN_ASSIGN; } 00154 template<typename C> static inline C 00155 op (const C& x) { return x; } 00156 template<typename R, typename C> static inline void 00157 set_op (R& x, const C& y) { x= y; } 00158 }; 00159 00160 struct as_op { 00161 template<typename R, typename C> static inline R 00162 op (const C& x) { return as<R> (x); } 00163 template<typename R, typename C> static inline void 00164 set_op (R& x, const C& y) { set_as (x, y); } 00165 }; 00166 00167 REPLACEABLE_RETURN(as_op); 00168 00169 struct copy_op { 00170 template<typename C> static inline C 00171 op (const C& x) { return copy (x); } 00172 template<typename R, typename C> static inline void 00173 set_op (R& x, const C& y) { x= copy (y); } 00174 static inline generic 00175 op (const generic& x) { return x; } 00176 static inline syntactic 00177 op (const syntactic& x) { return x; } 00178 template<typename R> static inline void 00179 set_op (R& x, const generic& y) { x= y; } 00180 template<typename R> static inline void 00181 set_op (R& x, const syntactic& y) { x= y; } 00182 }; 00183 00184 struct clear_op { 00185 template<typename C> static inline void 00186 set_op (C& x) { clear (x); } 00187 }; 00188 00189 struct duplicate_op { 00190 template<typename C> static inline C 00191 op (const C& x) { return duplicate (x); } 00192 template<typename R, typename C> static inline void 00193 set_op (R& x, const C& y) { x= duplicate (y); } 00194 }; 00195 00196 struct fast_op { 00197 static generic name () { return GEN_FAST; } 00198 template<typename C> static inline Fast_type(C) 00199 op (const C& x) { return fast (x); } 00200 template<typename R, typename C> static inline void 00201 set_op (R& x, const C& y) { x= fast (y); } 00202 }; 00203 00204 struct slow_op { 00205 static generic name () { return GEN_SLOW; } 00206 template<typename C> static inline C 00207 op (const Fast_type(C)& x) { return slow (x); } 00208 template<typename R, typename C> static inline void 00209 set_op (R& x, const C& y) { x= slow_as<R> (y); } 00210 }; 00211 00212 struct swap_op { 00213 template<typename C> static inline void 00214 set_op (C& x, C& y) { C aux= x; x= y; y= aux; } 00215 }; 00216 00217 struct flatten_op { 00218 template<typename C> static inline syntactic 00219 op (const C& x) { return flatten (x); } 00220 template<typename R, typename C> static inline void 00221 set_op (R& x, const C& y) { x= flatten (y); } 00222 }; 00223 00224 template<typename C> 00225 struct unary_return_type_helper<flatten_op,C> { 00226 typedef syntactic RET; 00227 }; 00228 00229 /****************************************************************************** 00230 * Constants 00231 ******************************************************************************/ 00232 00233 struct log2_as_op { 00234 template<typename R> static inline R 00235 op () { return Log2 (R); } 00236 template<typename R> static inline void 00237 set_op (R& x) { set_log2 (x); } 00238 }; 00239 00240 struct pi_as_op { 00241 template<typename R> static inline R 00242 op () { return Pi (R); } 00243 template<typename R> static inline void 00244 set_op (R& x) { set_pi (x); } 00245 }; 00246 00247 struct euler_as_op { 00248 template<typename R> static inline R 00249 op () { return Euler (R); } 00250 template<typename R> static inline void 00251 set_op (R& x) { set_euler (x); } 00252 }; 00253 00254 struct catalan_as_op { 00255 template<typename R> static inline R 00256 op () { return Catalan (R); } 00257 template<typename R> static inline void 00258 set_op (R& x) { set_catalan (x); } 00259 }; 00260 00261 struct smallest_as_op { 00262 template<typename R> static inline R 00263 op () { return Smallest (R); } 00264 template<typename R> static inline void 00265 set_op (R& x) { set_smallest (x); } 00266 }; 00267 00268 struct largest_as_op { 00269 template<typename R> static inline R 00270 op () { return Largest (R); } 00271 template<typename R> static inline void 00272 set_op (R& x) { set_largest (x); } 00273 }; 00274 00275 struct accuracy_as_op { 00276 template<typename R> static inline R 00277 op () { return Accuracy (R); } 00278 template<typename R> static inline void 00279 set_op (R& x) { set_accuracy (x); } 00280 }; 00281 00282 struct imaginary_as_op { 00283 template<typename R> static inline R 00284 op () { return Imaginary (R); } 00285 template<typename R> static inline void 00286 set_op (R& x) { set_imaginary (x); } 00287 }; 00288 00289 struct nan_as_op { 00290 template<typename R> static inline R 00291 op () { return Nan (R); } 00292 template<typename R> static inline void 00293 set_op (R& x) { set_nan (x); } 00294 }; 00295 00296 struct infinity_as_op { 00297 template<typename R> static inline R 00298 op () { return Infinity (R); } 00299 template<typename R> static inline void 00300 set_op (R& x) { set_infinity (x); } 00301 }; 00302 00303 struct maximal_as_op { 00304 template<typename R> static inline R 00305 op () { return Maximal (R); } 00306 template<typename R> static inline void 00307 set_op (R& x) { set_maximal (x); } 00308 }; 00309 00310 struct minimal_as_op { 00311 template<typename R> static inline R 00312 op () { return Minimal (R); } 00313 template<typename R> static inline void 00314 set_op (R& x) { set_minimal (x); } 00315 }; 00316 00317 struct fuzz_as_op { 00318 template<typename R> static inline R 00319 op () { return Fuzz (R); } 00320 template<typename R> static inline void 00321 set_op (R& x) { set_fuzz (x); } 00322 }; 00323 00324 REPLACEABLE_RETURN(log2_as_op); 00325 REPLACEABLE_RETURN(pi_as_op); 00326 REPLACEABLE_RETURN(euler_as_op); 00327 REPLACEABLE_RETURN(catalan_as_op); 00328 REPLACEABLE_RETURN(smallest_as_op); 00329 REPLACEABLE_RETURN(largest_as_op); 00330 REPLACEABLE_RETURN(accuracy_as_op); 00331 REPLACEABLE_RETURN(imaginary_as_op); 00332 REPLACEABLE_RETURN(infinity_as_op); 00333 REPLACEABLE_RETURN(nan_as_op); 00334 REPLACEABLE_RETURN(maximal_as_op); 00335 REPLACEABLE_RETURN(minimal_as_op); 00336 REPLACEABLE_RETURN(fuzz_as_op); 00337 00338 /****************************************************************************** 00339 * Hashing 00340 ******************************************************************************/ 00341 00342 struct hash_op { 00343 static generic name () { return GEN_HASH; } 00344 template<typename C> static inline nat 00345 op (const C& x) { return hash (x); } 00346 }; 00347 00348 struct exact_hash_op { 00349 static generic name () { return GEN_EXACT_HASH; } 00350 template<typename C> static inline nat 00351 op (const C& x) { return exact_hash (x); } 00352 }; 00353 00354 struct hard_hash_op { 00355 static generic name () { return GEN_HARD_HASH; } 00356 template<typename C> static inline nat 00357 op (const C& x) { return hard_hash (x); } 00358 }; 00359 00360 /****************************************************************************** 00361 * Arithmetic operators 00362 ******************************************************************************/ 00363 00364 struct zero_op { 00365 template<typename T> static inline T 00366 op (const T& x) { return T(0); } 00367 }; 00368 00369 struct neg_op { 00370 static generic name () { return GEN_MINUS; } 00371 template<typename C> static inline C 00372 op (const C& x) { return -x; } 00373 template<typename C> static inline void 00374 set_op (C& x) { neg (x); } 00375 template<typename R, typename C> static inline void 00376 set_op (R& x, const C& y) { neg (x, y); } 00377 template<typename C> static inline C 00378 diff_op (const C& me, const C& x) { 00379 (void) me; return -derive (x); } 00380 00381 template<typename C, typename M> static inline C 00382 op_mod (const C& x, const M& p) { 00383 C y; neg_mod (y, x, p); return y; } 00384 template<typename C, typename M> static inline C 00385 op_mod (const C& x, const M& p, C& carry) { 00386 C y; neg_mod (y, x, p, carry); return y; } 00387 template<typename C, typename M> static inline void 00388 set_op_mod (C& x, const M& p) { 00389 neg_mod (x, p); } 00390 template<typename C, typename M> static inline void 00391 set_op_mod (C& x, const M& p, C& carry) { 00392 neg_mod (x, p, carry); } 00393 template<typename C, typename M> static inline void 00394 set_op_mod (C& x, const C& y, const M& p) { 00395 neg_mod (x, y, p); } 00396 template<typename C, typename M> static inline void 00397 set_op_mod (C& x, const C& y, const M& p, C& carry) { 00398 neg_mod (x, y, p, carry); } 00399 }; 00400 00401 struct add_op { 00402 typedef id_op lop; 00403 typedef id_op rop; 00404 static generic name () { return GEN_PLUS; } 00405 static generic set_name () { return GEN_PLUS_ASSIGN; } 00406 template<typename C> static inline C 00407 neutral () { return 0; } 00408 template<typename R> static inline void 00409 set_neutral (R& r) { set_zero (r); } 00410 template<typename C> static inline C 00411 op (const C& x, const C& y) { return x + y; } 00412 template<typename R, typename C> static inline void 00413 set_op (R& x, const C& y) { x += y; } 00414 template<typename R, typename C1, typename C2> static inline void 00415 set_op (R& x, const C1& y1, const C2& y2) { add (x, y1, y2); } 00416 template<typename C> static inline C 00417 diff_op (const C& me, const C& x, const C& y) { 00418 (void) me; return derive (x) + derive (y); } 00419 template<typename C, typename M> static inline C 00420 op_mod (const C& x, const C& y, const M& p) { 00421 C z; add_mod (z, x, y, p); return z; } 00422 template<typename C, typename M> static inline C 00423 op_mod (const C& x, const C& y, const M& p, C& carry) { 00424 C z; add_mod (z, x, y, p, carry); return z; } 00425 template<typename C, typename M> static inline void 00426 set_op_mod (C& x, const C& y, const M& p) { 00427 add_mod (x, y, p); } 00428 template<typename C, typename M> static inline void 00429 set_op_mod (C& x, const C& y, const M& p, C& carry) { 00430 add_mod (x, y, p, carry); } 00431 template<typename C, typename M> static inline void 00432 set_op_mod (C& x, const C& y1, const C& y2, const M& p) { 00433 add_mod (x, y1, y2, p); } 00434 template<typename C, typename M> static inline void 00435 set_op_mod (C& x, const C& y1, const C& y2, const M& p, C& carry) { 00436 add_mod (x, y1, y2, p, carry); } 00437 }; 00438 00439 struct radd_op { 00440 static generic name () { return GEN_PLUS; } 00441 template<typename C,typename S> static inline C 00442 op (const C& x, const S& y) { return x + y; } 00443 template<typename C,typename S> static inline void 00444 set_op (C& x, const S& y) { x += y; } 00445 template<typename R, typename C1, typename C2> static inline void 00446 set_op (R& x, const C1& y1, const C2& y2) { add (x, y1, y2); } 00447 }; 00448 00449 struct ladd_op { 00450 static generic name () { return GEN_PLUS; } 00451 template<typename C,typename S> static inline C 00452 op (const C& y, const S& x) { return x + y; } 00453 template<typename R, typename C1, typename C2> static inline void 00454 set_op (R& x, const C1& y2, const C2& y1) { add (x, y1, y2); } 00455 }; 00456 00457 struct sub_op { 00458 typedef id_op lop; 00459 typedef neg_op rop; 00460 static generic name () { return GEN_MINUS; } 00461 static generic set_name () { return GEN_MINUS_ASSIGN; } 00462 template<typename C> static inline C 00463 op (const C& x, const C& y) { return x - y; } 00464 template<typename R, typename C> static inline void 00465 set_op (R& x, const C& y) { x -= y; } 00466 template<typename R, typename C1, typename C2> static inline void 00467 set_op (R& x, const C1& y1, const C2& y2) { sub (x, y1, y2); } 00468 template<typename C> static inline C 00469 diff_op (const C& me, const C& x, const C& y) { 00470 (void) me; return derive (x) - derive (y); } 00471 template<typename C, typename M> static inline C 00472 op_mod (const C& x, const C& y, const M& p) { 00473 C z; sub_mod (z, x, y, p); return z; } 00474 template<typename C, typename M> static inline C 00475 op_mod (const C& x, const C& y, const M& p, C& carry) { 00476 C z; sub_mod (z, x, y, p, carry); return z; } 00477 template<typename C, typename M> static inline void 00478 set_op_mod (C& x, const C& y, const M& p) { 00479 sub_mod (x, y, p); } 00480 template<typename C, typename M> static inline void 00481 set_op_mod (C& x, const C& y, const M& p, C& carry) { 00482 sub_mod (x, y, p, carry); } 00483 template<typename C, typename M> static inline void 00484 set_op_mod (C& x, const C& y1, const C& y2, const M& p) { 00485 sub_mod (x, y1, y2, p); } 00486 template<typename C, typename M> static inline void 00487 set_op_mod (C& x, const C& y1, const C& y2, const M& p, C& carry) { 00488 sub_mod (x, y1, y2, p, carry); } 00489 }; 00490 00491 struct rsub_op { 00492 static generic name () { return GEN_MINUS; } 00493 template<typename C,typename S> static inline C 00494 op (const C& x, const S& y) { return x - y; } 00495 template<typename C,typename S> static inline void 00496 set_op (C& x, const S& y) { x -= y; } 00497 template<typename R, typename C1, typename C2> static inline void 00498 set_op (R& x, const C1& y1, const C2& y2) { sub (x, y1, y2); } 00499 }; 00500 00501 struct lsub_op { 00502 static generic name () { return GEN_MINUS; } 00503 template<typename C,typename S> static inline C 00504 op (const C& y, const S& x) { return x - y; } 00505 template<typename R, typename C1, typename C2> static inline void 00506 set_op (R& x, const C1& y2, const C2& y1) { sub (x, y1, y2); } 00507 }; 00508 00509 struct lmul_op; 00510 struct rmul_op; 00511 struct mul_add_op; 00512 00513 struct mul_op { 00514 typedef lmul_op sc_left; 00515 typedef rmul_op sc_right; 00516 typedef id_op nomul_op; 00517 typedef clear_op clr_op; 00518 typedef mul_add_op acc_op; 00519 static generic name () { return GEN_TIMES; } 00520 static generic set_name () { return GEN_TIMES_ASSIGN; } 00521 template<typename C> static inline C 00522 neutral () { return 1; } 00523 template<typename R> static inline void 00524 set_neutral (R& r) { set_one (r); } 00525 template<typename C> static inline C 00526 op (const C& x, const C& y) { return x * y; } 00527 template<typename R, typename C> static inline void 00528 set_op (R& x, const C& y) { x *= y; } 00529 template<typename R, typename C1, typename C2> static inline void 00530 set_op (R& x, const C1& y1, const C2& y2) { mul (x, y1, y2); } 00531 template<typename C> static inline C 00532 diff_op (const C& me, const C& x, const C& y) { 00533 (void) me; return derive (x)*y + x*derive (y); } 00534 template<typename C,typename M> static inline C 00535 op_mod (const C& x, const C& y, const M& p) { 00536 C z; mul_mod (z, x, y, p); return z; } 00537 template<typename C,typename M> static inline C 00538 op_mod (const C& x, const C& y, const M& p, C& carry) { 00539 C z; mul_mod (z, x, y, p, carry); return z; } 00540 template<typename C,typename M> static inline void 00541 set_op_mod (C& x, const C& y, const M& p) { 00542 mul_mod (x, y, p); } 00543 template<typename C,typename M> static inline void 00544 set_op_mod (C& x, const C& y, const M& p, C& carry) { 00545 mul_mod (x, y, p, carry); } 00546 template<typename C, typename M> static inline void 00547 set_op (C& x, const C& y1, const C& y2, const M& p) { 00548 mul_mod (x, y1, y2, p); } 00549 template<typename C, typename M> static inline void 00550 set_op (C& x, const C& y1, const C& y2, const M& p, C& carry) { 00551 mul_mod (x, y1, y2, p, carry); } 00552 }; 00553 00554 struct rmul_op { 00555 static generic name () { return GEN_TIMES; } 00556 template<typename C,typename S> static inline C 00557 op (const C& x, const S& y) { return x * y; } 00558 template<typename C,typename S> static inline void 00559 set_op (C& x, const S& y) { x *= y; } 00560 template<typename R, typename C1, typename C2> static inline void 00561 set_op (R& x, const C1& y1, const C2& y2) { mul (x, y1, y2); } 00562 template<typename C,typename S> static inline C 00563 diff_op (const C& me, const C& x, const S& y) { 00564 (void) me; return derive (x) * y; } 00565 template<typename C,typename M> static inline C 00566 op_mod (const C& x, const C& y, const M& p) { 00567 C z; mul_mod (z, x, y, p); return z; } 00568 template<typename C,typename M> static inline C 00569 op_mod (const C& x, const C& y, const M& p, C& carry) { 00570 C z; mul_mod (z, x, y, p, carry); return z; } 00571 }; 00572 00573 struct lmul_op { 00574 static generic name () { return GEN_TIMES; } 00575 template<typename C,typename S> static inline C 00576 op (const C& y, const S& x) { return x * y; } 00577 template<typename R, typename C1, typename C2> static inline void 00578 set_op (R& x, const C1& y2, const C2& y1) { mul (x, y1, y2); } 00579 template<typename C,typename S> static inline C 00580 diff_op (const C& me, const C& y, const S& x) { 00581 (void) me; return x * derive (y); } 00582 template<typename C,typename M> static inline C 00583 op_mod (const C& y, const C& x, const M& p) { 00584 C z; mul_mod (z, x, y, p); return z; } 00585 template<typename C,typename M> static inline C 00586 op_mod (const C& y, const C& x, const M& p, C& carry) { 00587 C z; mul_mod (z, x, y, p, carry); return z; } 00588 }; 00589 00590 struct mul_add_op { 00591 typedef add_op nomul_op; 00592 typedef mul_op rhs_op; 00593 typedef no_op clr_op; 00594 typedef mul_add_op acc_op; 00595 static generic name () { return GEN_MUL_ADD; } 00596 template<typename C> static inline C 00597 neutral () { return 0; } 00598 template<typename R> static inline void 00599 set_neutral (R& r) { set_zero (r); } 00600 template<typename C> static inline C 00601 op (const C& x, const C& y, const C& z) { return x + y * z; } 00602 template<typename R, typename C1, typename C2> static inline void 00603 set_op (R& x, const C1& y, const C2& z) { mul_add (x, y, z); } 00604 }; 00605 00606 struct rmul_add_op { 00607 static generic name () { return GEN_MUL_ADD; } 00608 template<typename R, typename C,typename S> static inline void 00609 set_op (R& x, const C& y, const S& z) { mul_add (x, y, z); } 00610 }; 00611 00612 struct lmul_add_op { 00613 static generic name () { return GEN_MUL_ADD; } 00614 template<typename R, typename C,typename S> static inline void 00615 set_op (R& x, const C& z, const S& y) { mul_add (x, y, z); } 00616 }; 00617 00618 struct mul_sub_op { 00619 typedef sub_op nomul_op; 00620 typedef mul_op rhs_op; 00621 typedef no_op clr_op; 00622 typedef mul_sub_op acc_op; 00623 static generic name () { return GEN_MUL_SUB; } 00624 template<typename C> static inline C 00625 neutral () { return 0; } 00626 template<typename R> static inline void 00627 set_neutral (R& r) { set_zero (r); } 00628 template<typename C> static inline C 00629 op (const C& x, const C& y, const C& z) { return x - y * z; } 00630 template<typename R, typename C1, typename C2> static inline void 00631 set_op (R& x, const C1& y, const C2& z) { mul_sub (x, y, z); } 00632 }; 00633 00634 struct square_op { 00635 static generic name () { return GEN_SQUARE; } 00636 template<typename C> static inline C 00637 op (const C& x) { return square (x); } 00638 template<typename R> static inline void 00639 set_op (R& x) { x= square (x); } 00640 template<typename R, typename C> static inline void 00641 set_op (R& x, const C& y) { x= square (y); } 00642 template<typename C> static inline C 00643 diff_op (const C& me, const C& x) { 00644 (void) me; return 2*derive (x)*x; } 00645 }; 00646 00647 struct graeffe_op { 00648 static generic name () { return GEN_GRAEFFE; } 00649 template<typename C> static inline C 00650 op (const C& x) { return graeffe (x); } 00651 template<typename R> static inline void 00652 set_op (R& x) { x= graeffe (x); } 00653 template<typename R, typename C> static inline void 00654 set_op (R& x, const C& y) { x= graeffe (y); } 00655 }; 00656 00657 struct invert_op { 00658 static generic name () { return GEN_INVERT; } 00659 template<typename C> static inline C 00660 op (const C& x) { return invert (x); } 00661 template<typename C> static inline void 00662 set_op (C& x) { x= invert (x); } 00663 template<typename R, typename C> static inline void 00664 set_op (R& x, const C& y) { x= invert (y); } 00665 template<typename C> static inline C 00666 diff_op (const C& me, const C& x) { 00667 (void) me; return -derive (x) / square (x); } 00668 template<typename C> static inline C 00669 def (const C& me, const C& f) { 00670 return (C(1) - lshiftz (me * rshiftz (f))) / f[0]; } 00671 }; 00672 00673 struct ldiv_op; 00674 struct rdiv_op; 00675 00676 struct div_op { 00677 typedef ldiv_op sc_left; 00678 typedef rdiv_op sc_right; 00679 static generic name () { return GEN_OVER; } 00680 static generic set_name () { return GEN_OVER_ASSIGN; } 00681 template<typename C> static inline C 00682 op (const C& x, const C& y) { return x / y; } 00683 template<typename R, typename C> static inline void 00684 set_op (R& x, const C& y) { x /= y; } 00685 template<typename R, typename C1, typename C2> static inline void 00686 set_op (R& x, const C1& y1, const C2& y2) { div (x, y1, y2); } 00687 template<typename C> static inline C 00688 diff_op (const C& me, const C& x, const C& y) { 00689 (void) me; return (derive (x)*y - x*derive (y)) / square (y); } 00690 static inline nat nr_init () { return 0; } 00691 template<typename C> static inline C 00692 def (const C& me, const C& f, const C& g) { 00693 if (g[0] == 0) { 00694 nat val; 00695 for (val=0; g[val]==0; val++) 00696 ASSERT (val != C::get_cancel_order (), 00697 "valuation of denominator too high"); 00698 return rshiftz (f, (int) val) / rshiftz (g, (int) val); 00699 } 00700 return (f - lshiftz (me * rshiftz (g))) / g[0]; } 00701 }; 00702 00703 struct rdiv_op { 00704 static generic name () { return GEN_OVER; } 00705 template<typename C,typename S> static inline C 00706 op (const C& x, const S& y) { return x / y; } 00707 template<typename C,typename S> static inline void 00708 set_op (C& x, const S& y) { x /= y; } 00709 template<typename R, typename C1, typename C2> static inline void 00710 set_op (R& x, const C1& y1, const C2& y2) { div (x, y1, y2); } 00711 template<typename C,typename S> static inline C 00712 diff_op (const C& me, const C& x, const S& y) { 00713 (void) me; return derive (x) / y; } 00714 }; 00715 00716 struct ldiv_op { 00717 static generic name () { return GEN_OVER; } 00718 template<typename C,typename S> static inline C 00719 op (const C& y, const S& x) { return x / y; } 00720 template<typename R, typename C1, typename C2> static inline void 00721 set_op (R& x, const C1& y2, const C2& y1) { div (x, y1, y2); } 00722 template<typename C,typename S> static inline C 00723 diff_op (const C& me, const C& y, const S& x) { 00724 (void) me; return -x * derive (y) / square (y); } 00725 }; 00726 00727 struct quo_op { 00728 static generic name () { return GEN_DIV; } 00729 template<typename C> static inline C 00730 op (const C& x, const C& y) { return quo (x, y); } 00731 template<typename R, typename C1, typename C2> static inline void 00732 set_op (R& x, const C1& y1, const C2& y2) { x= quo (y1, y2); } 00733 static inline nat nr_init () { return 0; } 00734 template<typename C> static inline C 00735 def (const C& me, const C& f, const C& g) { 00736 if (g[0] == 0) { 00737 nat val; 00738 for (val=0; g[val]==0; val++) 00739 if (val == C::get_cancel_order ()) return 0; 00740 return quo (rshiftz (f, (int) val), rshiftz (g, (int) val)); 00741 } 00742 return quo (f - lshiftz (me * rshiftz (g)), g[0]); } 00743 }; 00744 00745 struct pquo_op { 00746 static generic name () { return "pquo"; } 00747 template<typename C> static inline C 00748 op (const C& x, const C& y) { return pquo (x, y); } 00749 template<typename R, typename C1, typename C2> static inline void 00750 set_op (R& x, const C1& y1, const C2& y2) { x= pquo (y1, y2); } 00751 }; 00752 00753 struct rquo_op { 00754 static generic name () { return GEN_DIV; } 00755 template<typename C,typename S> static inline C 00756 op (const C& x, const S& y) { return quo (x, y); } 00757 template<typename R, typename C1, typename C2> static inline void 00758 set_op (R& x, const C1& y1, const C2& y2) { x= quo (y1, y2); } 00759 }; 00760 00761 struct rem_op { 00762 static generic name () { return GEN_MOD; } 00763 template<typename C> static inline C 00764 op (const C& x, const C& y) { return rem (x, y); } 00765 template<typename R, typename C1, typename C2> static inline void 00766 set_op (R& x, const C1& y1, const C2& y2) { x= rem (y1, y2); } 00767 template<typename C> static inline C 00768 op (const C& x, const C& y, nat n) { return rem (x, y); } 00769 }; 00770 00771 struct prem_op { 00772 static generic name () { return "prem"; } 00773 template<typename C> static inline C 00774 op (const C& x, const C& y) { return prem (x, y); } 00775 template<typename R, typename C1, typename C2> static inline void 00776 set_op (R& x, const C1& y1, const C2& y2) { x= prem (y1, y2); } 00777 template<typename C> static inline C 00778 op (const C& x, const C& y, nat n) { 00779 if (x == 0 || y == 0) return x; 00780 nat m= deg (y); 00781 C z= m >= n ? C(1) : C(binpow (y[m], n - m)); 00782 return z * prem (x, y); } 00783 }; 00784 00785 struct rrem_op { 00786 static generic name () { return GEN_MOD; } 00787 template<typename C,typename S> static inline C 00788 op (const C& x, const S& y) { return rem (x, y); } 00789 template<typename R, typename C1, typename C2> static inline void 00790 set_op (R& x, const C1& y1, const C2& y2) { x= rem (y1, y2); } 00791 }; 00792 00793 struct lshift2_op { 00794 template<typename C,typename S> static inline C 00795 op (const C& x, const S& sh) { return lshift2 (x, sh); } 00796 template<typename C,typename S> static inline void 00797 set_op (C& x, const S& sh) { lshift2_assign (x, sh); } 00798 template<typename R, typename C1, typename C2> static inline void 00799 set_op (R& x, const C1& y1, const C2& y2) { lshift2 (x, y1, y2); } 00800 }; 00801 00802 struct rshift2_op { 00803 template<typename C,typename S> static inline C 00804 op (const C& x, const S& sh) { return rshift2 (x, sh); } 00805 template<typename C,typename S> static inline void 00806 set_op (C& x, const S& sh) { rshift2_assign (x, sh); } 00807 template<typename R, typename C1, typename C2> static inline void 00808 set_op (R& x, const C1& y1, const C2& y2) { rshift2 (x, y1, y2); } 00809 }; 00810 00811 struct lshiftz_op { 00812 template<typename C,typename S> static inline C 00813 op (const C& x, const S& sh) { return lshiftz (x, sh); } 00814 template<typename C,typename S> static inline void 00815 set_op (C& x, const S& sh) { lshiftz_assign (x, sh); } 00816 template<typename R, typename C1, typename C2> static inline void 00817 set_op (R& x, const C1& y1, const C2& y2) { lshiftz (x, y1, y2); } 00818 }; 00819 00820 struct rshiftz_op { 00821 template<typename C,typename S> static inline C 00822 op (const C& x, const S& sh) { return rshiftz (x, sh); } 00823 template<typename C,typename S> static inline void 00824 set_op (C& x, const S& sh) { rshiftz_assign (x, sh); } 00825 template<typename R, typename C1, typename C2> static inline void 00826 set_op (R& x, const C1& y1, const C2& y2) { rshiftz (x, y1, y2); } 00827 }; 00828 00829 struct incexp2_op { 00830 template<typename C,typename S> static inline C 00831 op (const C& x, const S& sh) { return incexp2 (x, sh); } 00832 template<typename C,typename S> static inline void 00833 set_op (C& x, const S& sh) { incexp2_assign (x, sh); } 00834 template<typename R, typename C1, typename C2> static inline void 00835 set_op (R& x, const C1& y1, const C2& y2) { incexp2 (x, y1, y2); } 00836 }; 00837 00838 struct decexp2_op { 00839 template<typename C,typename S> static inline C 00840 op (const C& x, const S& sh) { return decexp2 (x, sh); } 00841 template<typename C,typename S> static inline void 00842 set_op (C& x, const S& sh) { decexp2_assign (x, sh); } 00843 template<typename R, typename C1, typename C2> static inline void 00844 set_op (R& x, const C1& y1, const C2& y2) { decexp2 (x, y1, y2); } 00845 }; 00846 00847 struct or_op { 00848 template<typename C> static inline C 00849 neutral () { return false; } 00850 template<typename R> static inline void 00851 set_neutral (R& r) { set_false (r); } 00852 template<typename C> static inline C 00853 op (const C& x, const C& y) { return x | y; } 00854 template<typename R, typename C> static inline void 00855 set_op (R& x, const C& y) { x |= y; } 00856 template<typename R, typename C1, typename C2> static inline void 00857 set_op (R& x, const C1& y1, const C2& y2) { x= y1 | y2; } 00858 }; 00859 00860 struct and_op { 00861 template<typename C> static inline C 00862 neutral () { return true; } 00863 template<typename R> static inline void 00864 set_neutral (R& r) { set_true (r); } 00865 template<typename C> static inline C 00866 op (const C& x, const C& y) { return x & y; } 00867 template<typename R, typename C> static inline void 00868 set_op (R& x, const C& y) { x &= y; } 00869 template<typename R, typename C1, typename C2> static inline void 00870 set_op (R& x, const C1& y1, const C2& y2) { x= y1 & y2; } 00871 }; 00872 00873 /****************************************************************************** 00874 * Extra arithmetic operators 00875 ******************************************************************************/ 00876 00877 struct gcd_op { 00878 static generic name () { return GEN_GCD; } 00879 template<typename C> static inline C 00880 neutral () { return C(0); } 00881 template<typename R> static inline void 00882 set_neutral (R& r) { set_zero (r); } 00883 template<typename C> static inline C 00884 op (const C& x, const C& y) { return gcd (x, y); } 00885 template<typename R, typename C> static inline void 00886 set_op (R& x, const C& y) { x= gcd (x, y); } 00887 template<typename R, typename C1, typename C2> static inline void 00888 set_op (R& x, const C1& y1, const C2& y2) { x= gcd (y1, y2); } 00889 }; 00890 00891 struct lcm_op { 00892 static generic name () { return GEN_LCM; } 00893 template<typename C> static inline C 00894 neutral () { return C(1); } 00895 template<typename R> static inline void 00896 set_neutral (R& r) { set_one (r); } 00897 template<typename C> static inline C 00898 op (const C& x, const C& y) { return lcm (x, y); } 00899 template<typename R, typename C> static inline void 00900 set_op (R& x, const C& y) { x= lcm (x, y); } 00901 template<typename R, typename C1, typename C2> static inline void 00902 set_op (R& x, const C1& y1, const C2& y2) { x= lcm (y1, y2); } 00903 }; 00904 00905 template<typename C> struct xgcd_matrix; 00906 00907 struct xgcd_op { 00908 template<typename C> static inline xgcd_matrix<C> 00909 op (const C& x, const C& y) { return xgcd (x, y); } 00910 template<typename R, typename C1, typename C2> static inline void 00911 set_op (R& x, const C1& y1, const C2& y2) { x= xgcd (y1, y2); } 00912 }; 00913 00914 /****************************************************************************** 00915 * Predicates 00916 ******************************************************************************/ 00917 00918 struct hard_eq_op { // hard equality in memory 00919 static generic name () { return GEN_HARD_EQ; } 00920 template<typename C> static inline bool 00921 op (const C& x, const C& y) { return hard_eq (x, y); } 00922 static inline syntactic 00923 op (const syntactic& x, const syntactic& y) { return apply (name(), x, y); } 00924 template<typename C> static inline bool 00925 not_op (const C& x, const C& y) { return hard_neq (x, y); } 00926 template<typename C> static inline nat 00927 hash_op (const C& x) { return hard_hash (x); } 00928 }; 00929 00930 struct hard_neq_op { // hard inequality in memory 00931 static generic name () { return GEN_HARD_NEQ; } 00932 template<typename C> static inline bool 00933 op (const C& x, const C& y) { return hard_neq (x, y); } 00934 static inline syntactic 00935 op (const syntactic& x, const syntactic& y) { return apply (name(), x, y); } 00936 template<typename C> static inline bool 00937 not_op (const C& x, const C& y) { return hard_eq (x, y); } 00938 template<typename C> static inline nat 00939 hash_op (const C& x) { return hard_hash (x); } 00940 }; 00941 00942 struct hard_less_op { // hard address comparaison 00943 static generic name () { return GEN_HARD_LESS; } 00944 template<typename C> static inline bool 00945 op (const C& x, const C& y) { return hard_less (x, y); } 00946 }; 00947 00948 struct hard_gtr_op { // hard address comparaison 00949 static generic name () { return GEN_HARD_GTR; } 00950 template<typename C> static inline bool 00951 op (const C& x, const C& y) { return hard_gtr (x, y); } 00952 }; 00953 00954 struct exact_eq_op { // syntactic equality 00955 static generic name () { return GEN_EXACT_EQ; } 00956 template<typename C> static inline bool 00957 op (const C& x, const C& y) { return exact_eq (x, y); } 00958 static inline syntactic 00959 op (const syntactic& x, const syntactic& y) { return apply (name(), x, y); } 00960 template<typename C> static inline bool 00961 not_op (const C& x, const C& y) { return exact_neq (x, y); } 00962 template<typename C> static inline nat 00963 hash_op (const C& x) { return exact_hash (x); } 00964 }; 00965 00966 struct exact_neq_op { // syntactic inequality 00967 static generic name () { return GEN_EXACT_NEQ; } 00968 template<typename C> static inline bool 00969 op (const C& x, const C& y) { return exact_neq (x, y); } 00970 static inline syntactic 00971 op (const syntactic& x, const syntactic& y) { return apply (name(), x, y); } 00972 template<typename C> static inline bool 00973 not_op (const C& x, const C& y) { return exact_eq (x, y); } 00974 template<typename C> static inline nat 00975 hash_op (const C& x) { return exact_hash (x); } 00976 }; 00977 00978 struct equal_op { 00979 static generic name () { return GEN_EQUAL; } 00980 template<typename C> static inline bool 00981 op (const C& x, const C& y) { return x == y; } 00982 static inline syntactic 00983 op (const syntactic& x, const syntactic& y) { return apply (name(), x, y); } 00984 template<typename C> static inline bool 00985 not_op (const C& x, const C& y) { return x != y; } 00986 template<typename C> static inline nat 00987 hash_op (const C& x) { return hash (x); } 00988 }; 00989 00990 struct unequal_op { 00991 static generic name () { return GEN_UNEQUAL; } 00992 template<typename C> static inline bool 00993 op (const C& x, const C& y) { return x != y; } 00994 static inline syntactic 00995 op (const syntactic& x, const syntactic& y) { return apply (name(), x, y); } 00996 template<typename C> static inline bool 00997 not_op (const C& x, const C& y) { return x == y; } 00998 template<typename C> static inline nat 00999 hash_op (const C& x) { return hash (x); } 01000 }; 01001 01002 struct less_op { 01003 static generic name () { return GEN_LESS; } 01004 template<typename C> static inline bool 01005 op (const C& x, const C& y) { return x < y; } 01006 static inline syntactic 01007 op (const syntactic& x, const syntactic& y) { return apply (name(), x, y); } 01008 template<typename C> static inline bool 01009 not_op (const C& x, const C& y) { return !(x < y); } 01010 }; 01011 01012 struct lesseq_op { 01013 static generic name () { return GEN_LESSEQ; } 01014 template<typename C> static inline bool 01015 op (const C& x, const C& y) { return x <= y; } 01016 static inline syntactic 01017 op (const syntactic& x, const syntactic& y) { return apply (name(), x, y); } 01018 template<typename C> static inline bool 01019 not_op (const C& x, const C& y) { return !(x <= y); } 01020 }; 01021 01022 struct gtr_op { 01023 static generic name () { return GEN_GTR; } 01024 template<typename C> static inline bool 01025 op (const C& x, const C& y) { return x > y; } 01026 static inline syntactic 01027 op (const syntactic& x, const syntactic& y) { return apply (name(), x, y); } 01028 template<typename C> static inline bool 01029 not_op (const C& x, const C& y) { return !(x > y); } 01030 }; 01031 01032 struct gtreq_op { 01033 static generic name () { return GEN_GTREQ; } 01034 template<typename C> static inline bool 01035 op (const C& x, const C& y) { return x >= y; } 01036 static inline syntactic 01037 op (const syntactic& x, const syntactic& y) { return apply (name(), x, y); } 01038 template<typename C> static inline bool 01039 not_op (const C& x, const C& y) { return !(x >= y); } 01040 }; 01041 01042 /****************************************************************************** 01043 * Ordering related operators 01044 ******************************************************************************/ 01045 01046 struct min_op { 01047 static generic name () { return GEN_MIN; } 01048 template<typename C> static inline C 01049 neutral () { return Maximal (C); } 01050 template<typename R> static inline void 01051 set_neutral (R& x) { set_maximal (x); } 01052 template<typename C> static inline C 01053 op (const C& x, const C& y) { return min (x, y); } 01054 template<typename R, typename C> static inline void 01055 set_op (R& x, const C& y) { x= min (x, y); } 01056 template<typename R, typename C1, typename C2> static inline void 01057 set_op (R& x, const C1& y1, const C2& y2) { x= min (y1, y2); } 01058 }; 01059 01060 struct max_op { 01061 static generic name () { return GEN_MAX; } 01062 template<typename C> static inline C 01063 neutral () { return Minimal (C); } 01064 template<typename R> static inline void 01065 set_neutral (R& x) { set_minimal (x); } 01066 template<typename C> static inline C 01067 op (const C& x, const C& y) { return max (x, y); } 01068 template<typename R, typename C> static inline void 01069 set_op (R& x, const C& y) { x= max (x, y); } 01070 template<typename R, typename C1, typename C2> static inline void 01071 set_op (R& x, const C1& y1, const C2& y2) { x= max (y1, y2); } 01072 }; 01073 01074 struct inf_op { 01075 static generic name () { return GEN_INF; } 01076 template<typename C> static inline C 01077 neutral () { return Maximal (C); } 01078 template<typename R> static inline void 01079 set_neutral (R& x) { set_maximal (x); } 01080 template<typename C> static inline C 01081 op (const C& x, const C& y) { return inf (x, y); } 01082 template<typename R, typename C> static inline void 01083 set_op (R& x, const C& y) { x= inf (x, y); } 01084 template<typename R, typename C1, typename C2> static inline void 01085 set_op (R& x, const C1& y1, const C2& y2) { x= inf (y1, y2); } 01086 }; 01087 01088 struct sup_op { 01089 static generic name () { return GEN_SUP; } 01090 template<typename C> static inline C 01091 neutral () { return Minimal (C); } 01092 template<typename R> static inline void 01093 set_neutral (R& x) { set_minimal (x); } 01094 template<typename C> static inline C 01095 op (const C& x, const C& y) { return sup (x, y); } 01096 template<typename R, typename C> static inline void 01097 set_op (R& x, const C& y) { x= sup (x, y); } 01098 template<typename R, typename C1, typename C2> static inline void 01099 set_op (R& x, const C1& y1, const C2& y2) { x= sup (y1, y2); } 01100 }; 01101 01102 struct abs_op { 01103 static generic name () { return GEN_ABS; } 01104 template<typename C> static inline Abs_type(C) 01105 op (const C& x) { return abs (x); } 01106 static inline generic 01107 op (const generic& x) { return abs (x); } 01108 static inline syntactic 01109 op (const syntactic& x) { return abs (x); } 01110 template<typename R, typename C> static inline void 01111 set_op (R& x, const C& y) { x= abs (y); } 01112 }; 01113 01114 struct abs_as_op { 01115 static generic name () { return GEN_ABS; } 01116 template<typename R, typename C> static inline R 01117 op (const C& x) { return as<R> (abs (x)); } 01118 template<typename R, typename C> static inline void 01119 set_op (R& x, const C& y) { x= as<R> (abs (y)); } 01120 }; 01121 01122 REPLACEABLE_RETURN(abs_as_op); 01123 01124 struct sign_op { 01125 static generic name () { return GEN_SIGN; } 01126 template<typename C> static inline int 01127 op (const C& x) { return sign (x); } 01128 static inline generic 01129 op (const generic& x) { return gen (GEN_SIGN, x); } 01130 static inline syntactic 01131 op (const syntactic& x) { return apply (GEN_SIGN, x); } 01132 template<typename C> static inline void 01133 set_op (int& x, const C& y) { x= sign (y); } 01134 }; 01135 01136 /****************************************************************************** 01137 * Elementary functions 01138 ******************************************************************************/ 01139 01140 struct sqrt_op { 01141 static generic name () { return GEN_SQRT; } 01142 template<typename C> static inline C 01143 op (const C& x) { return sqrt (x); } 01144 template<typename R, typename C> static inline void 01145 set_op (R& x, const C& y) { x= sqrt (y); } 01146 template<typename C, typename I> static inline C 01147 op_init (const C& x, const I& i) { return sqrt_init (x, i); } 01148 template<typename C> static inline C 01149 diff_op (const C& me, const C& x) { 01150 return derive (x) / (2 * me); } 01151 static inline nat nr_init () { return 1; } 01152 template<typename C> static inline C 01153 def (const C& me, const C& f) { 01154 if (f[0] == 0) { 01155 nat val= 0; 01156 for (val=0; val< C::get_cancel_order () && f[val]==0; val++); 01157 ASSERT (val< C::get_cancel_order () , "valuation too high"); 01158 ASSERT ((val&1) == 0, "square root is not a series"); 01159 return lshiftz (sqrt (rshiftz (f, (int) val)), (int) (val/2)); 01160 } 01161 return integrate (derive (f) / (2*me)); } 01162 }; 01163 01164 struct cbrt_op { 01165 static generic name () { return GEN_CBRT; } 01166 template<typename C> static inline C 01167 op (const C& x) { return cbrt (x); } 01168 template<typename R, typename C> static inline void 01169 set_op (R& x, const C& y) { x= cbrt (y); } 01170 }; 01171 01172 struct hypot_op { 01173 static generic name () { return GEN_HYPOT; } 01174 template<typename C> static inline C 01175 op (const C& x, const C& y) { return hypot (x, y); } 01176 template<typename R, typename C1, typename C2> static inline void 01177 set_op (R& x, const C1& y1, const C2& y2) { x= hypot (y1, y2); } 01178 }; 01179 01180 struct exp_op { 01181 static generic name () { return GEN_EXP; } 01182 template<typename C> static inline C 01183 op (const C& x) { return exp (x); } 01184 template<typename R, typename C> static inline void 01185 set_op (R& x, const C& y) { x= exp (y); } 01186 template<typename C, typename I> static inline C 01187 op_init (const C& x, const I& i) { (void) i; return exp (x); } 01188 template<typename C> static inline C 01189 diff_op (const C& me, const C& x) { 01190 return derive (x) * me; } 01191 static inline nat nr_init () { return 1; } 01192 template<typename C> static inline C 01193 def (const C& me, const C& f) { 01194 return integrate (diff_op (me, f)); } 01195 }; 01196 01197 struct exp2_op { 01198 static generic name () { return GEN_EXP2; } 01199 template<typename C> static inline C 01200 op (const C& x) { return exp2 (x); } 01201 template<typename R, typename C> static inline void 01202 set_op (R& x, const C& y) { x= exp2 (y); } 01203 }; 01204 01205 struct exp10_op { 01206 static generic name () { return GEN_EXP10; } 01207 template<typename C> static inline C 01208 op (const C& x) { return exp10 (x); } 01209 template<typename R, typename C> static inline void 01210 set_op (R& x, const C& y) { x= exp10 (y); } 01211 }; 01212 01213 struct log_op { 01214 static generic name () { return GEN_LOG; } 01215 template<typename C> static inline C 01216 op (const C& x) { return log (x); } 01217 template<typename R, typename C> static inline void 01218 set_op (R& x, const C& y) { x= log (y); } 01219 template<typename C,typename I> static inline C 01220 op_init (const C& x, const I& i) { return log_init (x, i); } 01221 template<typename C> static inline C 01222 diff_op (const C& me, const C& x) { 01223 (void) me; return derive (x) / x; } 01224 static inline nat nr_init () { return 1; } 01225 template<typename C> static inline C 01226 def (const C& me, const C& f) { 01227 return integrate (diff_op (me, f)); } 01228 }; 01229 01230 struct log2_op { 01231 static generic name () { return GEN_LOG2; } 01232 template<typename C> static inline C 01233 op (const C& x) { return log2 (x); } 01234 template<typename R, typename C> static inline void 01235 set_op (R& x, const C& y) { x= log2 (y); } 01236 }; 01237 01238 struct log10_op { 01239 static generic name () { return GEN_LOG10; } 01240 template<typename C> static inline C 01241 op (const C& x) { return log10 (x); } 01242 template<typename R, typename C> static inline void 01243 set_op (R& x, const C& y) { x= log10 (y); } 01244 }; 01245 01246 struct pow_op { 01247 static generic name () { return GEN_POWER; } 01248 template<typename C1, typename C2> static inline C1 01249 op (const C1& x, const C2& y) { return pow (x, y); } 01250 template<typename R, typename C1, typename C2> static inline void 01251 set_op (R& x, const C1& y1, const C2& y2) { x= pow (y1, y2); } 01252 }; 01253 01254 typedef pow_op rpow_op; 01255 01256 struct lpow_op { 01257 static generic name () { return GEN_POWER; } 01258 template<typename C1, typename C2> static inline C1 01259 op (const C1& y, const C2& x) { return pow (x, y); } 01260 template<typename R, typename C1, typename C2> static inline void 01261 set_op (R& x, const C1& y2, const C2& y1) { x= pow (y1, y2); } 01262 }; 01263 01264 struct trig_op { 01265 template<typename C> static inline C 01266 op (const C& x) { return trig (x); } 01267 template<typename R, typename C> static inline void 01268 set_op (R& x, const C& y) { x= trig (y); } 01269 template<typename C, typename I> static inline C 01270 op_init (const C& x, const I& i) { (void) i; return trig (x); } 01271 static inline generic 01272 op (const generic& x) { return xsqtuple (comma (cos (x), sin (x))); } 01273 static inline syntactic 01274 op (const syntactic& x) { return as_syntactic (op (as_generic (x))); } 01275 template<typename C> static inline C 01276 diff_op (const C& me, const C& x); 01277 static inline nat nr_init () { return 1; } 01278 template<typename V,typename C> static inline V 01279 def (const V& me, const C& f) { 01280 return integrate (diff_op (me, f)); } 01281 }; 01282 01283 struct cos_op { 01284 static generic name () { return GEN_COS; } 01285 template<typename C> static inline C 01286 op (const C& x) { return cos (x); } 01287 template<typename R, typename C> static inline void 01288 set_op (R& x, const C& y) { x= cos (y); } 01289 template<typename C, typename I> static inline C 01290 op_init (const C& x, const I& i) { (void) i; return cos (x); } 01291 template<typename C> static inline C 01292 diff_op (const C& me, const C& x) { 01293 (void) me; return -derive (x) * sin (x); } 01294 static inline nat nr_init () { return 1; } 01295 template<typename C> static inline C 01296 def (const C& me, const C& f) { 01297 (void) me; return cos_sin (f) [0]; } 01298 }; 01299 01300 struct sin_op { 01301 static generic name () { return GEN_SIN; } 01302 template<typename C> static inline C 01303 op (const C& x) { return sin (x); } 01304 template<typename R, typename C> static inline void 01305 set_op (R& x, const C& y) { x= sin (y); } 01306 template<typename C, typename I> static inline C 01307 op_init (const C& x, const I& i) { (void) i; return sin (x); } 01308 template<typename C> static inline C 01309 diff_op (const C& me, const C& x) { 01310 (void) me; return derive (x) * cos (x); } 01311 static inline nat nr_init () { return 1; } 01312 template<typename C> static inline C 01313 def (const C& me, const C& f) { 01314 (void) me; return cos_sin (f) [1]; } 01315 }; 01316 01317 struct tan_op { 01318 static generic name () { return GEN_TAN; } 01319 template<typename C> static inline C 01320 op (const C& x) { return tan (x); } 01321 template<typename R, typename C> static inline void 01322 set_op (R& x, const C& y) { x= tan (y); } 01323 template<typename C, typename I> static inline C 01324 op_init (const C& x, const I& i) { (void) i; return tan (x); } 01325 template<typename C> static inline C 01326 diff_op (const C& me, const C& x) { 01327 (void) me; return derive (x) / square (cos (x)); } 01328 static inline nat nr_init () { return 1; } 01329 template<typename C> static inline C 01330 def (const C& me, const C& f); 01331 }; 01332 01333 struct acos_op { 01334 static generic name () { return GEN_ARCCOS; } 01335 template<typename C> static inline C 01336 op (const C& x) { return acos (x); } 01337 template<typename R, typename C> static inline void 01338 set_op (R& x, const C& y) { x= acos (y); } 01339 template<typename C, typename I> static inline C 01340 op_init (const C& x, const I& i) { return acos_init (x, i); } 01341 template<typename C> static inline C 01342 diff_op (const C& me, const C& x) { 01343 (void) me; return -derive (x) / sqrt (1 - square (x)); } 01344 static inline nat nr_init () { return 1; } 01345 template<typename C> static inline C 01346 def (const C& me, const C& f) { 01347 return integrate (diff_op (me, f)); } 01348 }; 01349 01350 struct asin_op { 01351 static generic name () { return GEN_ARCSIN; } 01352 template<typename C> static inline C 01353 op (const C& x) { return asin (x); } 01354 template<typename R, typename C> static inline void 01355 set_op (R& x, const C& y) { x= asin (y); } 01356 template<typename C, typename I> static inline C 01357 op_init (const C& x, const I& i) { return asin_init (x, i); } 01358 template<typename C> static inline C 01359 diff_op (const C& me, const C& x) { 01360 (void) me; return derive (x) / sqrt (1 - square (x)); } 01361 static inline nat nr_init () { return 1; } 01362 template<typename C> static inline C 01363 def (const C& me, const C& f) { 01364 return integrate (diff_op (me, f)); } 01365 }; 01366 01367 struct atan_op { 01368 static generic name () { return GEN_ARCTAN; } 01369 template<typename C> static inline C 01370 op (const C& x) { return atan (x); } 01371 template<typename R, typename C> static inline void 01372 set_op (R& x, const C& y) { x= atan (y); } 01373 template<typename C, typename I> static inline C 01374 op_init (const C& x, const I& i) { return atan_init (x, i); } 01375 template<typename C> static inline C 01376 diff_op (const C& me, const C& x) { 01377 (void) me; return derive (x) / (square (x) + 1); } 01378 static inline nat nr_init () { return 1; } 01379 template<typename C> static inline C 01380 def (const C& me, const C& f) { 01381 return integrate (diff_op (me, f)); } 01382 }; 01383 01384 struct atan2_op { 01385 static generic name () { return GEN_ARCTAN2; } 01386 template<typename C> static inline C 01387 op (const C& x, const C& y) { return atan2 (x, y); } 01388 template<typename R, typename C1, typename C2> static inline void 01389 set_op (R& x, const C1& y1, const C2& y2) { x= atan2 (y1, y2); } 01390 }; 01391 01392 struct cosh_op { 01393 static generic name () { return GEN_CH; } 01394 template<typename C> static inline C 01395 op (const C& x) { return cosh (x); } 01396 template<typename R, typename C> static inline void 01397 set_op (R& x, const C& y) { x= cosh (y); } 01398 template<typename C, typename I> static inline C 01399 op_init (const C& x, const I& i) { (void) i; return cosh (x); } 01400 template<typename C> static inline C 01401 diff_op (const C& me, const C& x) { 01402 (void) me; return derive (x) * sinh (x); } 01403 }; 01404 01405 struct sinh_op { 01406 static generic name () { return GEN_SH; } 01407 template<typename C> static inline C 01408 op (const C& x) { return sinh (x); } 01409 template<typename R, typename C> static inline void 01410 set_op (R& x, const C& y) { x= sinh (y); } 01411 template<typename C, typename I> static inline C 01412 op_init (const C& x, const I& i) { (void) i; return sinh (x); } 01413 template<typename C> static inline C 01414 diff_op (const C& me, const C& x) { 01415 (void) me; return derive (x) * cosh (x); } 01416 }; 01417 01418 struct tanh_op { 01419 static generic name () { return GEN_TH; } 01420 template<typename C> static inline C 01421 op (const C& x) { return tanh (x); } 01422 template<typename R, typename C> static inline void 01423 set_op (R& x, const C& y) { x= tanh (y); } 01424 template<typename C, typename I> static inline C 01425 op_init (const C& x, const I& i) { (void) i; return tanh (x); } 01426 template<typename C> static inline C 01427 diff_op (const C& me, const C& x) { 01428 (void) me; return derive (x) / square (cosh (x)); } 01429 }; 01430 01431 struct acosh_op { 01432 static generic name () { return GEN_ARGCH; } 01433 template<typename C> static inline C 01434 op (const C& x) { return acosh (x); } 01435 template<typename R, typename C> static inline void 01436 set_op (R& x, const C& y) { x= acosh (y); } 01437 template<typename C, typename I> static inline C 01438 op_init (const C& x, const I& i) { return acosh_init (x, i); } 01439 template<typename C> static inline C 01440 diff_op (const C& me, const C& x) { 01441 (void) me; return derive (x) / sqrt (square (x) - 1); } 01442 }; 01443 01444 struct asinh_op { 01445 static generic name () { return GEN_ARGSH; } 01446 template<typename C> static inline C 01447 op (const C& x) { return asinh (x); } 01448 template<typename R, typename C> static inline void 01449 set_op (R& x, const C& y) { x= asinh (y); } 01450 template<typename C, typename I> static inline C 01451 op_init (const C& x, const I& i) { return asinh_init (x, i); } 01452 template<typename C> static inline C 01453 diff_op (const C& me, const C& x) { 01454 (void) me; return derive (x) / sqrt (square (x) + 1); } 01455 }; 01456 01457 struct atanh_op { 01458 static generic name () { return GEN_ARGTH; } 01459 template<typename C> static inline C 01460 op (const C& x) { return atanh (x); } 01461 template<typename R, typename C> static inline void 01462 set_op (R& x, const C& y) { x= atanh (y); } 01463 template<typename C, typename I> static inline C 01464 op_init (const C& x, const I& i) { return atanh_init (x, i); } 01465 template<typename C> static inline C 01466 diff_op (const C& me, const C& x) { 01467 (void) me; return derive (x) / (1 - square (x)); } 01468 }; 01469 01470 /****************************************************************************** 01471 * Special functions 01472 ******************************************************************************/ 01473 01474 struct gamma_op { 01475 static generic name () { return GEN_GAMMA; } 01476 template<typename C> static inline C 01477 op (const C& x) { return gamma (x); } 01478 template<typename R, typename C> static inline void 01479 set_op (R& x, const C& y) { x= gamma (y); } 01480 }; 01481 01482 struct zeta_op { 01483 static generic name () { return GEN_ZETA; } 01484 template<typename C> static inline C 01485 op (const C& x) { return zeta (x); } 01486 template<typename R, typename C> static inline void 01487 set_op (R& x, const C& y) { x= zeta (y); } 01488 }; 01489 01490 struct erf_op { 01491 static generic name () { return GEN_ERF; } 01492 template<typename C> static inline C 01493 op (const C& x) { return erf (x); } 01494 template<typename R, typename C> static inline void 01495 set_op (R& x, const C& y) { x= erf (y); } 01496 }; 01497 01498 /****************************************************************************** 01499 * Special operations for approximate and rounded arithmetic 01500 ******************************************************************************/ 01501 01502 struct is_finite_op { 01503 template<typename T> static inline bool 01504 op (const T& x) { return is_finite (x); } 01505 template<typename T> static inline bool 01506 not_op (const T& x) { return !is_finite (x); } 01507 }; 01508 01509 struct is_infinite_op { 01510 template<typename T> static inline bool 01511 op (const T& x) { return is_infinite (x); } 01512 template<typename T> static inline bool 01513 not_op (const T& x) { return !is_infinite (x); } 01514 }; 01515 01516 struct is_fuzz_op { 01517 template<typename T> static inline bool 01518 op (const T& x) { return is_fuzz (x); } 01519 template<typename T> static inline bool 01520 not_op (const T& x) { return !is_fuzz (x); } 01521 }; 01522 01523 struct is_nan_op { 01524 template<typename T> static inline bool 01525 op (const T& x) { return is_nan (x); } 01526 template<typename T> static inline bool 01527 not_op (const T& x) { return !is_nan (x); } 01528 }; 01529 01530 struct is_reliable_op { 01531 // Returns true for ball and interval types, as well as exact types 01532 template<typename T> static inline bool 01533 op (const T& x) { return is_reliable (x); } 01534 template<typename T> static inline bool 01535 not_op (const T& x) { return !is_reliable (x); } 01536 }; 01537 01538 struct and_is_finite_op { 01539 template<typename B> static inline B 01540 neutral () { return true; } 01541 template<typename R> static inline void 01542 set_neutral (R& r) { set_true (r); } 01543 template<typename B, typename C> static inline void 01544 set_op (B& x, const C& y) { x= x && is_finite (y); } 01545 template<typename T> static inline bool 01546 op (const T& x) { return is_finite (x); } 01547 }; 01548 01549 struct or_is_infinite_op { 01550 template<typename B> static inline B 01551 neutral () { return false; } 01552 template<typename R> static inline void 01553 set_neutral (R& r) { set_false (r); } 01554 template<typename B, typename C> static inline void 01555 set_op (B& x, const C& y) { x= x || is_infinite (y); } 01556 template<typename T> static inline bool 01557 op (const T& x) { return is_infinite (x); } 01558 }; 01559 01560 struct or_is_fuzz_op { 01561 template<typename B> static inline B 01562 neutral () { return false; } 01563 template<typename R> static inline void 01564 set_neutral (R& r) { set_false (r); } 01565 template<typename B, typename C> static inline void 01566 set_op (B& x, const C& y) { x= x || is_fuzz (y); } 01567 template<typename T> static inline bool 01568 op (const T& x) { return is_fuzz (x); } 01569 }; 01570 01571 struct or_is_nan_op { 01572 template<typename B> static inline B 01573 neutral () { return false; } 01574 template<typename R> static inline void 01575 set_neutral (R& r) { set_false (r); } 01576 template<typename B, typename C> static inline void 01577 set_op (B& x, const C& y) { x= x || is_nan (y); } 01578 template<typename T> static inline bool 01579 op (const T& x) { return is_nan (x); } 01580 }; 01581 01582 template<typename C> struct unary_return_type_helper<is_finite_op,C> { 01583 typedef bool RET; }; 01584 template<typename C> struct unary_return_type_helper<is_infinite_op,C> { 01585 typedef bool RET; }; 01586 template<typename C> struct unary_return_type_helper<is_fuzz_op,C> { 01587 typedef bool RET; }; 01588 template<typename C> struct unary_return_type_helper<is_nan_op,C> { 01589 typedef bool RET; }; 01590 template<typename C> struct unary_return_type_helper<and_is_finite_op,C> { 01591 typedef bool RET; }; 01592 template<typename C> struct unary_return_type_helper<or_is_infinite_op,C> { 01593 typedef bool RET; }; 01594 template<typename C> struct unary_return_type_helper<or_is_fuzz_op,C> { 01595 typedef bool RET; }; 01596 template<typename C> struct unary_return_type_helper<or_is_nan_op,C> { 01597 typedef bool RET; }; 01598 01599 struct exponent_op { 01600 // Get the exponent of a floating point like number 01601 static generic name () { return GEN_EXPONENT; } 01602 template<typename C> static inline xint 01603 op (const C& x) { return exponent (x); } 01604 template<typename R, typename C> static inline void 01605 set_op (R& x, const C& y) { x= exponent (y); } 01606 }; 01607 01608 struct max_exponent_op { 01609 template<typename C> static inline C 01610 neutral () { return Minimal (C); } 01611 template<typename R> static inline void 01612 set_neutral (R& x) { set_minimal (x); } 01613 template<typename R, typename C> static inline void 01614 set_op (R& x, const C& y) { x= max (x, exponent (y)); } 01615 }; 01616 01617 template<typename C> struct unary_return_type_helper<exponent_op,C> { 01618 typedef xint RET; }; 01619 template<typename C> struct unary_return_type_helper<max_exponent_op,C> { 01620 typedef xint RET; }; 01621 01622 struct magnitude_op { 01623 // Get the fractional exponent of a floating point like number. 01624 // For instance, if z is an ordinary or complex floating point number, 01625 // then its magnitude is given by log2 abs z. 01626 static generic name () { return GEN_MAGNITUDE; } 01627 template<typename C> static inline double 01628 op (const C& x) { return magnitude (x); } 01629 template<typename R, typename C> static inline void 01630 set_op (R& x, const C& y) { x= magnitude (y); } 01631 }; 01632 01633 struct max_magnitude_op { 01634 template<typename C> static inline C 01635 neutral () { return Minimal (C); } 01636 template<typename R> static inline void 01637 set_neutral (R& x) { set_minimal (x); } 01638 template<typename R, typename C> static inline void 01639 set_op (R& x, const C& y) { x= max (x, magnitude (y)); } 01640 }; 01641 01642 template<typename C> struct unary_return_type_helper<magnitude_op,C> { 01643 typedef double RET; }; 01644 template<typename C> struct unary_return_type_helper<max_magnitude_op,C> { 01645 typedef double RET; }; 01646 01647 struct precision_op { 01648 // Get the actual precision of a multiple precision floating point 01649 // like number. For vectorial inputs, we take the minimum over all entries 01650 static generic name () { return GEN_PRECISION; } 01651 template<typename C> static inline xnat 01652 op (const C& x) { return precision (x); } 01653 template<typename R, typename C> static inline void 01654 set_op (R& x, const C& y) { x= precision (y); } 01655 }; 01656 01657 struct min_precision_op { 01658 template<typename C> static inline C 01659 neutral () { return Maximal (C); } 01660 template<typename R> static inline void 01661 set_neutral (R& x) { set_minimal (x); } 01662 template<typename R, typename C> static inline void 01663 set_op (R& x, const C& y) { x= min (x, precision (y)); } 01664 }; 01665 01666 template<typename C> struct unary_return_type_helper<precision_op,C> { 01667 typedef xnat RET; }; 01668 template<typename C> struct unary_return_type_helper<min_precision_op,C> { 01669 typedef xnat RET; }; 01670 01671 struct change_precision_op { 01672 // Change the actual precision of a multiple precision 01673 // floating point like number 01674 static generic name () { return GEN_CHANGE_PRECISION; } 01675 template<typename C> static inline C 01676 op (const C& x, xnat p) { return change_precision (x, p); } 01677 template<typename R, typename C> static inline void 01678 set_op (R& x, const C& y, xnat p) { x= change_precision (y, p); } 01679 }; 01680 01681 struct rounding_error_op { 01682 // When the number x is the result of a floating point computation, 01683 // rounding_error (x) is an upper bound for the distance between x and 01684 // the corresponding exact computation. For instance, for real x, 01685 // taking rounding_error (x) = max (next_above x - x, x - next_below x) 01686 // is potentially slow, but correct for all rounding modes 01687 static generic name () { return GEN_ROUNDING_ERROR; } 01688 template<typename C> static inline Abs_type(C) 01689 op (const C& x) { return rounding_error (x); } 01690 template<typename R, typename C> static inline void 01691 set_op (R& x, const C& y) { x= as<R> (rounding_error (y)); } 01692 }; 01693 01694 struct additive_error_op { 01695 // This is a variant of rounding_error_op to be used in 01696 // the specific cases of addition, subtraction and truncation 01697 static generic name () { return GEN_ADDITIVE_ERROR; } 01698 template<typename C> static inline Abs_type(C) 01699 op (const C& x) { return additive_error (x); } 01700 template<typename R, typename C> static inline void 01701 set_op (R& x, const C& y) { x= as<R> (additive_error (y)); } 01702 }; 01703 01704 struct multiplicative_error_op { 01705 // This is a variant of rounding_error_op to be used in 01706 // the specific cases of multiplication, division, shifting, 01707 // sqrt, hypot and abs 01708 static generic name () { return GEN_MULTIPLICATIVE_ERROR; } 01709 template<typename C> static inline Abs_type(C) 01710 op (const C& x) { return multiplicative_error (x); } 01711 template<typename R, typename C> static inline void 01712 set_op (R& x, const C& y) { x= as<R> (multiplicative_error (y)); } 01713 }; 01714 01715 struct elementary_error_op { 01716 // This is a variant of rounding_error_op to be used in 01717 // the specific cases of elementary functions 01718 static generic name () { return GEN_ELEMENTARY_ERROR; } 01719 template<typename C> static inline Abs_type(C) 01720 op (const C& x) { return elementary_error (x); } 01721 template<typename R, typename C> static inline void 01722 set_op (R& x, const C& y) { x= as<R> (elementary_error (y)); } 01723 }; 01724 01725 struct floor_op { 01726 // closest integer below 01727 static generic name () { return GEN_FLOOR; } 01728 template<typename C> static inline C 01729 op (const C& x) { return floor (x); } 01730 template<typename C> static inline void 01731 set_op (C& x) { x= floor (x); } 01732 template<typename R, typename C> static inline void 01733 set_op (R& x, const C& y) { x= floor (y); } 01734 }; 01735 01736 struct trunc_op { 01737 // closest integer when rounding towards zero 01738 static generic name () { return GEN_TRUNC; } 01739 template<typename C> static inline C 01740 op (const C& x) { return trunc (x); } 01741 template<typename C> static inline void 01742 set_op (C& x) { x= trunc (x); } 01743 template<typename R, typename C> static inline void 01744 set_op (R& x, const C& y) { x= trunc (y); } 01745 }; 01746 01747 struct ceil_op { 01748 // closest integer above 01749 static generic name () { return GEN_CEIL; } 01750 template<typename C> static inline C 01751 op (const C& x) { return ceil (x); } 01752 template<typename C> static inline void 01753 set_op (C& x) { x= ceil (x); } 01754 template<typename R, typename C> static inline void 01755 set_op (R& x, const C& y) { x= ceil (y); } 01756 }; 01757 01758 struct round_op { 01759 // closest integer 01760 static generic name () { return GEN_ROUND; } 01761 template<typename C> static inline C 01762 op (const C& x) { return round (x); } 01763 template<typename C> static inline void 01764 set_op (C& x) { x= round (x); } 01765 template<typename R, typename C> static inline void 01766 set_op (R& x, const C& y) { x= round (y); } 01767 }; 01768 01769 /****************************************************************************** 01770 * Operators on complex number like types 01771 ******************************************************************************/ 01772 01773 struct gaussian_op { 01774 static generic name () { return GEN_GAUSSIAN; } 01775 template<typename C> static inline Complex_type(C) 01776 op (const C& x, const C& y) { return gaussian (x, y); } 01777 static inline generic 01778 op (const generic& x, const generic& y) { return gaussian (x, y); } 01779 static inline syntactic 01780 op (const syntactic& x, const syntactic& y) { return gaussian (x, y); } 01781 template<typename R, typename C1, typename C2> static inline void 01782 set_op (R& x, const C1& y1, const C2& y2) { gaussian_as (x, y1, y2); } 01783 }; 01784 01785 struct polar_op { 01786 static generic name () { return GEN_POLAR; } 01787 template<typename C> static inline Complex_type(C) 01788 op (const C& x, const C& y) { return polar (x, y); } 01789 static inline generic 01790 op (const generic& x, const generic& y) { return polar (x, y); } 01791 template<typename R, typename C1, typename C2> static inline void 01792 set_op (R& x, const C1& y1, const C2& y2) { x= polar (y1, y2); } 01793 }; 01794 01795 template<typename C> 01796 struct binary_return_type_helper<polar_op,C,C> { 01797 typedef Complex_type(C) RET; 01798 }; 01799 01800 struct Re_op { 01801 static generic name () { return GEN_RE; } 01802 template<typename C> static inline Real_type(C) 01803 op (const C& z) { return Re (z); } 01804 static inline generic 01805 op (const generic& z) { return Re (z); } 01806 static inline syntactic 01807 op (const syntactic& z) { return Re (z); } 01808 template<typename R, typename C> static inline void 01809 set_op (R& x, const C& y) { x= Re (y); } 01810 }; 01811 01812 struct Im_op { 01813 static generic name () { return GEN_IM; } 01814 template<typename C> static inline Real_type(C) 01815 op (const C& z) { return Im (z); } 01816 static inline generic 01817 op (const generic& z) { return Im (z); } 01818 static inline syntactic 01819 op (const syntactic& z) { return Im (z); } 01820 template<typename R, typename C> static inline void 01821 set_op (R& x, const C& y) { x= Im (y); } 01822 }; 01823 01824 template<typename C> 01825 struct unary_return_type_helper<Im_op,C> { 01826 typedef Real_type(C) RET; 01827 }; 01828 01829 struct arg_op { 01830 static generic name () { return GEN_ARG; } 01831 template<typename C> static inline Real_type(C) 01832 op (const C& z) { return arg (z); } 01833 static inline generic 01834 op (const generic& z) { return arg (z); } 01835 static inline syntactic 01836 op (const syntactic& z) { return arg (z); } 01837 template<typename R, typename C> static inline void 01838 set_op (R& x, const C& y) { x= arg (y); } 01839 }; 01840 01841 template<typename C> 01842 struct unary_return_type_helper<arg_op,C> { 01843 typedef Real_type(C) RET; 01844 }; 01845 01846 struct conj_op { 01847 static generic name () { return GEN_CONJ; } 01848 template<typename C> static inline C 01849 op (const C& z) { return conj (z); } 01850 template<typename R, typename C> static inline void 01851 set_op (R& x, const C& y) { x= conj (y); } 01852 }; 01853 01854 /****************************************************************************** 01855 * Operators on ball like types 01856 ******************************************************************************/ 01857 01858 struct ball_op { 01859 static generic name () { return GEN_BALL; } 01860 template<typename B, typename C, typename R> static inline B 01861 op (const C& c, const R& r) { 01862 return make_ball<B> (c, r); } 01863 template<typename B, typename C, typename R> static inline void 01864 set_op (B& b, const C& c, const R& r) { 01865 b= make_ball<B> (c, r); } 01866 }; 01867 01868 struct center_op { 01869 static generic name () { return GEN_CENTER; } 01870 template<typename C> static inline Center_type(C) 01871 op (const C& x) { return center (x); } 01872 template<typename R, typename C> static inline void 01873 set_op (R& x, const C& y) { x= center (y); } 01874 }; 01875 01876 struct radius_op { 01877 static generic name () { return GEN_RADIUS; } 01878 template<typename C> static inline Radius_type(C) 01879 op (const C& x) { return radius (x); } 01880 template<typename R, typename C> static inline void 01881 set_op (R& x, const C& y) { x= radius (y); } 01882 }; 01883 01884 struct interval_op { 01885 static generic name () { return GEN_INTERVAL; } 01886 template<typename B, typename R> static inline B 01887 op (const R& l, const R& r) { 01888 return make_interval<B> (l, r); } 01889 template<typename B, typename R> static inline void 01890 set_op (B& b, const R& l, const R& r) { 01891 b= make_interval<B> (l, r); } 01892 }; 01893 01894 struct lower_op { 01895 static generic name () { return GEN_LOWER; } 01896 template<typename C> static inline Center_type(C) 01897 op (const C& x) { return lower (x); } 01898 template<typename R, typename C> static inline void 01899 set_op (R& x, const C& y) { x= lower (y); } 01900 }; 01901 01902 template<typename C> 01903 struct unary_return_type_helper<lower_op,C> { 01904 typedef Center_type(C) RET; 01905 }; 01906 01907 struct upper_op { 01908 static generic name () { return GEN_UPPER; } 01909 template<typename C> static inline Center_type(C) 01910 op (const C& x) { return upper (x); } 01911 template<typename R, typename C> static inline void 01912 set_op (R& x, const C& y) { x= upper (y); } 01913 }; 01914 01915 template<typename C> 01916 struct unary_return_type_helper<upper_op,C> { 01917 typedef Center_type(C) RET; 01918 }; 01919 01920 struct sharpen_op { 01921 // return number with same center and zero radius 01922 static generic name () { return GEN_SHARPEN; } 01923 template<typename C> static inline C 01924 op (const C& x) { return sharpen (x); } 01925 template<typename R, typename C> static inline void 01926 set_op (R& x, const C& y) { x= sharpen (y); } 01927 }; 01928 01929 struct blur_op { 01930 // increase radius by a given amount 01931 static generic name () { return GEN_BLUR; } 01932 template<typename C, typename D> static inline C 01933 op (const C& x, const D& y) { return blur (x, y); } 01934 template<typename R, typename C, typename D> static inline void 01935 set_op (R& x, const C& y, const D& z) { x= blur (y, z); } 01936 }; 01937 01938 /****************************************************************************** 01939 * Operators on quotient types 01940 ******************************************************************************/ 01941 01942 struct numerator_op { 01943 static generic name () { return GEN_NUMERATOR; } 01944 template<typename C> static inline Numerator_type(C) 01945 op (const C& z) { return numerator (z); } 01946 static inline generic 01947 op (const generic& z) { return numerator (z); } 01948 static inline syntactic 01949 op (const syntactic& z) { return numerator (z); } 01950 template<typename R, typename C> static inline void 01951 set_op (R& x, const C& y) { x= numerator (y); } 01952 }; 01953 01954 struct denominator_op { 01955 static generic name () { return GEN_DENOMINATOR; } 01956 template<typename C> static inline Denominator_type(C) 01957 op (const C& z) { return denominator (z); } 01958 static inline generic 01959 op (const generic& z) { return denominator (z); } 01960 static inline syntactic 01961 op (const syntactic& z) { return denominator (z); } 01962 template<typename R, typename C> static inline void 01963 set_op (R& x, const C& y) { x= denominator (y); } 01964 }; 01965 01966 /****************************************************************************** 01967 * Operators on modular and fibered like types 01968 ******************************************************************************/ 01969 01970 template<typename R> 01971 struct lift_helper { 01972 template<typename C> static inline R 01973 op (const C& x) { return as<R> (lift (x)); } 01974 }; 01975 01976 struct lift_op { 01977 static generic name () { return GEN_LIFT; } 01978 template<typename C> static inline Lift_type(C) 01979 op (const C& x) { return lift (x); } 01980 template<typename R, typename C> static inline void 01981 set_op (R& x, const C& y) { x= lift_helper<R>::op (y); } 01982 }; 01983 01984 template<typename C> 01985 struct unary_return_type_helper<lift_op,C> { 01986 typedef Lift_type(C) RET; 01987 }; 01988 01989 template<typename R> 01990 struct project_helper { 01991 template<typename C> static inline R 01992 op (const C& x) { return as<R> (project (x)); } 01993 }; 01994 01995 struct project_op { 01996 static generic name () { return GEN_PROJECT; } 01997 template<typename C> static inline Project_type(C) 01998 op (const C& x) { return project (x); } 01999 template<typename R, typename C> static inline void 02000 set_op (R& x, const C& y) { x= project_helper<R>::op (y); } 02001 }; 02002 02003 template<typename C> 02004 struct unary_return_type_helper<project_op,C> { 02005 typedef Project_type(C) RET; 02006 }; 02007 02008 /****************************************************************************** 02009 * Calculus 02010 ******************************************************************************/ 02011 02012 struct derive_op { 02013 static generic name () { return GEN_DERIVE; } 02014 template<typename C> static inline C 02015 op (const C& x) { return derive (x); } 02016 template<typename R, typename C> static inline void 02017 set_op (R& x, const C& y) { x= derive (y); } 02018 template<typename C,typename V> static inline C 02019 op (const C& x, const V& v) { return derive (x, v); } 02020 template<typename R, typename C, typename V> static inline void 02021 set_op (R& x, const C& y, const V& v) { x= derive (y, v); } 02022 }; 02023 02024 struct xderive_op { 02025 static generic name () { return GEN_XDERIVE; } 02026 template<typename C> static inline C 02027 op (const C& x) { return xderive (x); } 02028 template<typename R, typename C> static inline void 02029 set_op (R& x, const C& y) { return xderive (y); } 02030 template<typename C,typename V> static inline C 02031 op (const C& x, const V& v) { return xderive (x, v); } 02032 template<typename R, typename C, typename V> static inline void 02033 set_op (R& x, const C& y, const V& v) { x= xderive (y, v); } 02034 }; 02035 02036 struct integrate_op { 02037 static generic name () { return GEN_INTEGRATE; } 02038 template<typename C> static inline C 02039 op (const C& x) { return integrate (x); } 02040 template<typename R, typename C> static inline void 02041 set_op (R& x, const C& y) { x= integrate (y); } 02042 template<typename C,typename V> static inline C 02043 op (const C& x, const V& v) { return integrate (x, v); } 02044 template<typename R, typename C, typename V> static inline void 02045 set_op (R& x, const C& y, const V& v) { x= integrate (y, v); } 02046 template<typename C,typename I> static inline C 02047 op_init (const C& x, const I& i) { return integrate_init (x, i); } 02048 template<typename C,typename V,typename I> static inline C 02049 op_init (const C& x, const V& v, const I& i) { 02050 return integrate_init (x, v, i); } 02051 }; 02052 02053 struct compose_op { 02054 static generic name () { return GEN_COMPOSE; } 02055 template<typename C1,typename C2> static inline C1 02056 op (const C1& x, const C2& y) { return compose (x, y); } 02057 template<typename R, typename C1, typename C2> static inline void 02058 set_op (R& x, const C1& y1, const C2& y2) { x= compose (y1, y2); } 02059 template<typename C> static inline C 02060 diff_op (const C& me, const C& x, const C& y) { 02061 (void) me; return derive (y) * compose (derive (x), y); } 02062 }; 02063 02064 struct reverse_op { 02065 static generic name () { return GEN_REVERSE; } 02066 template<typename C> static inline C 02067 op (const C& x) { return reverse (x); } 02068 template<typename R, typename C> static inline void 02069 set_op (R& x, const C& y) { x= reverse (y); } 02070 template<typename C> static inline C 02071 diff_op (const C& me, const C& x) { 02072 return 1 / compose (derive (x), me); } 02073 }; 02074 02075 struct append_op { 02076 static generic name () { return GEN_APPEND; } 02077 template<typename C1,typename C2> static inline C1 02078 op (const C1& x, const C2& y) { return append (x, y); } 02079 template<typename R, typename C1, typename C2> static inline void 02080 set_op (R& x, const C1& y1, const C2& y2) { x= append (y1, y2); } 02081 }; 02082 02083 struct solve_vector_lde_op { 02084 template<typename C> static inline C 02085 op (const C& x) { ERROR ("must initialize (solve_vector_lde_op::op)"); } 02086 template<typename C, typename I> static inline C 02087 op_init (const C& x, const I& i) { return solve_vector_lde_init (x, i); } 02088 static inline generic op_init (const generic& x, const generic& i) { 02089 return solve_lde_init (x, i); } 02090 static inline syntactic op_init (const syntactic& x, const syntactic& i) { 02091 return solve_lde_init (x, i); } 02092 template<typename C> static inline C 02093 diff_op (const C& me, const C& x); 02094 static inline nat nr_init () { return 1; } 02095 template<typename C> static inline C 02096 def (const C& me, const C& f) { 02097 return integrate (diff_op (me, f)); } 02098 }; 02099 02100 struct solve_matrix_lde_op { 02101 template<typename C> static inline C 02102 op (const C& x) { ERROR ("must initialize (solve_matrix_lde_op::op)"); } 02103 template<typename C, typename I> static inline C 02104 op_init (const C& x, const I& i) { return solve_matrix_lde_init (x, i); } 02105 static inline generic op_init (const generic& x, const generic& i) { 02106 return solve_lde_init (x, i); } 02107 static inline syntactic op_init (const syntactic& x, const syntactic& i) { 02108 return solve_lde_init (x, i); } 02109 template<typename C> static inline C diff_op (const C& me, const C& x) { 02110 return x * me; } 02111 static inline nat nr_init () { return 1; } 02112 template<typename C> static inline C def (const C& me, const C& f) { 02113 return integrate (diff_op (me, f)); } 02114 }; 02115 02116 /****************************************************************************** 02117 * Asymptotic relations 02118 ******************************************************************************/ 02119 02120 struct is_infinitesimal_op { 02121 template<typename T> static inline bool 02122 op (const T& x) { return x << 1; } 02123 template<typename T> static inline bool 02124 not_op (const T& x) { return !(x << 1); } 02125 }; 02126 02127 struct is_non_infinitesimal_op { 02128 template<typename T> static inline bool 02129 op (const T& x) { return !(x << 1); } 02130 template<typename T> static inline bool 02131 not_op (const T& x) { return x << 1; } 02132 }; 02133 02134 struct is_bounded_op { 02135 template<typename T> static inline bool 02136 op (const T& x) { return x <<= 1; } 02137 template<typename T> static inline bool 02138 not_op (const T& x) { return !(x <<= 1); } 02139 }; 02140 02141 struct is_non_bounded_op { 02142 template<typename T> static inline bool 02143 op (const T& x) { return !(x <<= 1); } 02144 template<typename T> static inline bool 02145 not_op (const T& x) { return x <<= 1; } 02146 }; 02147 02148 struct is_infinitely_large_op { 02149 template<typename T> static inline bool 02150 op (const T& x) { return x >> 1; } 02151 template<typename T> static inline bool 02152 not_op (const T& x) { return !(x >> 1); } 02153 }; 02154 02155 struct is_non_infinitely_large_op { 02156 template<typename T> static inline bool 02157 op (const T& x) { return !(x >> 1); } 02158 template<typename T> static inline bool 02159 not_op (const T& x) { return x >> 1; } 02160 }; 02161 02162 struct is_constant_op { 02163 template<typename T> static inline bool 02164 op (const T& x) { return x == 1; } 02165 template<typename T> static inline bool 02166 not_op (const T& x) { return x != 1; } 02167 }; 02168 02169 struct is_non_constant_op { 02170 template<typename T> static inline bool 02171 op (const T& x) { return x != 1; } 02172 template<typename T> static inline bool 02173 not_op (const T& x) { return x == 1; } 02174 }; 02175 02176 struct smaller_equal_op { 02177 template<typename T1, typename T2> static inline bool 02178 op (const T1& x1, const T2& x2) { return x1 <<= x2; } 02179 template<typename T1, typename T2> static inline bool 02180 not_op (const T1& x1, const T2& x2) { return !(x1 <<= x2); } 02181 }; 02182 02183 struct not_smaller_equal_op { 02184 template<typename T1, typename T2> static inline bool 02185 op (const T1& x1, const T2& x2) { return !(x1 <<= x2); } 02186 template<typename T1, typename T2> static inline bool 02187 not_op (const T1& x1, const T2& x2) { return x1 <<= x2; } 02188 }; 02189 02190 struct smaller_op { 02191 template<typename T1, typename T2> static inline bool 02192 op (const T1& x1, const T2& x2) { return x1 << x2; } 02193 template<typename T1, typename T2> static inline bool 02194 not_op (const T1& x1, const T2& x2) { return !(x1 << x2); } 02195 }; 02196 02197 struct not_smaller_op { 02198 template<typename T1, typename T2> static inline bool 02199 op (const T1& x1, const T2& x2) { return !(x1 << x2); } 02200 template<typename T1, typename T2> static inline bool 02201 not_op (const T1& x1, const T2& x2) { return x1 << x2; } 02202 }; 02203 02204 struct larger_equal_op { 02205 template<typename T> static inline bool 02206 op (const T& x1, const T& x2) { return x1 >>= x2; } 02207 template<typename T> static inline bool 02208 not_op (const T& x1, const T& x2) { return !(x1 >>= x2); } 02209 }; 02210 02211 struct not_larger_equal_op { 02212 template<typename T> static inline bool 02213 op (const T& x1, const T& x2) { return !(x1 >>= x2); } 02214 template<typename T> static inline bool 02215 not_op (const T& x1, const T& x2) { return x1 >>= x2; } 02216 }; 02217 02218 struct larger_op { 02219 template<typename T> static inline bool 02220 op (const T& x1, const T& x2) { return x1 >> x2; } 02221 template<typename T> static inline bool 02222 not_op (const T& x1, const T& x2) { return !(x1 >> x2); } 02223 }; 02224 02225 struct not_larger_op { 02226 template<typename T> static inline bool 02227 op (const T& x1, const T& x2) { return !(x1 >> x2); } 02228 template<typename T> static inline bool 02229 not_op (const T& x1, const T& x2) { return x1 >> x2; } 02230 }; 02231 02232 /****************************************************************************** 02233 * Restriction of support 02234 ******************************************************************************/ 02235 02236 struct common_part_op { 02237 typedef zero_op lop; 02238 typedef zero_op rop; 02239 static generic name () { return "common_part"; } 02240 template<typename T> static inline T 02241 op (const T& x, const T& y) { return common_part (x, y); } 02242 }; 02243 02244 struct dominant_part_op { 02245 static generic name () { return "dominant_part"; } 02246 template<typename T> static inline T 02247 op (const T& x) { return dominant_part (x); } 02248 }; 02249 02250 struct remainder_part_op { 02251 static generic name () { return "remainder_part"; } 02252 template<typename T> static inline T 02253 op (const T& x) { return remainder_part (x); } 02254 }; 02255 02256 struct infinitesimal_part_op { 02257 typedef is_infinitesimal_op pred; 02258 static generic name () { return "infinitesimal_part"; } 02259 template<typename T> static inline T 02260 op (const T& x) { return infinitesimal_part (x); } 02261 }; 02262 02263 struct non_infinitesimal_part_op { 02264 typedef is_non_infinitesimal_op pred; 02265 static generic name () { return "non_infinitesimal_part"; } 02266 template<typename T> static inline T 02267 op (const T& x) { return non_infinitesimal_part (x); } 02268 }; 02269 02270 struct bounded_part_op { 02271 typedef is_bounded_op pred; 02272 static generic name () { return "bounded_part"; } 02273 template<typename T> static inline T 02274 op (const T& x) { return bounded_part (x); } 02275 }; 02276 02277 struct non_bounded_part_op { 02278 typedef is_non_bounded_op pred; 02279 static generic name () { return "non_bounded_part"; } 02280 template<typename T> static inline T 02281 op (const T& x) { return non_bounded_part (x); } 02282 }; 02283 02284 struct infinite_part_op { 02285 typedef is_infinitely_large_op pred; 02286 static generic name () { return "infinite_part"; } 02287 template<typename T> static inline T 02288 op (const T& x) { return infinite_part (x); } 02289 }; 02290 02291 struct non_infinite_part_op { 02292 typedef is_non_infinitely_large_op pred; 02293 static generic name () { return "non_infinite_part"; } 02294 template<typename T> static inline T 02295 op (const T& x) { return non_infinite_part (x); } 02296 }; 02297 02298 struct constant_part_op { 02299 typedef is_constant_op pred; 02300 static generic name () { return "constant_part"; } 02301 template<typename T> static inline T 02302 op (const T& x) { return constant_part (x); } 02303 }; 02304 02305 struct non_constant_part_op { 02306 typedef is_non_constant_op pred; 02307 static generic name () { return "non_constant_part"; } 02308 template<typename T> static inline T 02309 op (const T& x) { return non_constant_part (x); } 02310 }; 02311 02312 /****************************************************************************** 02313 * Miscellaneous operators 02314 ******************************************************************************/ 02315 02316 struct access_op { 02317 static generic name () { return GEN_ACCESS; } 02318 template<typename C, typename I> 02319 static inline Binary_return_type(access_op,C,I) 02320 op (const C& x, const I& i) { return x[i]; } 02321 template<typename R, typename C, typename I> static inline void 02322 set_op (R& x, const C& y, const I& i) { x= y[i]; } 02323 }; 02324 02325 struct mv_inject_op { 02326 static generic name () { return "inject"; } 02327 template<typename C, typename I, typename D> static inline C 02328 op (const C& x, const I& i, const D& d) { return inject (x, i, d); } 02329 template<typename R, typename C, typename I, typename D> static inline void 02330 set_op (R& x, const C& y, const I& i, const D& d) { x= inject (y, i, d); } 02331 }; 02332 02333 struct mv_project_op { 02334 static generic name () { return "project"; } 02335 template<typename C, typename I> static inline C 02336 op (const C& x, const I& i) { return project (x, i); } 02337 template<typename R, typename C, typename I> static inline void 02338 set_op (R& x, const C& y, const I& i) { x= project (y, i); } 02339 }; 02340 02341 } // namespace mmx 02342 #endif // __MMX_OPERATORS_HPP