numerix_doc 0.4
|
00001 00002 /****************************************************************************** 00003 * MODULE : tangent.hpp 00004 * DESCRIPTION: Efficient computations in first order jet spaces C[X]/(X^2) 00005 * COPYRIGHT : (C) 2006 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_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 * The tangent type 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 * Basic routines 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> tangent<CD,DD> 00094 map (const function_1<CD,Argument(CS) >& funC, 00095 const function_1<DD,Argument(DS) >& funD, 00096 const tangent<CS,DS>& z, 00097 const format<CD>& fmC, 00098 const format<DD>& fmD) { 00099 return tangent<CD,DD> (funC (base (z)), funD (slope (z))); 00100 } 00101 00102 TRUE_IDENTITY_OP_SUGAR(TMPL,Tangent) 00103 EXACT_IDENTITY_OP_SUGAR(TMPL,Tangent) 00104 HARD_IDENTITY_OP_SUGAR(TMPL,Tangent) 00105 00106 TMPL syntactic 00107 flatten (const Tangent& z) { 00108 return apply ("tangent", flatten (base (z)), flatten (slope (z))); 00109 } 00110 00111 TMPL 00112 struct binary_helper<Tangent >: public void_binary_helper<Tangent > { 00113 static inline string short_type_name () { 00114 return "Ta" * Short_type_name (C) * Short_type_name (D); } 00115 static inline generic full_type_name () { 00116 return gen ("Tangent", Full_type_name (C)); } 00117 static inline generic disassemble (const Tangent& z) { 00118 return gen_vec (as<generic> (base (z)), as<generic> (slope (z))); } 00119 static inline Tangent assemble (const generic& v) { 00120 return Tangent (as<C> (vector_access (v, 0)), 00121 as<D> (vector_access (v, 1))); } 00122 static inline void write (const port& out, const Tangent& z) { 00123 binary_write<C> (out, base (z)); 00124 binary_write<D> (out, slope (z)); } 00125 static inline Tangent read (const port& in) { 00126 C b= binary_read<C> (in); 00127 D s= binary_read<D> (in); 00128 return Tangent (b, s); } 00129 }; 00130 00131 /****************************************************************************** 00132 * Constants 00133 ******************************************************************************/ 00134 00135 TMPL inline void set_nan (Tangent& z) { 00136 set_nan (base (z)); set_nan (slope (z)); } 00137 TMPL inline void set_infinity (Tangent& z) { 00138 set_infinity (base (z)); set_zero (slope (z)); } 00139 TMPL inline void set_fuzz (Tangent& z) { 00140 set_fuzz (base (z)); set_fuzz (slope (z)); } 00141 TMPL inline void set_smallest (Tangent& z) { 00142 set_smallest (base (z)); set_zero (slope (z)); } 00143 TMPL inline void set_largest (Tangent& z) { 00144 set_largest (base (z)); set_zero (slope (z)); } 00145 TMPL inline void set_accuracy (Tangent& z) { 00146 set_accuracy (base (z)); set_zero (slope (z)); } 00147 TMPL inline void set_log2 (Tangent& z) { 00148 set_log2 (base (z)); set_zero (slope (z)); } 00149 TMPL inline void set_pi (Tangent& z) { 00150 set_pi (base (z)); set_zero (slope (z)); } 00151 TMPL inline void set_euler (Tangent& z) { 00152 set_euler (base (z)); set_zero (slope (z)); } 00153 TMPL inline void set_imaginary (Tangent& z) { 00154 set_imaginary (base (z)); set_zero (slope (z)); } 00155 TMPL inline Tangent times_infinity (const Tangent& x) { 00156 return x * infinity_cst<Tangent > (); } 00157 00158 /****************************************************************************** 00159 * Basic arithmetic 00160 ******************************************************************************/ 00161 00162 TMPL inline Tangent 00163 operator - (const Tangent& z) { 00164 return Tangent (-base (z), -slope (z)); 00165 } 00166 00167 TMPL inline Tangent 00168 operator + (const Tangent& z1, const Tangent& z2) { 00169 return Tangent (base (z1) + base (z2), slope (z1) + slope (z2)); 00170 } 00171 00172 TMPL inline Tangent 00173 operator - (const Tangent& z1, const Tangent& z2) { 00174 return Tangent (base (z1) - base (z2), slope (z1) - slope (z2)); 00175 } 00176 00177 TMPL inline Tangent 00178 operator * (const Tangent& z1, const Tangent& z2) { 00179 return Tangent (base (z1) * base (z2), 00180 base (z1) * slope (z2) + slope (z1) * base (z2)); 00181 } 00182 00183 TMPL inline Tangent 00184 operator * (const C& z1, const Tangent& z2) { 00185 return Tangent (z1 * base (z2), z1 * slope (z2)); 00186 } 00187 00188 TMPL inline Tangent 00189 operator * (const Tangent& z1, const C& z2) { 00190 return Tangent (base (z1) * z2, slope (z1) * z2); 00191 } 00192 00193 TMPL inline Tangent 00194 square (const Tangent& z) { 00195 return Tangent (square (base (z)), (base (z) + base (z)) * slope (z)); 00196 } 00197 00198 TMPL inline Tangent 00199 invert (const Tangent& z) { 00200 C inv= invert (base (z)); 00201 return Tangent (inv, - square (inv) * slope (z)); 00202 } 00203 00204 TMPL inline Tangent 00205 operator / (const Tangent& z1, const Tangent& z2) { 00206 C inv= invert (base (z2)); 00207 return Tangent (inv * base (z1), 00208 inv * (slope (z1) - inv * base (z1) * slope (z2))); 00209 } 00210 00211 TMPL inline Tangent 00212 operator / (const C& z1, const Tangent& z2) { 00213 C inv= invert (base (z2)); 00214 return Tangent (inv * z1, - square (inv) * z1 * slope (z2)); 00215 } 00216 00217 TMPL inline Tangent 00218 operator / (const Tangent& z1, const C& z2) { 00219 C inv= invert (z2); 00220 return Tangent (inv * base (z1), inv * slope (z1)); 00221 } 00222 00223 ARITH_INT_SUGAR(TMPL,Tangent); 00224 00225 /****************************************************************************** 00226 * Elementary functions 00227 ******************************************************************************/ 00228 00229 TMPL inline Tangent 00230 sqrt (const Tangent& z) { 00231 C s= sqrt (base (z)); 00232 return Tangent (s, invert (s + s) * slope (z)); 00233 } 00234 00235 TMPL inline Tangent 00236 exp (const Tangent& z) { 00237 C e= exp (base (z)); 00238 return Tangent (e, e * slope (z)); 00239 } 00240 00241 TMPL inline Tangent 00242 log (const Tangent& z) { 00243 return Tangent (log (base (z)), invert (base (z)) * slope (z)); 00244 } 00245 00246 template<typename C, typename D, typename K> inline Tangent 00247 pow (const Tangent& z, const K& y) { 00248 return exp (Tangent (y) * log (z)); 00249 } 00250 00251 TMPL inline Tangent 00252 cos (const Tangent& z) { 00253 return Tangent (cos (base (z)), -sin (base (z)) * slope (z)); 00254 } 00255 00256 TMPL inline Tangent 00257 sin (const Tangent& z) { 00258 return Tangent (sin (base (z)), cos (base (z)) * slope (z)); 00259 } 00260 00261 TMPL inline Tangent 00262 tan (const Tangent& z) { 00263 return sin (z) / cos (z); 00264 } 00265 00266 TMPL inline Tangent 00267 cosh (const Tangent& z) { 00268 return Tangent (cosh (base (z)), sinh (base (z)) * slope (z)); 00269 } 00270 00271 TMPL inline Tangent 00272 sinh (const Tangent& z) { 00273 return Tangent (sinh (base (z)), cosh (base (z)) * slope (z)); 00274 } 00275 00276 TMPL Tangent 00277 tanh (const Tangent& z) { 00278 return sinh (z) / cosh (z); 00279 } 00280 00281 TMPL Tangent 00282 acos (const Tangent& z) { 00283 C df= -invert (sqrt (promote (1, base (z)) - square (base (z)))); 00284 return Tangent (acos (base (z)), df * slope (z)); 00285 } 00286 00287 TMPL Tangent 00288 asin (const Tangent& z) { 00289 C df= invert (sqrt (promote (1, base (z)) - square (base (z)))); 00290 return Tangent (asin (base (z)), df * slope (z)); 00291 } 00292 00293 TMPL Tangent 00294 atan (const Tangent& z) { 00295 C df= invert (promote (1, base (z)) + square (base (z))); 00296 return Tangent (asin (base (z)), df * slope (z)); 00297 } 00298 00299 TMPL Tangent 00300 atan2 (const Tangent& y, const Tangent& x) { 00301 ERROR ("not yet implemented"); 00302 return Tangent (atan2 (base (y), base (x)), 0); 00303 } 00304 00305 HYPOT_SUGAR(TMPL,Tangent) 00306 INV_TRIGO_SUGAR(TMPL,Tangent) 00307 INV_HYPER_SUGAR(TMPL,Tangent) 00308 ARG_HYPER_SUGAR(TMPL,Tangent) 00309 00310 /****************************************************************************** 00311 * Comparisons and other order related functions 00312 ******************************************************************************/ 00313 00314 TMPL inline bool 00315 operator <= (const Tangent& z1, const Tangent& z2) { 00316 return base (z1) < base (z2) || z1 == z2; 00317 } 00318 00319 TMPL inline bool 00320 operator < (const Tangent& z1, const Tangent& z2) { 00321 return base (z1) < base (z2); 00322 } 00323 00324 TMPL inline bool 00325 operator >= (const Tangent& z1, const Tangent& z2) { 00326 return base (z1) > base (z2) || z1 == z2; 00327 } 00328 00329 TMPL inline bool 00330 operator > (const Tangent& z1, const Tangent& z2) { 00331 return base (z1) > base (z2); 00332 } 00333 00334 TMPL inline Tangent 00335 min (const Tangent& z1, const Tangent& z2) { 00336 if (z1 <= z2) return z1; else return z2; 00337 } 00338 00339 TMPL Tangent 00340 max (const Tangent& z1, const Tangent& z2) { 00341 if (z1 >= z2) return z1; else return z2; 00342 } 00343 00344 EQUAL_INT_SUGAR(TMPL,Tangent); 00345 COMPARE_INT_SUGAR(TMPL,Tangent); 00346 00347 /****************************************************************************** 00348 * Floating point related functions 00349 ******************************************************************************/ 00350 00351 TMPL inline bool is_finite (const Tangent& z) { 00352 return is_finite (base (z)) && is_finite (slope (z)); } 00353 TMPL inline bool is_nan (const Tangent& z) { 00354 return is_nan (base (z)) || is_nan (slope (z)); } 00355 TMPL inline bool is_infinite (const Tangent& z) { 00356 return !is_nan (z) && (is_infinite (base (z)) || is_infinite (slope (z))); } 00357 TMPL inline bool is_fuzz (const Tangent& z) { 00358 return !is_nan (z) && (is_fuzz (base (z)) || is_fuzz (slope (z))); } 00359 TMPL inline bool is_reliable (const Tangent& z) { 00360 return is_reliable (base (z)); } 00361 00362 TMPL inline Tangent change_precision (const Tangent& z, xnat prec) { 00363 return Tangent (change_precision (base (z), prec), 00364 change_precision (slope (z), prec)); } 00365 TMPL inline xnat precision (const Tangent& z) { 00366 return precision (base (z)); } 00367 TMPL inline Tangent additive_error (const Tangent& z) { 00368 return Tangent (additive_error (base (z)), additive_error (slope (z))); } 00369 00370 TMPL inline double magnitude (const Tangent& z) { 00371 return magnitude (base (z)); } 00372 TMPL inline xint exponent (const Tangent& z) { 00373 return exponent (base (z)); } 00374 TMPL inline Tangent operator << (const Tangent& z, const xint& shift) { 00375 return Tangent (incexp2 (base (z), shift), incexp2 (slope (z), shift)); } 00376 TMPL inline Tangent operator >> (const Tangent& z, const xint& shift) { 00377 return Tangent (decexp2 (base (z), shift), decexp2 (slope (z), shift)); } 00378 00379 TMPL inline Tangent sharpen (const Tangent& z) { 00380 return Tangent (sharpen (base (z)), sharpen (slope (z))); } 00381 template<typename C, typename D, typename C2, typename D2> inline Tangent 00382 blur (const Tangent& z, const tangent<C2,D2>& r) { 00383 return Tangent (blur (base (z), base (r)), blur (slope (z), slope (r))); } 00384 00385 /****************************************************************************** 00386 * Complex tangent numbers 00387 ******************************************************************************/ 00388 00389 TMPL inline Abs_tangent 00390 abs (const Tangent& z) { 00391 // FIXME: this is not really nice 00392 return Abs_tangent (abs (base (z)), abs (slope (z))); 00393 } 00394 00395 TMPL inline Real_tangent 00396 Re (const Tangent& z) { 00397 return Real_tangent (Re (base (z)), Re (slope (z))); 00398 } 00399 00400 TMPL inline Real_tangent 00401 Im (const Tangent& z) { 00402 return Real_tangent (Im (base (z)), Im (slope (z))); 00403 } 00404 00405 #undef TMPL_DEF 00406 #undef TMPL 00407 #undef Tangent 00408 #undef Abs_tangent 00409 #undef Real_tangent 00410 } // namespace mmx 00411 #endif // __MMX_TANGENT_HPP