00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __MMX_TANGENT_HPP
00014 #define __MMX_TANGENT_HPP
00015 #include <numerix/rational.hpp>
00016 #include <basix/function.hpp>
00017 namespace mmx {
00018 #define TMPL_DEF template<typename C, typename D=C>
00019 #define TMPL template<typename C,typename D>
00020 #define Tangent tangent<C,D>
00021 #define Abs_tangent tangent<Abs_type(C),Abs_type(D) >
00022 #define Real_tangent tangent<Real_type(C),Real_type(D) >
00023 TMPL class tangent;
00024 TMPL inline C base (const Tangent& z);
00025 TMPL inline D slope (const Tangent& z);
00026 TMPL inline C& base (Tangent& z);
00027 TMPL inline D& slope (Tangent& z);
00028 TMPL inline Tangent operator - (const Tangent& z1, const Tangent& z2);
00029
00030
00031
00032
00033
00034 TMPL_DEF
00035 class tangent {
00036 MMX_ALLOCATORS
00037 private:
00038 C c;
00039 D d;
00040
00041 public:
00042 inline tangent (): c (0), d (0) {}
00043 inline tangent (const format<C>& fm1, const format<D>& fm2):
00044 c (promote (0, fm1)), d (promote (0, fm2)) {}
00045 template<typename T> tangent (const T& c2): c (c2), d (0) {}
00046 template<typename CT,typename DT> inline tangent (const tangent<CT,DT>& z):
00047 c (as<C> (base (z))), d (as<D> (slope (z))) {}
00048 inline tangent (const C& z): c (copy (z)), d (0) {}
00049 inline tangent (const C& c2, const D& d2): c (c2), d (d2) {}
00050 friend C base LESSGTR (const Tangent& z);
00051 friend D slope LESSGTR (const Tangent& z);
00052 friend C& base LESSGTR (Tangent& z);
00053 friend D& slope LESSGTR (Tangent& z);
00054 };
00055 DEFINE_BINARY_FORMAT_2 (tangent)
00056
00057 TMPL struct rounding_helper<Tangent >: public rounding_helper<C> {};
00058
00059 STYPE_TO_TYPE(TMPL,scalar_type,Tangent,C);
00060 UNARY_RETURN_TYPE(TMPL,Re_op,Tangent,Real_tangent);
00061 UNARY_RETURN_TYPE(TMPL,abs_op,Tangent,Abs_tangent);
00062
00063
00064
00065
00066
00067 TMPL inline void scalar_tangent (Tangent& r, const C& c) {
00068 r= Tangent (c, promote (0, slope (r))); }
00069 TMPL inline C base (const Tangent& z) { return z.c; }
00070 TMPL inline D slope (const Tangent& z) { return z.d; }
00071 TMPL inline C& base (Tangent& z) { return z.c; }
00072 TMPL inline D& slope (Tangent& z) { return z.d; }
00073 TMPL inline format<C> CF1 (const Tangent& z) { return get_format (base (z)); }
00074 TMPL inline format<D> CF2 (const Tangent& z) { return get_format (slope (z)); }
00075
00076 TMPL inline Tangent copy (const Tangent& z) {
00077 return Tangent (copy (base (z)), copy (slope (z))); }
00078 TMPL inline Tangent duplicate (const Tangent& z) {
00079 return Tangent (duplicate (base (z)), duplicate (slope (z))); }
00080
00081 template<typename Op, typename C, typename D> nat
00082 unary_hash (const Tangent& x) {
00083 nat h= Op::op (base (x));
00084 return (h<<3) ^ (h<<11) ^ (h>>29) ^ Op::op (slope (x));
00085 }
00086
00087 template<typename Op, typename C, typename D> bool
00088 binary_test (const Tangent& x1, const Tangent& x2) {
00089 return Op::op (base (x1), base (x2)) &&
00090 Op::op (slope (x1), slope (x2));
00091 }
00092
00093 template<typename CS, typename CD, typename DS, typename DD,
00094 typename FunC, typename FunD> tangent<CD,DD>
00095 map (const FunC& funC, const FunD& funD,
00096 const tangent<CS,DS>& z,
00097 const format<CD>& fmC, const format<DD>& fmD) {
00098 return tangent<CD,DD> (funC (base (z)), funD (slope (z)));
00099 }
00100
00101 TRUE_IDENTITY_OP_SUGAR(TMPL,Tangent)
00102 EXACT_IDENTITY_OP_SUGAR(TMPL,Tangent)
00103 HARD_IDENTITY_OP_SUGAR(TMPL,Tangent)
00104
00105 TMPL syntactic
00106 flatten (const Tangent& z) {
00107 return apply ("tangent", flatten (base (z)), flatten (slope (z)));
00108 }
00109
00110 TMPL
00111 struct binary_helper<Tangent >: public void_binary_helper<Tangent > {
00112 static inline string short_type_name () {
00113 return "Ta" * Short_type_name (C) * Short_type_name (D); }
00114 static inline generic full_type_name () {
00115 return gen ("Tangent", Full_type_name (C)); }
00116 static inline generic disassemble (const Tangent& z) {
00117 return gen_vec (as<generic> (base (z)), as<generic> (slope (z))); }
00118 static inline Tangent assemble (const generic& v) {
00119 return Tangent (as<C> (vector_access (v, 0)),
00120 as<D> (vector_access (v, 1))); }
00121 static inline void write (const port& out, const Tangent& z) {
00122 binary_write<C> (out, base (z));
00123 binary_write<D> (out, slope (z)); }
00124 static inline Tangent read (const port& in) {
00125 C b= binary_read<C> (in);
00126 D s= binary_read<D> (in);
00127 return Tangent (b, s); }
00128 };
00129
00130
00131
00132
00133
00134 TMPL inline void set_default (Tangent& z) {
00135 set_default (base (z)); set_zero (slope (z)); }
00136 TMPL inline void set_nan (Tangent& z) {
00137 set_nan (base (z)); set_nan (slope (z)); }
00138 TMPL inline void set_infinity (Tangent& z) {
00139 set_infinity (base (z)); set_zero (slope (z)); }
00140 TMPL inline void set_fuzz (Tangent& z) {
00141 set_fuzz (base (z)); set_fuzz (slope (z)); }
00142 TMPL inline void set_smallest (Tangent& z) {
00143 set_smallest (base (z)); set_zero (slope (z)); }
00144 TMPL inline void set_largest (Tangent& z) {
00145 set_largest (base (z)); set_zero (slope (z)); }
00146 TMPL inline void set_accuracy (Tangent& z) {
00147 set_accuracy (base (z)); set_zero (slope (z)); }
00148 TMPL inline void set_log2 (Tangent& z) {
00149 set_log2 (base (z)); set_zero (slope (z)); }
00150 TMPL inline void set_pi (Tangent& z) {
00151 set_pi (base (z)); set_zero (slope (z)); }
00152 TMPL inline void set_euler (Tangent& z) {
00153 set_euler (base (z)); set_zero (slope (z)); }
00154 TMPL inline void set_imaginary (Tangent& z) {
00155 set_imaginary (base (z)); set_zero (slope (z)); }
00156 TMPL inline Tangent times_infinity (const Tangent& x) {
00157 return x * infinity_cst<Tangent > (); }
00158
00159
00160
00161
00162
00163 TMPL inline Tangent
00164 operator - (const Tangent& z) {
00165 return Tangent (-base (z), -slope (z));
00166 }
00167
00168 TMPL inline Tangent
00169 operator + (const Tangent& z1, const Tangent& z2) {
00170 return Tangent (base (z1) + base (z2), slope (z1) + slope (z2));
00171 }
00172
00173 TMPL inline Tangent
00174 operator - (const Tangent& z1, const Tangent& z2) {
00175 return Tangent (base (z1) - base (z2), slope (z1) - slope (z2));
00176 }
00177
00178 TMPL inline Tangent
00179 operator * (const Tangent& z1, const Tangent& z2) {
00180 return Tangent (base (z1) * base (z2),
00181 base (z1) * slope (z2) + slope (z1) * base (z2));
00182 }
00183
00184 TMPL inline Tangent
00185 operator * (const C& z1, const Tangent& z2) {
00186 return Tangent (z1 * base (z2), z1 * slope (z2));
00187 }
00188
00189 TMPL inline Tangent
00190 operator * (const Tangent& z1, const C& z2) {
00191 return Tangent (base (z1) * z2, slope (z1) * z2);
00192 }
00193
00194 TMPL inline Tangent
00195 square (const Tangent& z) {
00196 return Tangent (square (base (z)), (base (z) + base (z)) * slope (z));
00197 }
00198
00199 TMPL inline Tangent
00200 invert (const Tangent& z) {
00201 C inv= invert (base (z));
00202 return Tangent (inv, - square (inv) * slope (z));
00203 }
00204
00205 TMPL inline Tangent
00206 operator / (const Tangent& z1, const Tangent& z2) {
00207 C inv= invert (base (z2));
00208 return Tangent (inv * base (z1),
00209 inv * (slope (z1) - inv * base (z1) * slope (z2)));
00210 }
00211
00212 TMPL inline Tangent
00213 operator / (const C& z1, const Tangent& z2) {
00214 C inv= invert (base (z2));
00215 return Tangent (inv * z1, - square (inv) * z1 * slope (z2));
00216 }
00217
00218 TMPL inline Tangent
00219 operator / (const Tangent& z1, const C& z2) {
00220 C inv= invert (z2);
00221 return Tangent (inv * base (z1), inv * slope (z1));
00222 }
00223
00224 ARITH_INT_SUGAR(TMPL,Tangent);
00225
00226
00227
00228
00229
00230 TMPL inline Tangent
00231 sqrt (const Tangent& z) {
00232 C s= sqrt (base (z));
00233 return Tangent (s, invert (s + s) * slope (z));
00234 }
00235
00236 TMPL inline Tangent
00237 exp (const Tangent& z) {
00238 C e= exp (base (z));
00239 return Tangent (e, e * slope (z));
00240 }
00241
00242 TMPL inline Tangent
00243 log (const Tangent& z) {
00244 return Tangent (log (base (z)), invert (base (z)) * slope (z));
00245 }
00246
00247 template<typename C, typename D, typename K> inline Tangent
00248 pow (const Tangent& z, const K& y) {
00249 return exp (Tangent (y) * log (z));
00250 }
00251
00252 TMPL inline Tangent
00253 cos (const Tangent& z) {
00254 return Tangent (cos (base (z)), -sin (base (z)) * slope (z));
00255 }
00256
00257 TMPL inline Tangent
00258 sin (const Tangent& z) {
00259 return Tangent (sin (base (z)), cos (base (z)) * slope (z));
00260 }
00261
00262 TMPL inline Tangent
00263 tan (const Tangent& z) {
00264 return sin (z) / cos (z);
00265 }
00266
00267 TMPL inline Tangent
00268 cosh (const Tangent& z) {
00269 return Tangent (cosh (base (z)), sinh (base (z)) * slope (z));
00270 }
00271
00272 TMPL inline Tangent
00273 sinh (const Tangent& z) {
00274 return Tangent (sinh (base (z)), cosh (base (z)) * slope (z));
00275 }
00276
00277 TMPL Tangent
00278 tanh (const Tangent& z) {
00279 return sinh (z) / cosh (z);
00280 }
00281
00282 TMPL Tangent
00283 acos (const Tangent& z) {
00284 C df= -invert (sqrt (promote (1, base (z)) - square (base (z))));
00285 return Tangent (acos (base (z)), df * slope (z));
00286 }
00287
00288 TMPL Tangent
00289 asin (const Tangent& z) {
00290 C df= invert (sqrt (promote (1, base (z)) - square (base (z))));
00291 return Tangent (asin (base (z)), df * slope (z));
00292 }
00293
00294 TMPL Tangent
00295 atan (const Tangent& z) {
00296 C df= invert (promote (1, base (z)) + square (base (z)));
00297 return Tangent (asin (base (z)), df * slope (z));
00298 }
00299
00300 TMPL Tangent
00301 atan2 (const Tangent& y, const Tangent& x) {
00302 ERROR ("not yet implemented");
00303 return Tangent (atan2 (base (y), base (x)), 0);
00304 }
00305
00306 HYPOT_SUGAR(TMPL,Tangent)
00307 INV_TRIGO_SUGAR(TMPL,Tangent)
00308 INV_HYPER_SUGAR(TMPL,Tangent)
00309 ARG_HYPER_SUGAR(TMPL,Tangent)
00310
00311
00312
00313
00314
00315 TMPL inline bool
00316 operator <= (const Tangent& z1, const Tangent& z2) {
00317 return base (z1) < base (z2) || z1 == z2;
00318 }
00319
00320 TMPL inline bool
00321 operator < (const Tangent& z1, const Tangent& z2) {
00322 return base (z1) < base (z2);
00323 }
00324
00325 TMPL inline bool
00326 operator >= (const Tangent& z1, const Tangent& z2) {
00327 return base (z1) > base (z2) || z1 == z2;
00328 }
00329
00330 TMPL inline bool
00331 operator > (const Tangent& z1, const Tangent& z2) {
00332 return base (z1) > base (z2);
00333 }
00334
00335 TMPL inline Tangent
00336 min (const Tangent& z1, const Tangent& z2) {
00337 if (z1 <= z2) return z1; else return z2;
00338 }
00339
00340 TMPL Tangent
00341 max (const Tangent& z1, const Tangent& z2) {
00342 if (z1 >= z2) return z1; else return z2;
00343 }
00344
00345 EQUAL_INT_SUGAR(TMPL,Tangent);
00346 COMPARE_INT_SUGAR(TMPL,Tangent);
00347 EQUAL_SCALAR_SUGAR(TMPL,Tangent,C);
00348 COMPARE_SCALAR_SUGAR(TMPL,Tangent,C);
00349 EQUAL_SCALAR_SUGAR_BIS(TMPL,Tangent,C);
00350 COMPARE_SCALAR_SUGAR_BIS(TMPL,Tangent,C);
00351
00352
00353
00354
00355
00356 TMPL inline bool is_finite (const Tangent& z) {
00357 return is_finite (base (z)) && is_finite (slope (z)); }
00358 TMPL inline bool is_nan (const Tangent& z) {
00359 return is_nan (base (z)) || is_nan (slope (z)); }
00360 TMPL inline bool is_infinite (const Tangent& z) {
00361 return !is_nan (z) && (is_infinite (base (z)) || is_infinite (slope (z))); }
00362 TMPL inline bool is_fuzz (const Tangent& z) {
00363 return !is_nan (z) && (is_fuzz (base (z)) || is_fuzz (slope (z))); }
00364 TMPL inline bool is_reliable (const Tangent& z) {
00365 return is_reliable (base (z)); }
00366
00367 TMPL inline Tangent change_precision (const Tangent& z, xnat prec) {
00368 return Tangent (change_precision (base (z), prec),
00369 change_precision (slope (z), prec)); }
00370 TMPL inline xnat precision (const Tangent& z) {
00371 return precision (base (z)); }
00372 TMPL inline Tangent additive_error (const Tangent& z) {
00373 return Tangent (additive_error (base (z)), additive_error (slope (z))); }
00374
00375 TMPL inline double magnitude (const Tangent& z) {
00376 return magnitude (base (z)); }
00377 TMPL inline xint exponent (const Tangent& z) {
00378 return exponent (base (z)); }
00379 TMPL inline Tangent operator << (const Tangent& z, const xint& shift) {
00380 return Tangent (incexp2 (base (z), shift), incexp2 (slope (z), shift)); }
00381 TMPL inline Tangent operator >> (const Tangent& z, const xint& shift) {
00382 return Tangent (decexp2 (base (z), shift), decexp2 (slope (z), shift)); }
00383
00384 TMPL inline Tangent sharpen (const Tangent& z) {
00385 return Tangent (sharpen (base (z)), sharpen (slope (z))); }
00386 template<typename C, typename D, typename C2, typename D2> inline Tangent
00387 blur (const Tangent& z, const tangent<C2,D2>& r) {
00388 return Tangent (blur (base (z), base (r)), blur (slope (z), slope (r))); }
00389
00390
00391
00392
00393
00394 TMPL inline Abs_tangent
00395 abs (const Tangent& z) {
00396
00397 return Abs_tangent (abs (base (z)), abs (slope (z)));
00398 }
00399
00400 TMPL inline Real_tangent
00401 Re (const Tangent& z) {
00402 return Real_tangent (Re (base (z)), Re (slope (z)));
00403 }
00404
00405 TMPL inline Real_tangent
00406 Im (const Tangent& z) {
00407 return Real_tangent (Im (base (z)), Im (slope (z)));
00408 }
00409
00410
00411
00412
00413
00414 template<typename CS, typename CD, typename DS, typename DD,
00415 typename FunC, typename FunD> tangent<CD,DD>
00416 map_tangent (const FunC& funC, const FunD& funD,
00417 const tangent<CS,DS>& z,
00418 const format<CD>& fmC, const format<DD>& fmD) {
00419
00420 return tangent<CD,DD> (funC (base (z)), funD (slope (z)));
00421 }
00422
00423 #undef TMPL_DEF
00424 #undef TMPL
00425 #undef Tangent
00426 #undef Abs_tangent
00427 #undef Real_tangent
00428 }
00429 #endif // __MMX_TANGENT_HPP