Mercurial > hg > segmenter-vamp-plugin
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 //! @} |