numerix_doc 0.4
/Users/mourrain/Devel/mmx/numerix/include/numerix/tangent.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines