00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
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 }