SourceForge Logo Tiny Vector Matrix library using Expression Templates Sourceforge Project Page

include/tvmet/NumericTraits.h

Go to the documentation of this file.
00001 /*
00002  * Tiny Vector Matrix Library
00003  * Dense Vector Matrix Libary of Tiny size using Expression Templates
00004  *
00005  * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  *
00021  * $Id: NumericTraits.h,v 1.16 2007-06-23 15:58:58 opetzold Exp $
00022  */
00023 
00024 #ifndef TVMET_NUMERIC_TRAITS_H
00025 #define TVMET_NUMERIC_TRAITS_H
00026 
00027 #if defined(TVMET_HAVE_COMPLEX)
00028 #  include <complex>
00029 #endif
00030 #include <cmath>
00031 #include <limits>
00032 
00033 #include <tvmet/CompileTimeError.h>
00034 
00035 
00036 namespace tvmet {
00037 
00038 
00057 template<class T>
00058 struct NumericTraits {
00059   typedef T         base_type;
00060   typedef T         value_type;
00061   typedef value_type        sum_type;
00062   typedef value_type        diff_type;
00063   typedef value_type        float_type;
00064   typedef value_type        signed_type;
00065 
00066   typedef NumericTraits<value_type>   traits_type;
00067   typedef const value_type&     argument_type;
00068 
00069   static inline
00070   base_type real(argument_type x);
00071 
00072   static inline
00073   base_type imag(argument_type x);
00074 
00075   static inline
00076   value_type conj(argument_type x);
00077 
00078   static inline
00079   base_type abs(argument_type x);
00080 
00081   static inline
00082   value_type sqrt(argument_type x);
00083 
00084   static inline
00085   base_type norm_1(argument_type x) {
00086     return NumericTraits<base_type>::abs(traits_type::real(x))
00087          + NumericTraits<base_type>::abs(traits_type::imag(x));
00088   }
00089 
00090   static inline
00091   base_type norm_2(argument_type x) { return traits_type::abs(x); }
00092 
00093   static inline
00094   base_type norm_inf(argument_type x) {
00095     return std::max(NumericTraits<base_type>::abs(traits_type::real(x)),
00096         NumericTraits<base_type>::abs(traits_type::imag(x)));
00097    }
00098 
00099   static inline
00100   bool equals(argument_type lhs, argument_type rhs) {
00101     static base_type sqrt_epsilon(
00102       NumericTraits<base_type>::sqrt(
00103         std::numeric_limits<base_type>::epsilon()));
00104 
00105     return traits_type::norm_inf(lhs - rhs) < sqrt_epsilon *
00106       std::max(std::max(traits_type::norm_inf(lhs),
00107       traits_type::norm_inf(rhs)),
00108          std::numeric_limits<base_type>::min());
00109   }
00110 };
00111 
00112 
00113 /*
00114  * numeric traits for standard types
00115  */
00116 
00117 
00122 template<>
00123 struct NumericTraits<char> {
00124   typedef char          value_type;
00125   typedef value_type        base_type;
00126   typedef long          sum_type;
00127   typedef int         diff_type;
00128   typedef float         float_type;
00129   typedef char          signed_type;
00130 
00131   typedef NumericTraits<value_type>   traits_type;
00132   typedef value_type        argument_type;
00133 
00134   static inline
00135   base_type real(argument_type x) { return x; }
00136 
00137   static inline
00138   base_type imag(argument_type) { return 0; }
00139 
00140   static inline
00141   value_type conj(argument_type x) { return x; }
00142 
00143   static inline
00144   base_type abs(argument_type x) { return std::abs(x); }
00145 
00146   static inline
00147   value_type sqrt(argument_type x) {
00148     return static_cast<value_type>(std::sqrt(static_cast<float_type>(x)));
00149   }
00150 
00151   static inline
00152   base_type norm_1(argument_type x) { return traits_type::abs(x); }
00153 
00154   static inline
00155   base_type norm_2(argument_type x) { return traits_type::abs(x); }
00156 
00157   static inline
00158   base_type norm_inf(argument_type x) { return traits_type::abs(x); }
00159 
00160   static inline
00161   bool equals(argument_type lhs, argument_type rhs) { return lhs == rhs; }
00162 
00163   enum { is_complex = false };
00164 
00166   enum {
00167     ops_plus = 1, 
00168     ops_muls = 1  
00169   };
00170 };
00171 
00172 
00182 template<>
00183 struct NumericTraits<unsigned char> {
00184   typedef unsigned char       value_type;
00185   typedef value_type        base_type;
00186   typedef unsigned long       sum_type;
00187   typedef int         diff_type;
00188   typedef float         float_type;
00189   typedef int         signed_type;
00190 
00191   typedef NumericTraits<value_type>   traits_type;
00192   typedef value_type        argument_type;
00193 
00194   static inline
00195   base_type real(argument_type x) { return x; }
00196 
00197   static inline
00198   base_type imag(argument_type) { return 0; }
00199 
00200   static inline
00201   base_type abs(argument_type x) { return std::abs(x); }
00202 
00203   static inline
00204   value_type sqrt(argument_type x) {
00205     return static_cast<value_type>(std::sqrt(static_cast<float_type>(x)));
00206   }
00207 
00208   static inline
00209   base_type norm_1(argument_type x) { return traits_type::abs(x); }
00210 
00211   static inline
00212   base_type norm_2(argument_type x) { return traits_type::abs(x); }
00213 
00214   static inline
00215   base_type norm_inf(argument_type x) { return traits_type::abs(x); }
00216 
00217   static inline
00218   bool equals(argument_type lhs, argument_type rhs) { return lhs == rhs; }
00219 
00220   enum { is_complex = false };
00221 
00223   enum {
00224     ops_plus = 1, 
00225     ops_muls = 1  
00226   };
00227 };
00228 
00229 
00234 template<>
00235 struct NumericTraits<short int> {
00236   typedef short int         value_type;
00237   typedef value_type        base_type;
00238 #if defined(TVMET_HAVE_LONG_LONG)
00239   typedef long long       sum_type;
00240 #else
00241   typedef long          sum_type;
00242 #endif
00243   typedef int         diff_type;
00244   typedef float         float_type;
00245   typedef short int       signed_type;
00246 
00247   typedef NumericTraits<value_type>   traits_type;
00248   typedef value_type        argument_type;
00249 
00250   static inline
00251   base_type real(argument_type x) { return x; }
00252 
00253   static inline
00254   base_type imag(argument_type) { return 0; }
00255 
00256   static inline
00257   value_type conj(argument_type x) { return x; }
00258 
00259   static inline
00260   base_type abs(argument_type x) { return std::abs(x); }
00261 
00262   static inline
00263   value_type sqrt(argument_type x) {
00264     return static_cast<value_type>(std::sqrt(static_cast<float_type>(x)));
00265   }
00266 
00267   static inline
00268   base_type norm_1(argument_type x) { return traits_type::abs(x); }
00269 
00270   static inline
00271   base_type norm_2(argument_type x) { return traits_type::abs(x); }
00272 
00273   static inline
00274   base_type norm_inf(argument_type x) { return traits_type::abs(x); }
00275 
00276   static inline
00277   bool equals(argument_type lhs, argument_type rhs) { return lhs == rhs; }
00278 
00279   enum { is_complex = false };
00280 
00282   enum {
00283     ops_plus = 1, 
00284     ops_muls = 1  
00285   };
00286 };
00287 
00288 
00298 template<>
00299 struct NumericTraits<short unsigned int> {
00300   typedef short unsigned int      value_type;
00301   typedef value_type        base_type;
00302 #if defined(TVMET_HAVE_LONG_LONG)
00303   typedef unsigned long long      sum_type;
00304 #else
00305   typedef unsigned long       sum_type;
00306 #endif
00307   typedef int           diff_type;
00308   typedef float         float_type;
00309   typedef int         signed_type;
00310 
00311   typedef NumericTraits<value_type>   traits_type;
00312   typedef value_type        argument_type;
00313 
00314   static inline
00315   base_type real(argument_type x) { return x; }
00316 
00317   static inline
00318   base_type imag(argument_type) { return 0; }
00319 
00320   static inline
00321   base_type abs(argument_type x) { return std::abs(x); }
00322 
00323   static inline
00324   value_type sqrt(argument_type x) {
00325     return static_cast<value_type>(std::sqrt(static_cast<float_type>(x)));
00326   }
00327 
00328   static inline
00329   base_type norm_1(argument_type x) { return traits_type::abs(x); }
00330 
00331   static inline
00332   base_type norm_2(argument_type x) { return traits_type::abs(x); }
00333 
00334   static inline
00335   base_type norm_inf(argument_type x) { return traits_type::abs(x); }
00336 
00337   static inline
00338   bool equals(argument_type lhs, argument_type rhs) { return lhs == rhs; }
00339 
00340   enum { is_complex = false };
00341 
00343   enum {
00344     ops_plus = 1, 
00345     ops_muls = 1  
00346   };
00347 };
00348 
00349 
00354 template<>
00355 struct NumericTraits<int> {
00356   typedef int           value_type;
00357   typedef value_type        base_type;
00358 #if defined(TVMET_HAVE_LONG_LONG)
00359   typedef long long       sum_type;
00360 #else
00361   typedef long          sum_type;
00362 #endif
00363   typedef int         diff_type;
00364   typedef double        float_type;
00365   typedef int         signed_type;
00366 
00367   typedef NumericTraits<value_type>   traits_type;
00368   typedef value_type        argument_type;
00369 
00370   static inline
00371   base_type real(argument_type x) { return x; }
00372 
00373   static inline
00374   base_type imag(argument_type) { return 0; }
00375 
00376   static inline
00377   value_type conj(argument_type x) { return x; }
00378 
00379   static inline
00380   base_type abs(argument_type x) { return std::abs(x); }
00381 
00382   static inline
00383   value_type sqrt(argument_type x) {
00384     return static_cast<value_type>(std::sqrt(static_cast<float_type>(x)));
00385   }
00386 
00387   static inline
00388   base_type norm_1(argument_type x) { return traits_type::abs(x); }
00389 
00390   static inline
00391   base_type norm_2(argument_type x) { return traits_type::abs(x); }
00392 
00393   static inline
00394   base_type norm_inf(argument_type x) { return traits_type::abs(x); }
00395 
00396   static inline
00397   bool equals(argument_type lhs, argument_type rhs) { return lhs == rhs; }
00398 
00399   enum { is_complex = false };
00400 
00402   enum {
00403     ops_plus = 1, 
00404     ops_muls = 1  
00405   };
00406 };
00407 
00408 
00418 template<>
00419 struct NumericTraits<unsigned int> {
00420   typedef unsigned int        value_type;
00421   typedef value_type        base_type;
00422 #if defined(TVMET_HAVE_LONG_LONG)
00423   typedef unsigned long long      sum_type;
00424 #else
00425   typedef unsigned long       sum_type;
00426 #endif
00427   typedef int           diff_type;
00428   typedef double        float_type;
00429   typedef long          signed_type;
00430 
00431   typedef NumericTraits<value_type>   traits_type;
00432   typedef value_type        argument_type;
00433 
00434   static inline
00435   base_type real(argument_type x) { return x; }
00436 
00437   static inline
00438   base_type imag(argument_type) { return 0; }
00439 
00440   static inline
00441   base_type abs(argument_type x) { return x; }
00442 
00443   static inline
00444   value_type sqrt(argument_type x) {
00445     return static_cast<value_type>(std::sqrt(static_cast<float_type>(x)));
00446   }
00447 
00448   static inline
00449   base_type norm_1(argument_type x) { return traits_type::abs(x); }
00450 
00451   static inline
00452   base_type norm_2(argument_type x) { return traits_type::abs(x); }
00453 
00454   static inline
00455   base_type norm_inf(argument_type x) { return traits_type::abs(x); }
00456 
00457   static inline
00458   bool equals(argument_type lhs, argument_type rhs) { return lhs == rhs; }
00459 
00460   enum { is_complex = false };
00461 
00463   enum {
00464     ops_plus = 1, 
00465     ops_muls = 1  
00466   };
00467 };
00468 
00469 
00474 template<>
00475 struct NumericTraits<long> {
00476   typedef long          value_type;
00477   typedef value_type        base_type;
00478 #if defined(TVMET_HAVE_LONG_LONG)
00479   typedef long long       sum_type;
00480 #else
00481   typedef long            sum_type;
00482 #endif
00483   typedef long          diff_type;
00484   typedef double        float_type;
00485   typedef long          signed_type;
00486 
00487   typedef NumericTraits<value_type>   traits_type;
00488   typedef value_type        argument_type;
00489 
00490   static inline
00491   base_type real(argument_type x) { return x; }
00492 
00493   static inline
00494   base_type imag(argument_type) { return 0; }
00495 
00496   static inline
00497   value_type conj(argument_type x) { return x; }
00498 
00499   static inline
00500   base_type abs(argument_type x) { return std::abs(x); }
00501 
00502   static inline
00503   value_type sqrt(argument_type x) {
00504     return static_cast<value_type>(std::sqrt(static_cast<float_type>(x)));
00505   }
00506 
00507   static inline
00508   base_type norm_1(argument_type x) { return traits_type::abs(x); }
00509 
00510   static inline
00511   base_type norm_2(argument_type x) { return traits_type::abs(x); }
00512 
00513   static inline
00514   base_type norm_inf(argument_type x) { return traits_type::abs(x); }
00515 
00516   static inline
00517   bool equals(argument_type lhs, argument_type rhs) { return lhs == rhs; }
00518 
00519   enum { is_complex = false };
00520 
00522   enum {
00523     ops_plus = 1, 
00524     ops_muls = 1  
00525   };
00526 };
00527 
00528 
00538 template<>
00539 struct NumericTraits<unsigned long> {
00540   typedef unsigned long       value_type;
00541   typedef value_type        base_type;
00542 #if defined(TVMET_HAVE_LONG_LONG)
00543   typedef unsigned long long      sum_type;
00544 #else
00545   typedef unsigned long       sum_type;
00546 #endif
00547   typedef unsigned long       diff_type;
00548   typedef double        float_type;
00549   typedef long          signed_type;
00550 
00551   typedef NumericTraits<value_type>   traits_type;
00552   typedef value_type        argument_type;
00553 
00554   static inline
00555   base_type real(argument_type x) { return x; }
00556 
00557   static inline
00558   base_type imag(argument_type) { return 0; }
00559 
00560   static inline
00561   base_type abs(argument_type x) { return x; }
00562 
00563   static inline
00564   value_type sqrt(argument_type x) {
00565     return static_cast<value_type>(std::sqrt(static_cast<float_type>(x)));
00566   }
00567 
00568   static inline
00569   base_type norm_1(argument_type x) { return traits_type::abs(x); }
00570 
00571   static inline
00572   base_type norm_2(argument_type x) { return traits_type::abs(x); }
00573 
00574   static inline
00575   base_type norm_inf(argument_type x) { return traits_type::abs(x); }
00576 
00577   static inline
00578   bool equals(argument_type lhs, argument_type rhs) { return lhs == rhs; }
00579 
00580   enum { is_complex = false };
00581 
00583   enum {
00584     ops_plus = 1, 
00585     ops_muls = 1  
00586   };
00587 };
00588 
00589 
00594 template<>
00595 struct NumericTraits<float> {
00596   typedef float         value_type;
00597   typedef value_type        base_type;
00598   typedef double        sum_type;
00599   typedef float         diff_type;
00600   typedef float         float_type;
00601   typedef float         signed_type;
00602 
00603   typedef NumericTraits<value_type>   traits_type;
00604   typedef value_type        argument_type;
00605 
00606   static inline
00607   base_type real(argument_type x) { return x; }
00608 
00609   static inline
00610   base_type imag(argument_type) { return 0; }
00611 
00612   static inline
00613   value_type conj(argument_type x) { return x; }
00614 
00615   static inline
00616   base_type abs(argument_type x) { return std::abs(x); }
00617 
00618   static inline
00619   value_type sqrt(argument_type x) { return std::sqrt(x); }
00620 
00621   static inline
00622   base_type norm_1(argument_type x) { return traits_type::abs(x); }
00623 
00624   static inline
00625   base_type norm_2(argument_type x) { return traits_type::abs(x); }
00626 
00627   static inline
00628   base_type norm_inf(argument_type x) { return traits_type::abs(x); }
00629 
00630   static inline
00631   bool equals(argument_type lhs, argument_type rhs) {
00632     static base_type sqrt_epsilon(
00633       NumericTraits<base_type>::sqrt(
00634         std::numeric_limits<base_type>::epsilon()));
00635 
00636     return traits_type::norm_inf(lhs - rhs) < sqrt_epsilon *
00637       std::max(std::max(traits_type::norm_inf(lhs),
00638       traits_type::norm_inf(rhs)),
00639          std::numeric_limits<base_type>::min());
00640   }
00641 
00642   enum { is_complex = false };
00643 
00645   enum {
00646     ops_plus = 1, 
00647     ops_muls = 1  
00648   };
00649 };
00650 
00651 
00656 template<>
00657 struct NumericTraits<double> {
00658   typedef double        value_type;
00659   typedef value_type        base_type;
00660 #if defined(TVMET_HAVE_LONG_DOUBLE)
00661   typedef long double       sum_type;
00662 #else
00663   typedef double        sum_type;
00664 #endif
00665   typedef double        diff_type;
00666   typedef double        float_type;
00667   typedef double        signed_type;
00668 
00669   typedef NumericTraits<value_type>   traits_type;
00670   typedef value_type        argument_type;
00671 
00672   static inline
00673   base_type real(argument_type x) { return x; }
00674 
00675   static inline
00676   base_type imag(argument_type) { return 0; }
00677 
00678   static inline
00679   value_type conj(argument_type x) { return x; }
00680 
00681   static inline
00682   base_type abs(argument_type x) { return std::abs(x); }
00683 
00684   static inline
00685   value_type sqrt(argument_type x) { return std::sqrt(x); }
00686 
00687   static inline
00688   base_type norm_1(argument_type x) { return traits_type::abs(x); }
00689 
00690   static inline
00691   base_type norm_2(argument_type x) { return traits_type::abs(x); }
00692 
00693   static inline
00694   base_type norm_inf(argument_type x) { return traits_type::abs(x); }
00695 
00696   static inline
00697   bool equals(argument_type lhs, argument_type rhs) {
00698     static base_type sqrt_epsilon(
00699       NumericTraits<base_type>::sqrt(
00700         std::numeric_limits<base_type>::epsilon()));
00701 
00702     return traits_type::norm_inf(lhs - rhs) < sqrt_epsilon *
00703       std::max(std::max(traits_type::norm_inf(lhs),
00704       traits_type::norm_inf(rhs)),
00705          std::numeric_limits<base_type>::min());
00706   }
00707 
00708   enum { is_complex = false };
00709 
00711   enum {
00712     ops_plus = 1, 
00713     ops_muls = 1  
00714   };
00715 };
00716 
00717 
00718 #if defined(TVMET_HAVE_LONG_DOUBLE)
00719 
00723 template<>
00724 struct NumericTraits<long double> {
00725   typedef long double         value_type;
00726   typedef value_type        base_type;
00727   typedef long double       sum_type;
00728   typedef long double       diff_type;
00729   typedef long double         float_type;
00730   typedef long double       signed_type;
00731 
00732   typedef NumericTraits<value_type>   traits_type;
00733   typedef value_type        argument_type;
00734 
00735   static inline
00736   base_type real(argument_type x) { return x; }
00737 
00738   static inline
00739   base_type imag(argument_type) { return 0; }
00740 
00741   static inline
00742   value_type conj(argument_type x) { return x; }
00743 
00744   static inline
00745   base_type abs(argument_type x) { return std::abs(x); }
00746 
00747   static inline
00748   value_type sqrt(argument_type x) { return std::sqrt(x); }
00749 
00750   static inline
00751   base_type norm_1(argument_type x) { return traits_type::abs(x); }
00752 
00753   static inline
00754   base_type norm_2(argument_type x) { return traits_type::abs(x); }
00755 
00756   static inline
00757   base_type norm_inf(argument_type x) { return traits_type::abs(x); }
00758 
00759   static inline
00760   bool equals(argument_type lhs, argument_type rhs) {
00761     static base_type sqrt_epsilon(
00762       NumericTraits<base_type>::sqrt(
00763         std::numeric_limits<base_type>::epsilon()));
00764 
00765     return traits_type::norm_inf(lhs - rhs) < sqrt_epsilon *
00766       std::max(std::max(traits_type::norm_inf(lhs),
00767       traits_type::norm_inf(rhs)),
00768          std::numeric_limits<base_type>::min());
00769   }
00770 
00771   enum { is_complex = false };
00772 
00774   enum {
00775     ops_plus = 1, 
00776     ops_muls = 1  
00777   };
00778 };
00779 #endif // TVMET_HAVE_LONG_DOUBLE
00780 
00781 
00782 /*
00783  * numeric traits for complex types
00784  */
00785 #if defined(TVMET_HAVE_COMPLEX)
00786 
00791 template<>
00792 struct NumericTraits< std::complex<int> > {
00793   typedef int         base_type;
00794   typedef std::complex<int>     value_type;
00795   typedef std::complex<long>      sum_type;
00796   typedef std::complex<int>     diff_type;
00797   typedef std::complex<float>     float_type;
00798   typedef std::complex<int>     signed_type;
00799 
00800   typedef NumericTraits<value_type>   traits_type;
00801   typedef const value_type&     argument_type;
00802 
00803   static inline
00804   base_type real(argument_type z) { return std::real(z); }
00805 
00806   static inline
00807   base_type imag(argument_type z) { return std::imag(z); }
00808 
00809   static inline
00810   value_type conj(argument_type z) { return std::conj(z); }
00811 
00812   static inline
00813   base_type abs(argument_type z) {
00814     base_type x = z.real();
00815     base_type y = z.imag();
00816 
00817     // XXX probably case of overrun; header complex uses scaling
00818     return static_cast<base_type>(NumericTraits<base_type>::sqrt(x * x + y * y));
00819   }
00820 
00821   static /* inline */
00822   value_type sqrt(argument_type z) {
00823     // borrowed and adapted from header complex
00824     base_type x = z.real();
00825     base_type y = z.imag();
00826 
00827     if(x == base_type()) {
00828   base_type t = NumericTraits<base_type>::sqrt(
00829                         NumericTraits<base_type>::abs(y) / 2);
00830   return value_type(t, y < base_type() ? -t : t);
00831     }
00832     else {
00833       base_type t = NumericTraits<base_type>::sqrt(
00834           2 * (traits_type::abs(z)
00835                 + NumericTraits<base_type>::abs(x)));
00836       base_type u = t / 2;
00837       return x > base_type()
00838   ? value_type(u, y / t)
00839   : value_type(NumericTraits<base_type>::abs(y) / t, y < base_type() ? -u : u);
00840     }
00841   }
00842 
00843   static inline
00844   base_type norm_1(argument_type z) {
00845     return NumericTraits<base_type>::abs((traits_type::real(z)))
00846          + NumericTraits<base_type>::abs((traits_type::imag(z)));
00847   }
00848 
00849   static inline
00850   base_type norm_2(argument_type z) { return traits_type::abs(z); }
00851 
00852   static inline
00853   base_type norm_inf(argument_type z) {
00854     return std::max(NumericTraits<base_type>::abs(traits_type::real(z)),
00855         NumericTraits<base_type>::abs(traits_type::imag(z)));
00856   }
00857 
00858   static inline
00859   bool equals(argument_type lhs, argument_type rhs) {
00860     return (traits_type::real(lhs) == traits_type::real(rhs))
00861         && (traits_type::imag(lhs) == traits_type::imag(rhs));
00862   }
00863 
00864   enum { is_complex = true };
00865 
00867   enum {
00868     ops_plus = 2, 
00869     ops_muls = 6  
00870   };
00871 };
00872 
00873 
00883 template<>
00884 struct NumericTraits< std::complex<unsigned int> > {
00885   typedef unsigned int        base_type;
00886   typedef std::complex<unsigned int>    value_type;
00887   typedef std::complex<unsigned long>     sum_type;
00888   typedef std::complex<int>     diff_type;
00889   typedef std::complex<float>     float_type;
00890   typedef std::complex<int>     signed_type;
00891 
00892   typedef NumericTraits<value_type>   traits_type;
00893   typedef const value_type&     argument_type;
00894 
00895   static inline
00896   base_type real(argument_type z) { return std::real(z); }
00897 
00898   static inline
00899   base_type imag(argument_type z) { return std::imag(z); }
00900 
00901   static inline
00902   base_type abs(argument_type z) {
00903     base_type x = z.real();
00904     base_type y = z.imag();
00905 
00906     // XXX probably case of overrun; header complex uses scaling
00907     return static_cast<base_type>(NumericTraits<base_type>::sqrt(x * x + y * y));
00908   }
00909 
00910   static /* inline */
00911   value_type sqrt(argument_type z) {
00912     // borrowed and adapted from header complex
00913     base_type x = z.real();
00914     base_type y = z.imag();
00915 
00916     if(x == base_type()) {
00917   base_type t = NumericTraits<base_type>::sqrt(
00918                         NumericTraits<base_type>::abs(y) / 2);
00919   return value_type(t, t);
00920     }
00921     else {
00922       base_type t = NumericTraits<base_type>::sqrt(
00923           2 * (traits_type::abs(z)
00924                 + NumericTraits<base_type>::abs(x)));
00925       return value_type(t / 2, y / t);
00926     }
00927   }
00928 
00929   static inline
00930   base_type norm_1(argument_type z) {
00931     return NumericTraits<base_type>::abs((traits_type::real(z)))
00932          + NumericTraits<base_type>::abs((traits_type::imag(z)));
00933   }
00934 
00935   static inline
00936   base_type norm_2(argument_type z) { return traits_type::abs(z); }
00937 
00938   static inline
00939   base_type norm_inf(argument_type z) {
00940     return std::max(NumericTraits<base_type>::abs(traits_type::real(z)),
00941         NumericTraits<base_type>::abs(traits_type::imag(z)));
00942   }
00943 
00944   static inline
00945   bool equals(argument_type lhs, argument_type rhs) {
00946     return (traits_type::real(lhs) == traits_type::real(rhs))
00947         && (traits_type::imag(lhs) == traits_type::imag(rhs));
00948   }
00949 
00950   enum { is_complex = true };
00951 
00953   enum {
00954     ops_plus = 2, 
00955     ops_muls = 6  
00956   };
00957 };
00958 
00959 
00964 template<>
00965 struct NumericTraits< std::complex<long> > {
00966   typedef long          base_type;
00967   typedef std::complex<long>      value_type;
00968 #if defined(TVMET_HAVE_LONG_LONG)
00969   typedef std::complex<long long>   sum_type;
00970 #else
00971   typedef std::complex<long>      sum_type;
00972 #endif
00973   typedef std::complex<int>     diff_type;
00974   typedef std::complex<float>     float_type;
00975   typedef std::complex<int>     signed_type;
00976 
00977   typedef NumericTraits<value_type>   traits_type;
00978   typedef const value_type&     argument_type;
00979 
00980   static inline
00981   base_type real(argument_type z) { return std::real(z); }
00982 
00983   static inline
00984   base_type imag(argument_type z) { return std::imag(z); }
00985 
00986   static inline
00987   value_type conj(argument_type z) { return std::conj(z); }
00988 
00989   static inline
00990   base_type abs(argument_type z) {
00991     base_type x = z.real();
00992     base_type y = z.imag();
00993 
00994     // XXX probably case of overrun; header complex uses scaling
00995     return static_cast<base_type>(NumericTraits<base_type>::sqrt(x * x + y * y));
00996   }
00997 
00998   static /* inline */
00999   value_type sqrt(argument_type z) {
01000     // borrowed and adapted from header complex
01001     base_type x = z.real();
01002     base_type y = z.imag();
01003 
01004     if(x == base_type()) {
01005   base_type t = NumericTraits<base_type>::sqrt(
01006                         NumericTraits<base_type>::abs(y) / 2);
01007   return value_type(t, y < base_type() ? -t : t);
01008     }
01009     else {
01010       base_type t = NumericTraits<base_type>::sqrt(
01011           2 * (traits_type::abs(z)
01012                 + NumericTraits<base_type>::abs(x)));
01013       base_type u = t / 2;
01014       return x > base_type()
01015   ? value_type(u, y / t)
01016   : value_type(NumericTraits<base_type>::abs(y) / t, y < base_type() ? -u : u);
01017     }
01018   }
01019 
01020   static inline
01021   base_type norm_1(argument_type z) {
01022     return NumericTraits<base_type>::abs((traits_type::real(z)))
01023          + NumericTraits<base_type>::abs((traits_type::imag(z)));
01024   }
01025 
01026   static inline
01027   base_type norm_2(argument_type z) { return traits_type::abs(z); }
01028 
01029   static inline
01030   base_type norm_inf(argument_type z) {
01031     return std::max(NumericTraits<base_type>::abs(traits_type::real(z)),
01032         NumericTraits<base_type>::abs(traits_type::imag(z)));
01033   }
01034 
01035   static inline
01036   bool equals(argument_type lhs, argument_type rhs) {
01037     return (traits_type::real(lhs) == traits_type::real(rhs))
01038         && (traits_type::imag(lhs) == traits_type::imag(rhs));
01039   }
01040 
01041   enum { is_complex = true };
01042 
01044   enum {
01045     ops_plus = 2, 
01046     ops_muls = 6  
01047   };
01048 };
01049 
01050 
01060 template<>
01061 struct NumericTraits< std::complex<unsigned long> > {
01062   typedef unsigned long       base_type;
01063   typedef std::complex<unsigned long>   value_type;
01064 #if defined(TVMET_HAVE_LONG_LONG)
01065   typedef std::complex<unsigned long long>  sum_type;
01066 #else
01067   typedef std::complex<unsigned long>   sum_type;
01068 #endif
01069   typedef std::complex<long>      diff_type;
01070   typedef std::complex<float>     float_type;
01071   typedef std::complex<long>      signed_type;
01072 
01073   typedef NumericTraits<value_type>   traits_type;
01074   typedef const value_type&     argument_type;
01075 
01076   static inline
01077   base_type real(argument_type z) { return std::real(z); }
01078 
01079   static inline
01080   base_type imag(argument_type z) { return std::imag(z); }
01081 
01082   static inline
01083   base_type abs(argument_type z) {
01084     base_type x = z.real();
01085     base_type y = z.imag();
01086 
01087     // XXX probably case of overrun; header complex uses scaling
01088     return static_cast<base_type>(NumericTraits<base_type>::sqrt(x * x + y * y));
01089   }
01090 
01091   static /* inline */
01092   value_type sqrt(argument_type z) {
01093     // borrowed and adapted from header complex
01094     base_type x = z.real();
01095     base_type y = z.imag();
01096 
01097     if(x == base_type()) {
01098   base_type t = NumericTraits<base_type>::sqrt(
01099                         NumericTraits<base_type>::abs(y) / 2);
01100   return value_type(t, t);
01101     }
01102     else {
01103       base_type t = NumericTraits<base_type>::sqrt(
01104           2 * (traits_type::abs(z)
01105                 + NumericTraits<base_type>::abs(x)));
01106       return value_type(t / 2, y / t);
01107     }
01108   }
01109 
01110   static inline
01111   base_type norm_1(argument_type z) {
01112     return NumericTraits<base_type>::abs((traits_type::real(z)))
01113          + NumericTraits<base_type>::abs((traits_type::imag(z)));
01114   }
01115 
01116   static inline
01117   base_type norm_2(argument_type z) { return traits_type::abs(z); }
01118 
01119   static inline
01120   base_type norm_inf(argument_type z) {
01121     return std::max(NumericTraits<base_type>::abs(traits_type::real(z)),
01122         NumericTraits<base_type>::abs(traits_type::imag(z)));
01123   }
01124 
01125   static inline
01126   bool equals(argument_type lhs, argument_type rhs) {
01127     return (traits_type::real(lhs) == traits_type::real(rhs))
01128         && (traits_type::imag(lhs) == traits_type::imag(rhs));
01129   }
01130 
01131   enum { is_complex = true };
01132 
01134   enum {
01135     ops_plus = 2, 
01136     ops_muls = 6  
01137   };
01138 };
01139 
01140 
01145 template<>
01146 struct NumericTraits< std::complex<float> > {
01147   typedef float         base_type;
01148   typedef std::complex<float>     value_type;
01149   typedef std::complex<double>      sum_type;
01150   typedef std::complex<float>     diff_type;
01151   typedef std::complex<float>     float_type;
01152   typedef std::complex<float>     signed_type;
01153 
01154   typedef NumericTraits<value_type>   traits_type;
01155   typedef const value_type&     argument_type;
01156 
01157   static inline
01158   base_type real(argument_type z) { return std::real(z); }
01159 
01160   static inline
01161   base_type imag(argument_type z) { return std::imag(z); }
01162 
01163   static inline
01164   value_type conj(argument_type z) { return std::conj(z); }
01165 
01166   static inline
01167   base_type abs(argument_type z) { return std::abs(z); }
01168 
01169   static inline
01170   value_type sqrt(argument_type z) { return std::sqrt(z); }
01171 
01172   static inline
01173   base_type norm_1(argument_type z) {
01174     return NumericTraits<base_type>::abs((traits_type::real(z)))
01175          + NumericTraits<base_type>::abs((traits_type::imag(z)));
01176   }
01177 
01178   static inline
01179   base_type norm_2(argument_type z) { return traits_type::abs(z); }
01180 
01181   static inline
01182   base_type norm_inf(argument_type z) {
01183     return std::max(NumericTraits<base_type>::abs(traits_type::real(z)),
01184               NumericTraits<base_type>::abs(traits_type::imag(z)));
01185   }
01186 
01187  static inline
01188   bool equals(argument_type lhs, argument_type rhs) {
01189     static base_type sqrt_epsilon(
01190       NumericTraits<base_type>::sqrt(
01191         std::numeric_limits<base_type>::epsilon()));
01192 
01193     return traits_type::norm_inf(lhs - rhs) < sqrt_epsilon *
01194       std::max(std::max(traits_type::norm_inf(lhs),
01195       traits_type::norm_inf(rhs)),
01196          std::numeric_limits<base_type>::min());
01197   }
01198 
01199   enum { is_complex = true };
01200 
01202   enum {
01203     ops_plus = 2, 
01204     ops_muls = 6  
01205   };
01206 };
01207 
01208 
01213 template<>
01214 struct NumericTraits< std::complex<double> > {
01215   typedef double        base_type;
01216   typedef std::complex<double>      value_type;
01217 #if defined(TVMET_HAVE_LONG_DOUBLE)
01218   typedef std::complex<long double>     sum_type;
01219 #else
01220   typedef std::complex<double>      sum_type;
01221 #endif
01222   typedef std::complex<double>      diff_type;
01223   typedef std::complex<double>      float_type;
01224   typedef std::complex<double>      signed_type;
01225 
01226   typedef NumericTraits<value_type>   traits_type;
01227   typedef const value_type&     argument_type;
01228 
01229   static inline
01230   base_type real(argument_type z) { return std::real(z); }
01231 
01232   static inline
01233   base_type imag(argument_type z) { return std::imag(z); }
01234 
01235   static inline
01236   value_type conj(argument_type z) { return std::conj(z); }
01237 
01238   static inline
01239   base_type abs(argument_type z) { return std::abs(z); }
01240 
01241   static inline
01242   value_type sqrt(argument_type z) { return std::sqrt(z); }
01243 
01244   static inline
01245   base_type norm_1(argument_type z) {
01246     return NumericTraits<base_type>::abs((traits_type::real(z)))
01247          + NumericTraits<base_type>::abs((traits_type::imag(z)));
01248   }
01249 
01250   static inline
01251   base_type norm_2(argument_type z) { return traits_type::abs(z); }
01252 
01253   static inline
01254   base_type norm_inf(argument_type z) {
01255     return std::max(NumericTraits<base_type>::abs(traits_type::real(z)),
01256               NumericTraits<base_type>::abs(traits_type::imag(z)));
01257   }
01258 
01259  static inline
01260   bool equals(argument_type lhs, argument_type rhs) {
01261     static base_type sqrt_epsilon(
01262       NumericTraits<base_type>::sqrt(
01263         std::numeric_limits<base_type>::epsilon()));
01264 
01265     return traits_type::norm_inf(lhs - rhs) < sqrt_epsilon *
01266       std::max(std::max(traits_type::norm_inf(lhs),
01267       traits_type::norm_inf(rhs)),
01268          std::numeric_limits<base_type>::min());
01269   }
01270 
01271   enum { is_complex = true };
01272 
01274   enum {
01275     ops_plus = 2, 
01276     ops_muls = 6  
01277   };
01278 };
01279 
01280 
01281 #if defined(TVMET_HAVE_LONG_DOUBLE)
01282 
01286 template<>
01287 struct NumericTraits< std::complex<long double> > {
01288   typedef long double       base_type;
01289   typedef std::complex<long double>   value_type;
01290   typedef std::complex<long double>     sum_type;
01291   typedef std::complex<long double>   diff_type;
01292   typedef std::complex<long double>   float_type;
01293   typedef std::complex<long double>   signed_type;
01294 
01295   typedef NumericTraits<value_type>   traits_type;
01296   typedef const value_type&     argument_type;
01297 
01298   static inline
01299   base_type real(argument_type z) { return std::real(z); }
01300 
01301   static inline
01302   base_type imag(argument_type z) { return std::imag(z); }
01303 
01304   static inline
01305   value_type conj(argument_type z) { return std::conj(z); }
01306 
01307   static inline
01308   base_type abs(argument_type z) { return std::abs(z); }
01309 
01310   static inline
01311   value_type sqrt(argument_type z) { return std::sqrt(z); }
01312 
01313   static inline
01314   base_type norm_1(argument_type z) {
01315     return NumericTraits<base_type>::abs((traits_type::real(z)))
01316          + NumericTraits<base_type>::abs((traits_type::imag(z)));
01317   }
01318 
01319   static inline
01320   base_type norm_2(argument_type z) { return traits_type::abs(z); }
01321 
01322   static inline
01323   base_type norm_inf(argument_type z) {
01324     return std::max(NumericTraits<base_type>::abs(traits_type::real(z)),
01325               NumericTraits<base_type>::abs(traits_type::imag(z)));
01326   }
01327 
01328   static inline
01329   bool equals(argument_type lhs, argument_type rhs) {
01330     static base_type sqrt_epsilon(
01331       NumericTraits<base_type>::sqrt(
01332         std::numeric_limits<base_type>::epsilon()));
01333 
01334     return traits_type::norm_inf(lhs - rhs) < sqrt_epsilon *
01335       std::max(std::max(traits_type::norm_inf(lhs),
01336       traits_type::norm_inf(rhs)),
01337          std::numeric_limits<base_type>::min());
01338   }
01339 
01340   enum { is_complex = true };
01341 
01343   enum {
01344     ops_plus = 2, 
01345     ops_muls = 6  
01346   };
01347 };
01348 #endif // defined(TVMET_HAVE_LONG_DOUBLE)
01349 
01350 
01351 #endif // defined(TVMET_HAVE_COMPLEX)
01352 
01353 
01354 } // namespace tvmet
01355 
01356 
01357 #endif //  TVMET_NUMERIC_TRAITS_H
01358 
01359 
01360 // Local Variables:
01361 // mode:C++
01362 // tab-width:8
01363 // End:

Author: