Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of Eurobot_2012_Secondary by
NumericTraits.h
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 00039 /** 00040 * \class NumericTraits NumericTraits.h "tvmet/NumericTraits.h" 00041 * \brief Traits for integral types for operations. 00042 * 00043 * For each type we have to specialize this traits. 00044 * 00045 * \note Keep in mind that the long types long long and long double doesn't 00046 * have traits. This is due to the sum_type. We can't give a guarantee 00047 * that there is a type of holding the sum. Therefore using this traits 00048 * is only safe if you have long long resp. long double types by 00049 * working on long ints and doubles. Otherwise you will get not expected 00050 * result for some circumstances. Anyway, you can use big integer/float 00051 * libraries and specialize the traits by your own. 00052 * 00053 * \todo The abs function of complex<non_float_type> can have an 00054 * overrun due to numeric computation. Solve it (someone 00055 * using value_type=long here?) 00056 */ 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 00118 /** 00119 * \class NumericTraits<char> NumericTraits.h "tvmet/NumericTraits.h" 00120 * \brief Traits specialized for char. 00121 */ 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 00165 /** Complexity on operations. */ 00166 enum { 00167 ops_plus = 1, /**< Complexity on plus/minus ops. */ 00168 ops_muls = 1 /**< Complexity on multiplications. */ 00169 }; 00170 }; 00171 00172 00173 /** 00174 * \class NumericTraits<unsigned char> NumericTraits.h "tvmet/NumericTraits.h" 00175 * \brief Traits specialized for unsigned char. 00176 * 00177 * \note Normally it doesn't make sense to call <tt>conj</tt> 00178 * for an unsigned type! An unary minus operator 00179 * applied to unsigned type will result unsigned. Therefore 00180 * this function is missing here. 00181 */ 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 00222 /** Complexity on operations. */ 00223 enum { 00224 ops_plus = 1, /**< Complexity on plus/minus ops. */ 00225 ops_muls = 1 /**< Complexity on multiplications. */ 00226 }; 00227 }; 00228 00229 00230 /** 00231 * \class NumericTraits<short int> NumericTraits.h "tvmet/NumericTraits.h" 00232 * \brief Traits specialized for short int. 00233 */ 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 00281 /** Complexity on operations. */ 00282 enum { 00283 ops_plus = 1, /**< Complexity on plus/minus ops. */ 00284 ops_muls = 1 /**< Complexity on multiplications. */ 00285 }; 00286 }; 00287 00288 00289 /** 00290 * \class NumericTraits<short unsigned int> NumericTraits.h "tvmet/NumericTraits.h" 00291 * \brief Traits specialized for short unsigned int. 00292 * 00293 * \note Normally it doesn't make sense to call <tt>conj</tt> 00294 * for an unsigned type! An unary minus operator 00295 * applied to unsigned type will result unsigned. Therefore 00296 * this function is missing here. 00297 */ 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 00342 /** Complexity on operations. */ 00343 enum { 00344 ops_plus = 1, /**< Complexity on plus/minus ops. */ 00345 ops_muls = 1 /**< Complexity on multiplications. */ 00346 }; 00347 }; 00348 00349 00350 /** 00351 * \class NumericTraits<int> NumericTraits.h "tvmet/NumericTraits.h" 00352 * \brief Traits specialized for int. 00353 */ 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 00401 /** Complexity on operations. */ 00402 enum { 00403 ops_plus = 1, /**< Complexity on plus/minus ops. */ 00404 ops_muls = 1 /**< Complexity on multiplications. */ 00405 }; 00406 }; 00407 00408 00409 /** 00410 * \class NumericTraits<unsigned int> NumericTraits.h "tvmet/NumericTraits.h" 00411 * \brief Traits specialized for unsigned int. 00412 * 00413 * \note Normally it doesn't make sense to call <tt>conj</tt> 00414 * for an unsigned type! An unary minus operator 00415 * applied to unsigned type will result unsigned. Therefore 00416 * this function is missing here. 00417 */ 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 00462 /** Complexity on operations. */ 00463 enum { 00464 ops_plus = 1, /**< Complexity on plus/minus ops. */ 00465 ops_muls = 1 /**< Complexity on multiplications. */ 00466 }; 00467 }; 00468 00469 00470 /** 00471 * \class NumericTraits<long> NumericTraits.h "tvmet/NumericTraits.h" 00472 * \brief Traits specialized for long. 00473 */ 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 00521 /** Complexity on operations. */ 00522 enum { 00523 ops_plus = 1, /**< Complexity on plus/minus ops. */ 00524 ops_muls = 1 /**< Complexity on multiplications. */ 00525 }; 00526 }; 00527 00528 00529 /** 00530 * \class NumericTraits<unsigned long> NumericTraits.h "tvmet/NumericTraits.h" 00531 * \brief Traits specialized for unsigned long. 00532 * 00533 * \note Normally it doesn't make sense to call <tt>conj</tt> 00534 * for an unsigned type! An unary minus operator 00535 * applied to unsigned type will result unsigned. Therefore 00536 * this function is missing here. 00537 */ 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 00582 /** Complexity on operations. */ 00583 enum { 00584 ops_plus = 1, /**< Complexity on plus/minus ops. */ 00585 ops_muls = 1 /**< Complexity on multiplications. */ 00586 }; 00587 }; 00588 00589 00590 /** 00591 * \class NumericTraits<float> NumericTraits.h "tvmet/NumericTraits.h" 00592 * \brief Traits specialized for float. 00593 */ 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 00644 /** Complexity on operations. */ 00645 enum { 00646 ops_plus = 1, /**< Complexity on plus/minus ops. */ 00647 ops_muls = 1 /**< Complexity on multiplications. */ 00648 }; 00649 }; 00650 00651 00652 /** 00653 * \class NumericTraits<double> NumericTraits.h "tvmet/NumericTraits.h" 00654 * \brief Traits specialized for double. 00655 */ 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 00710 /** Complexity on operations. */ 00711 enum { 00712 ops_plus = 1, /**< Complexity on plus/minus ops. */ 00713 ops_muls = 1 /**< Complexity on multiplications. */ 00714 }; 00715 }; 00716 00717 00718 #if defined(TVMET_HAVE_LONG_DOUBLE) 00719 /** 00720 * \class NumericTraits<long double> NumericTraits.h "tvmet/NumericTraits.h" 00721 * \brief Traits specialized for long double. 00722 */ 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 00773 /** Complexity on operations. */ 00774 enum { 00775 ops_plus = 1, /**< Complexity on plus/minus ops. */ 00776 ops_muls = 1 /**< Complexity on multiplications. */ 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 00787 /** 00788 * \class NumericTraits< std::complex<int> > NumericTraits.h "tvmet/NumericTraits.h" 00789 * \brief Traits specialized for std::complex<int>. 00790 */ 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 00866 /** Complexity on operations. */ 00867 enum { 00868 ops_plus = 2, /**< Complexity on plus/minus ops. */ 00869 ops_muls = 6 /**< Complexity on multiplications. */ 00870 }; 00871 }; 00872 00873 00874 /** 00875 * \class NumericTraits< std::complex<unsigned int> > NumericTraits.h "tvmet/NumericTraits.h" 00876 * \brief Traits specialized for std::complex<unsigned int>. 00877 * 00878 * \note Normally it doesn't make sense to call <tt>conj</tt> 00879 * for an unsigned type! An unary minus operator 00880 * applied to unsigned type will result unsigned. Therefore 00881 * this function is missing here. 00882 */ 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 00952 /** Complexity on operations. */ 00953 enum { 00954 ops_plus = 2, /**< Complexity on plus/minus ops. */ 00955 ops_muls = 6 /**< Complexity on multiplications. */ 00956 }; 00957 }; 00958 00959 00960 /** 00961 * \class NumericTraits< std::complex<long> > NumericTraits.h "tvmet/NumericTraits.h" 00962 * \brief Traits specialized for std::complex<long>. 00963 */ 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 01043 /** Complexity on operations. */ 01044 enum { 01045 ops_plus = 2, /**< Complexity on plus/minus ops. */ 01046 ops_muls = 6 /**< Complexity on multiplications. */ 01047 }; 01048 }; 01049 01050 01051 /** 01052 * \class NumericTraits< std::complex<unsigned long> > NumericTraits.h "tvmet/NumericTraits.h" 01053 * \brief Traits specialized for std::complex<unsigned long>. 01054 * 01055 * \note Normally it doesn't make sense to call <tt>conj</tt> 01056 * for an unsigned type! An unary minus operator 01057 * applied to unsigned type will result unsigned. Therefore 01058 * this function is missing here. 01059 */ 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 01133 /** Complexity on operations.*/ 01134 enum { 01135 ops_plus = 2, /**< Complexity on plus/minus ops. */ 01136 ops_muls = 6 /**< Complexity on multiplications. */ 01137 }; 01138 }; 01139 01140 01141 /** 01142 * \class NumericTraits< std::complex<float> > NumericTraits.h "tvmet/NumericTraits.h" 01143 * \brief Traits specialized for std::complex<float>. 01144 */ 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 01201 /** Complexity on operations. */ 01202 enum { 01203 ops_plus = 2, /**< Complexity on plus/minus ops. */ 01204 ops_muls = 6 /**< Complexity on multiplications. */ 01205 }; 01206 }; 01207 01208 01209 /** 01210 * \class NumericTraits< std::complex<double> > NumericTraits.h "tvmet/NumericTraits.h" 01211 * \brief Traits specialized for std::complex<double>. 01212 */ 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 01273 /** Complexity on operations. */ 01274 enum { 01275 ops_plus = 2, /**< Complexity on plus/minus ops. */ 01276 ops_muls = 6 /**< Complexity on multiplications. */ 01277 }; 01278 }; 01279 01280 01281 #if defined(TVMET_HAVE_LONG_DOUBLE) 01282 /** 01283 * \class NumericTraits< std::complex<long double> > NumericTraits.h "tvmet/NumericTraits.h" 01284 * \brief Traits specialized for std::complex<double>. 01285 */ 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 01342 /** Complexity on operations. */ 01343 enum { 01344 ops_plus = 2, /**< Complexity on plus/minus ops. */ 01345 ops_muls = 6 /**< Complexity on multiplications. */ 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:
Generated on Tue Jul 12 2022 21:02:13 by
1.7.2
