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 }
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
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
00818 return static_cast<base_type>(NumericTraits<base_type>::sqrt(x * x + y * y));
00819 }
00820
00821 static
00822 value_type sqrt(argument_type z) {
00823
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
00907 return static_cast<base_type>(NumericTraits<base_type>::sqrt(x * x + y * y));
00908 }
00909
00910 static
00911 value_type sqrt(argument_type z) {
00912
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
00995 return static_cast<base_type>(NumericTraits<base_type>::sqrt(x * x + y * y));
00996 }
00997
00998 static
00999 value_type sqrt(argument_type z) {
01000
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
01088 return static_cast<base_type>(NumericTraits<base_type>::sqrt(x * x + y * y));
01089 }
01090
01091 static
01092 value_type sqrt(argument_type z) {
01093
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 }
01355
01356
01357 #endif // TVMET_NUMERIC_TRAITS_H
01358
01359
01360
01361
01362
01363