00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __MMX_AFFINE_HPP
00014 #define __MMX_AFFINE_HPP
00015 #include <basix/function.hpp>
00016 #include <numerix/ball.hpp>
00017 namespace mmx {
00018 #define TMPL_DEF template<typename C, typename VC= C>
00019 #define TMPL template<typename C, typename VC>
00020 #define R Radius_type(C)
00021 #define VR typename affine_limits_helper<C,VC>::VT
00022 #define Affine affine<C,VC>
00023 #define Affine_rep affine_rep<C,VC>
00024 #define Abs_affine affine<Abs_type(C),Abs_type(VC) >
00025 #define Real_affine affine<Real_type(C),Real_type(VC) >
00026 TMPL class affine;
00027 TMPL struct affine_limits_helper;
00028 TMPL inline C base (const Affine& z);
00029 TMPL inline VC slope (const Affine& z);
00030 TMPL inline VR limits (const Affine& z);
00031 TMPL inline Affine operator - (const Affine& z1, const Affine& z2);
00032
00033
00034
00035
00036
00037 template<typename C> inline C dot (const C& x, const C& y) { return x * y; }
00038
00039 TMPL
00040 struct affine_limits_helper {
00041 typedef Radius_type(VC) VT;
00042 static inline VT infinite () {
00043 return Maximal (VT); }
00044 static inline VC get_linear (const VC& lin, const VC& dom) {
00045 return lin + sharpen (dom); }
00046 static inline VT get_limits (const VC& dom) {
00047 return radius (dom); }
00048 static inline VC get_domain (const VT& lim) {
00049 return blur (VC (0), lim); }
00050 static inline C truncate (const VC& lin, const VT& lim) {
00051 return dot (lin, get_domain (lim)); }
00052 static inline VT common (const VT& lim1, const VT& lim2) {
00053 if (hard_eq (lim1, lim2)) return lim1;
00054 return inf (radius (lim1), radius (lim2)); }
00055 };
00056
00057
00058
00059
00060
00061 TMPL_DEF
00062 class affine {
00063 MMX_ALLOCATORS
00064 private:
00065 C cst;
00066 VC lin;
00067 VR lim;
00068
00069 public:
00070 typedef affine_limits_helper<C,VC> Helper;
00071 inline affine ():
00072 cst (0), lin (0), lim (Helper::infinite ()) {}
00073 inline affine (const format<C>& fm1, const format<VC>& fm2):
00074 cst (promote (0, fm1)), lin (promote (0, fm2)),
00075 lim (Helper::infinite ()) {}
00076 template<typename T> affine (const T& cst2):
00077 cst (cst2), lin (0), lim (Helper::infinite ()) {}
00078 inline affine (const C& z):
00079 cst (copy (z)), lin (0), lim (Helper::infinite ()) {}
00080 inline affine (const C& cst2, const VC& lin2):
00081 cst (cst2), lin (lin2), lim (Helper::infinite ()) {}
00082 inline affine (const C& cst2, const VC& lin2, const VR& lim2):
00083 cst (cst2), lin (lin2), lim (lim2) {}
00084 template<typename CT,typename VCT> inline affine (const affine<CT,VCT>& z):
00085 cst (as<C> (base (z))),
00086 lin (as<VC> (slope (z))),
00087 lim (as<VR > (limits (z))) {}
00088 friend C base LESSGTR (const Affine& z);
00089 friend VC slope LESSGTR (const Affine& z);
00090 friend VR limits LESSGTR (const Affine& z);
00091 };
00092 DEFINE_BINARY_FORMAT_2 (affine)
00093
00094 TMPL struct rounding_helper<Affine >: public rounding_helper<C> {};
00095
00096 STYPE_TO_TYPE(TMPL,scalar_type,Affine,C);
00097 UNARY_RETURN_TYPE(TMPL,Re_op,Affine,Real_affine);
00098 UNARY_RETURN_TYPE(TMPL,abs_op,Affine,Abs_affine);
00099
00100
00101
00102
00103
00104 TMPL inline C base (const Affine& z) {
00105 return z.cst; }
00106 TMPL inline VC slope (const Affine& z) {
00107 return z.lin; }
00108 TMPL inline VR limits (const Affine& z) {
00109 return z.lim; }
00110 TMPL inline format<C> CF1 (const Affine& z) {
00111 return get_format (base (z)); }
00112 TMPL inline format<VC> CF2 (const Affine& z) {
00113 return get_format (slope (z)); }
00114 TMPL inline C truncate (const Affine& z) {
00115 typedef affine_limits_helper<C,VC> Helper;
00116 return base (z) + Helper::truncate (slope (z), limits (z)); }
00117 TMPL inline VR common_limits (const Affine& z1, const Affine& z2) {
00118 typedef affine_limits_helper<C,VC> Helper;
00119 return Helper::common (limits (z1), limits (z2)); }
00120
00121 TMPL inline Affine make_affine (const C& cst, const VC& lin, const VC& dom) {
00122 typedef affine_limits_helper<C,VC> Helper;
00123 return Affine (cst, Helper::get_linear (lin, dom),
00124 Helper::get_limits (dom)); }
00125 TMPL inline VC domain (const Affine& z) {
00126 typedef affine_limits_helper<C,VC> Helper;
00127 return Helper::get_domain (limits (z)); }
00128
00129
00130 TMPL inline Affine copy (const Affine& z) {
00131 return Affine (copy (base (z)), copy (slope (z)), copy (limits (z))); }
00132 TMPL inline Affine duplicate (const Affine& z) {
00133 return Affine (duplicate (base (z)), duplicate (slope (z)),
00134 duplicate (limits (z))); }
00135
00136 template<typename Op, typename C, typename VC> nat
00137 unary_hash (const Affine& x) {
00138 nat h= Op::op (base (x));
00139 h += (h<<3) ^ (h<<11) ^ (h>>29) ^ Op::op (slope (x));
00140 return (h<<3) ^ (h<<11) ^ (h>>29) ^ Op::op (limits (x));
00141 }
00142
00143 template<typename Op, typename C, typename VC> bool
00144 binary_test (const Affine& x1, const Affine& x2) {
00145 return Op::op (base (x1), base (x2)) &&
00146 Op::op (slope (x1), slope (x2)) &&
00147 Op::op (limits (x1), limits (x2));
00148 }
00149
00150 template<typename CS, typename CD, typename DS, typename DD,
00151 typename FunC, typename FunD> affine<CD,DD>
00152 map (const FunC& funC, const FunD& funD,
00153 const affine<CS,DS>& z,
00154 const format<CD>& fmC, const format<DD>& fmD) {
00155 return affine<CD,DD> (funC (base (z)), funD (slope (z)));
00156 }
00157
00158 TRUE_IDENTITY_OP_SUGAR(TMPL,Affine)
00159 EXACT_IDENTITY_OP_SUGAR(TMPL,Affine)
00160 HARD_IDENTITY_OP_SUGAR(TMPL,Affine)
00161
00162 TMPL syntactic
00163 flatten (const Affine& z) {
00164 return apply ("affine", flatten (base (z)), flatten (slope (z)),
00165 flatten (limits (z)));
00166 }
00167
00168 TMPL
00169 struct binary_helper<Affine >: public void_binary_helper<Affine > {
00170 static inline string short_type_name () {
00171 return "Af" * Short_type_name (C) * Short_type_name (VC); }
00172 static inline generic full_type_name () {
00173 return gen ("Affine", Full_type_name (C)); }
00174 static inline generic disassemble (const Affine& z) {
00175 return gen_vec (as<generic> (base (z)),
00176 as<generic> (slope (z)),
00177 as<generic> (limits (z))); }
00178 static inline Affine assemble (const generic& v) {
00179 return Affine (as<C> (vector_access (v, 0)),
00180 as<VC> (vector_access (v, 1)),
00181 as<VR> (vector_access (v, 2))); }
00182 static inline void write (const port& out, const Affine& z) {
00183 binary_write<C> (out, base (z));
00184 binary_write<VC> (out, slope (z));
00185 binary_write<VC> (out, limits (z)); }
00186 static inline Affine read (const port& in) {
00187 C b= binary_read<C> (in);
00188 VC s= binary_read<VC> (in);
00189 VR d= binary_read<VR> (in);
00190 return Affine (b, s, d); }
00191 };
00192
00193
00194
00195
00196
00197 TMPL inline void set_default (Affine& x) { x= Affine (Default (C), 0); }
00198 TMPL inline void set_nan (Affine& x) { x= Affine (Nan (C), 0); }
00199 TMPL inline void set_maximal (Affine& x) { x= Affine (Maximal (C), 0); }
00200 TMPL inline void set_minimal (Affine& x) { x= Affine (Minimal (C), 0); }
00201 TMPL inline void set_infinity (Affine& x) { x= Affine (Infinity (C), 0); }
00202 TMPL inline void set_fuzz (Affine& x) { x= Affine (Fuzz (C), 0); }
00203 TMPL inline void set_smallest (Affine& x) { x= Affine (Smallest (C), 0); }
00204 TMPL inline void set_largest (Affine& x) { x= Affine (Largest (C), 0); }
00205 TMPL inline void set_accuracy (Affine& x) { x= Affine (Accuracy (C), 0); }
00206 TMPL inline void set_log2 (Affine& x) { x= Affine (Log2 (C), 0); }
00207 TMPL inline void set_pi (Affine& x) { x= Affine (Pi (C), 0); }
00208 TMPL inline void set_euler (Affine& x) { x= Affine (Euler (C), 0); }
00209 TMPL inline void set_imaginary (Affine& x) { x= Affine (Imaginary (C), 0); }
00210
00211 TMPL inline Affine times_infinity (const Affine& x) {
00212 return x * infinity_cst<Affine > (); }
00213
00214
00215
00216
00217
00218 TMPL inline Affine
00219 operator - (const Affine& z) {
00220 return Affine (-base (z), -slope (z), limits (z));
00221 }
00222
00223 TMPL inline Affine
00224 operator + (const Affine& z1, const Affine& z2) {
00225 VR lim= common_limits (z1, z2);
00226 return Affine (base (z1) + base (z2), slope (z1) + slope (z2), lim);
00227 }
00228
00229 TMPL inline Affine
00230 operator + (const C& z1, const Affine& z2) {
00231 return Affine (z1 + base (z2), slope (z2), limits (z2));
00232 }
00233
00234 TMPL inline Affine
00235 operator + (const Affine& z1, const C& z2) {
00236 return Affine (base (z1) + z2, slope (z1), limits (z1));
00237 }
00238
00239 TMPL inline Affine
00240 operator - (const Affine& z1, const Affine& z2) {
00241 return Affine (base (z1) - base (z2), slope (z1) - slope (z2));
00242 }
00243
00244 TMPL inline Affine
00245 operator - (const C& z1, const Affine& z2) {
00246 return Affine (z1 - base (z2), slope (z2), limits (z2));
00247 }
00248
00249 TMPL inline Affine
00250 operator - (const Affine& z1, const C& z2) {
00251 return Affine (base (z1) - z2, slope (z1), limits (z1));
00252 }
00253
00254 TMPL inline Affine
00255 operator * (const Affine& z1, const Affine& z2) {
00256 VR lim= common_limits (z1, z2);
00257 return Affine (base (z1) * base (z2),
00258 truncate (z1) * slope (z2) + slope (z1) * truncate (z2), lim);
00259 }
00260
00261 TMPL inline Affine
00262 operator * (const C& z1, const Affine& z2) {
00263 return Affine (z1 * base (z2), z1 * slope (z2), limits (z2));
00264 }
00265
00266 TMPL inline Affine
00267 operator * (const Affine& z1, const C& z2) {
00268 return Affine (base (z1) * z2, slope (z1) * z2, limits (z1));
00269 }
00270
00271 TMPL inline Affine
00272 square (const Affine& z) {
00273 return Affine (square (base (z)),
00274 (base (z) + truncate (z)) * slope (z), limits (z));
00275 }
00276
00277 TMPL inline Affine
00278 invert (const Affine& z) {
00279 ERROR ("not yet implemented");
00280
00281
00282 }
00283
00284 TMPL inline Affine
00285 operator / (const Affine& z1, const Affine& z2) {
00286 ERROR ("not yet implemented");
00287
00288
00289
00290 }
00291
00292 TMPL inline Affine
00293 operator / (const C& z1, const Affine& z2) {
00294 ERROR ("not yet implemented");
00295
00296
00297 }
00298
00299 TMPL inline Affine
00300 operator / (const Affine& z1, const C& z2) {
00301 C inv= invert (z2);
00302 return Affine (inv * base (z1), inv * slope (z1), limits (z1));
00303 }
00304
00305 ARITH_INT_SUGAR(TMPL,Affine);
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398 TMPL inline bool
00399 operator <= (const Affine& z1, const Affine& z2) {
00400 return base (z1) < base (z2) || z1 == z2;
00401 }
00402
00403 TMPL inline bool
00404 operator < (const Affine& z1, const Affine& z2) {
00405 return base (z1) < base (z2);
00406 }
00407
00408 TMPL inline bool
00409 operator >= (const Affine& z1, const Affine& z2) {
00410 return base (z1) > base (z2) || z1 == z2;
00411 }
00412
00413 TMPL inline bool
00414 operator > (const Affine& z1, const Affine& z2) {
00415 return base (z1) > base (z2);
00416 }
00417
00418 TMPL inline Affine
00419 min (const Affine& z1, const Affine& z2) {
00420 if (z1 <= z2) return z1; else return z2;
00421 }
00422
00423 TMPL Affine
00424 max (const Affine& z1, const Affine& z2) {
00425 if (z1 >= z2) return z1; else return z2;
00426 }
00427
00428 EQUAL_INT_SUGAR(TMPL,Affine);
00429 COMPARE_INT_SUGAR(TMPL,Affine);
00430
00431
00432
00433
00434
00435 TMPL inline bool is_finite (const Affine& z) {
00436 return is_finite (base (z)) && is_finite (slope (z)); }
00437 TMPL inline bool is_nan (const Affine& z) {
00438 return is_nan (base (z)) || is_nan (slope (z)); }
00439 TMPL inline bool is_infinite (const Affine& z) {
00440 return !is_nan (z) && (is_infinite (base (z)) || is_infinite (slope (z))); }
00441 TMPL inline bool is_fuzz (const Affine& z) {
00442 return !is_nan (z) && (is_fuzz (base (z)) || is_fuzz (slope (z))); }
00443 TMPL inline bool is_reliable (const Affine& z) {
00444 return is_reliable (base (z)); }
00445
00446 TMPL inline Affine change_precision (const Affine& z, xnat prec) {
00447 return Affine (change_precision (base (z), prec),
00448 change_precision (slope (z), prec),
00449 change_precision (limits (z), prec)); }
00450 TMPL inline xnat precision (const Affine& z) {
00451 return precision (base (z)); }
00452 TMPL inline Affine additive_error (const Affine& z) {
00453 return Affine (additive_error (base (z)),
00454 additive_error (slope (z)),
00455 limits (z)); }
00456
00457 TMPL inline double magnitude (const Affine& z) {
00458 return magnitude (base (z)); }
00459 TMPL inline xint exponent (const Affine& z) {
00460 return exponent (base (z)); }
00461 TMPL inline Affine operator << (const Affine& z, const xint& s) {
00462 return Affine (incexp2 (base (z), s), incexp2 (slope (z), s), limits (z)); }
00463 TMPL inline Affine operator >> (const Affine& z, const xint& s) {
00464 return Affine (decexp2 (base (z), s), decexp2 (slope (z), s), limits (z)); }
00465
00466 TMPL inline Affine sharpen (const Affine& z) {
00467 return Affine (sharpen (base (z)), sharpen (slope (z)), limits (z)); }
00468 template<typename C, typename VC, typename C2, typename VC2> inline Affine
00469 blur (const Affine& z, const affine<C2,VC2>& r) {
00470 return Affine (blur (base (z), base (r)), blur (slope (z), slope (r)),
00471 limits (z)); }
00472
00473
00474
00475
00476
00477 TMPL inline Abs_affine
00478 abs (const Affine& z) {
00479
00480 return Abs_affine (abs (base (z)), abs (slope (z)), limits (z));
00481 }
00482
00483 TMPL inline Real_affine
00484 Re (const Affine& z) {
00485 return Real_affine (Re (base (z)), Re (slope (z)), limits (z));
00486 }
00487
00488 TMPL inline Real_affine
00489 Im (const Affine& z) {
00490 return Real_affine (Im (base (z)), Im (slope (z)), limits (z));
00491 }
00492
00493 #undef TMPL_DEF
00494 #undef TMPL
00495 #undef R
00496 #undef VR
00497 #undef Affine
00498 #undef Affine_rep
00499 }
00500 #endif // __MMX_AFFINE_HPP