comparison armadillo-2.4.4/include/armadillo_bits/upgrade_val.hpp @ 0:8b6102e2a9b0

Armadillo Library
author maxzanoni76 <max.zanoni@eecs.qmul.ac.uk>
date Wed, 11 Apr 2012 09:27:06 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:8b6102e2a9b0
1 // Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
2 // Copyright (C) 2009-2010 Conrad Sanderson
3 //
4 // This file is part of the Armadillo C++ library.
5 // It is provided without any warranty of fitness
6 // for any purpose. You can redistribute this file
7 // and/or modify it under the terms of the GNU
8 // Lesser General Public License (LGPL) as published
9 // by the Free Software Foundation, either version 3
10 // of the License or (at your option) any later version.
11 // (see http://www.opensource.org/licenses for more info)
12
13
14 //! \addtogroup upgrade_val
15 //! @{
16
17
18
19 //! upgrade_val is used to ensure an operation such as multiplication is possible between two types.
20 //! values are upgraded only where necessary.
21
22 template<typename T1, typename T2>
23 struct upgrade_val
24 {
25 typedef typename promote_type<T1,T2>::result T1_result;
26 typedef typename promote_type<T1,T2>::result T2_result;
27
28 arma_inline
29 static
30 typename promote_type<T1,T2>::result
31 apply(const T1 x)
32 {
33 typedef typename promote_type<T1,T2>::result out_type;
34 return out_type(x);
35 }
36
37 arma_inline
38 static
39 typename promote_type<T1,T2>::result
40 apply(const T2 x)
41 {
42 typedef typename promote_type<T1,T2>::result out_type;
43 return out_type(x);
44 }
45
46 };
47
48
49 // template<>
50 template<typename T>
51 struct upgrade_val<T,T>
52 {
53 typedef T T1_result;
54 typedef T T2_result;
55
56 arma_inline static const T& apply(const T& x) { return x; }
57 };
58
59
60 //! upgrade a type to allow multiplication with a complex type
61 //! e.g. the int in "int * complex<double>" is upgraded to a double
62 // template<>
63 template<typename T, typename T2>
64 struct upgrade_val< std::complex<T>, T2 >
65 {
66 typedef std::complex<T> T1_result;
67 typedef T T2_result;
68
69 arma_inline static const std::complex<T>& apply(const std::complex<T>& x) { return x; }
70 arma_inline static T apply(const T2 x) { return T(x); }
71 };
72
73
74 // template<>
75 template<typename T1, typename T>
76 struct upgrade_val< T1, std::complex<T> >
77 {
78 typedef T T1_result;
79 typedef std::complex<T> T2_result;
80
81 arma_inline static T apply(const T1 x) { return T(x); }
82 arma_inline static const std::complex<T>& apply(const std::complex<T>& x) { return x; }
83 };
84
85
86 //! ensure we don't lose precision when multiplying a complex number with a higher precision real number
87 template<>
88 struct upgrade_val< std::complex<float>, double >
89 {
90 typedef std::complex<double> T1_result;
91 typedef double T2_result;
92
93 arma_inline static const std::complex<double> apply(const std::complex<float>& x) { return std::complex<double>(x); }
94 arma_inline static double apply(const double x) { return x; }
95 };
96
97
98 template<>
99 struct upgrade_val< double, std::complex<float> >
100 {
101 typedef double T1_result;
102 typedef std::complex<float> T2_result;
103
104 arma_inline static double apply(const double x) { return x; }
105 arma_inline static const std::complex<double> apply(const std::complex<float>& x) { return std::complex<double>(x); }
106 };
107
108
109 //! ensure we don't lose precision when multiplying complex numbers with different underlying types
110 template<>
111 struct upgrade_val< std::complex<float>, std::complex<double> >
112 {
113 typedef std::complex<double> T1_result;
114 typedef std::complex<double> T2_result;
115
116 arma_inline static const std::complex<double> apply(const std::complex<float>& x) { return std::complex<double>(x); }
117 arma_inline static const std::complex<double>& apply(const std::complex<double>& x) { return x; }
118 };
119
120
121 template<>
122 struct upgrade_val< std::complex<double>, std::complex<float> >
123 {
124 typedef std::complex<double> T1_result;
125 typedef std::complex<double> T2_result;
126
127 arma_inline static const std::complex<double>& apply(const std::complex<double>& x) { return x; }
128 arma_inline static const std::complex<double> apply(const std::complex<float>& x) { return std::complex<double>(x); }
129 };
130
131
132 //! work around limitations in the complex class (at least as present in gcc 4.1 & 4.3)
133 template<>
134 struct upgrade_val< std::complex<double>, float >
135 {
136 typedef std::complex<double> T1_result;
137 typedef double T2_result;
138
139 arma_inline static const std::complex<double>& apply(const std::complex<double>& x) { return x; }
140 arma_inline static double apply(const float x) { return double(x); }
141 };
142
143
144 template<>
145 struct upgrade_val< float, std::complex<double> >
146 {
147 typedef double T1_result;
148 typedef std::complex<double> T2_result;
149
150 arma_inline static double apply(const float x) { return double(x); }
151 arma_inline static const std::complex<double>& apply(const std::complex<double>& x) { return x; }
152 };
153
154
155
156 //! @}