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   }