comparison armadillo-3.900.4/include/armadillo_bits/upgrade_val.hpp @ 49:1ec0e2823891

Switch to using subrepo copies of qm-dsp, nnls-chroma, vamp-plugin-sdk; update Armadillo version; assume build without external BLAS/LAPACK
author Chris Cannam
date Thu, 13 Jun 2013 10:25:24 +0100
parents
children
comparison
equal deleted inserted replaced
48:69251e11a913 49:1ec0e2823891
1 // Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
2 // Copyright (C) 2009-2010 Conrad Sanderson
3 //
4 // This Source Code Form is subject to the terms of the Mozilla Public
5 // License, v. 2.0. If a copy of the MPL was not distributed with this
6 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
7
8
9 //! \addtogroup upgrade_val
10 //! @{
11
12
13
14 //! upgrade_val is used to ensure an operation such as multiplication is possible between two types.
15 //! values are upgraded only where necessary.
16
17 template<typename T1, typename T2>
18 struct upgrade_val
19 {
20 typedef typename promote_type<T1,T2>::result T1_result;
21 typedef typename promote_type<T1,T2>::result T2_result;
22
23 arma_inline
24 static
25 typename promote_type<T1,T2>::result
26 apply(const T1 x)
27 {
28 typedef typename promote_type<T1,T2>::result out_type;
29 return out_type(x);
30 }
31
32 arma_inline
33 static
34 typename promote_type<T1,T2>::result
35 apply(const T2 x)
36 {
37 typedef typename promote_type<T1,T2>::result out_type;
38 return out_type(x);
39 }
40
41 };
42
43
44 // template<>
45 template<typename T>
46 struct upgrade_val<T,T>
47 {
48 typedef T T1_result;
49 typedef T T2_result;
50
51 arma_inline static const T& apply(const T& x) { return x; }
52 };
53
54
55 //! upgrade a type to allow multiplication with a complex type
56 //! e.g. the int in "int * complex<double>" is upgraded to a double
57 // template<>
58 template<typename T, typename T2>
59 struct upgrade_val< std::complex<T>, T2 >
60 {
61 typedef std::complex<T> T1_result;
62 typedef T T2_result;
63
64 arma_inline static const std::complex<T>& apply(const std::complex<T>& x) { return x; }
65 arma_inline static T apply(const T2 x) { return T(x); }
66 };
67
68
69 // template<>
70 template<typename T1, typename T>
71 struct upgrade_val< T1, std::complex<T> >
72 {
73 typedef T T1_result;
74 typedef std::complex<T> T2_result;
75
76 arma_inline static T apply(const T1 x) { return T(x); }
77 arma_inline static const std::complex<T>& apply(const std::complex<T>& x) { return x; }
78 };
79
80
81 //! ensure we don't lose precision when multiplying a complex number with a higher precision real number
82 template<>
83 struct upgrade_val< std::complex<float>, double >
84 {
85 typedef std::complex<double> T1_result;
86 typedef double T2_result;
87
88 arma_inline static const std::complex<double> apply(const std::complex<float>& x) { return std::complex<double>(x); }
89 arma_inline static double apply(const double x) { return x; }
90 };
91
92
93 template<>
94 struct upgrade_val< double, std::complex<float> >
95 {
96 typedef double T1_result;
97 typedef std::complex<float> T2_result;
98
99 arma_inline static double apply(const double x) { return x; }
100 arma_inline static const std::complex<double> apply(const std::complex<float>& x) { return std::complex<double>(x); }
101 };
102
103
104 //! ensure we don't lose precision when multiplying complex numbers with different underlying types
105 template<>
106 struct upgrade_val< std::complex<float>, std::complex<double> >
107 {
108 typedef std::complex<double> T1_result;
109 typedef std::complex<double> T2_result;
110
111 arma_inline static const std::complex<double> apply(const std::complex<float>& x) { return std::complex<double>(x); }
112 arma_inline static const std::complex<double>& apply(const std::complex<double>& x) { return x; }
113 };
114
115
116 template<>
117 struct upgrade_val< std::complex<double>, std::complex<float> >
118 {
119 typedef std::complex<double> T1_result;
120 typedef std::complex<double> T2_result;
121
122 arma_inline static const std::complex<double>& apply(const std::complex<double>& x) { return x; }
123 arma_inline static const std::complex<double> apply(const std::complex<float>& x) { return std::complex<double>(x); }
124 };
125
126
127 //! work around limitations in the complex class (at least as present in gcc 4.1 & 4.3)
128 template<>
129 struct upgrade_val< std::complex<double>, float >
130 {
131 typedef std::complex<double> T1_result;
132 typedef double T2_result;
133
134 arma_inline static const std::complex<double>& apply(const std::complex<double>& x) { return x; }
135 arma_inline static double apply(const float x) { return double(x); }
136 };
137
138
139 template<>
140 struct upgrade_val< float, std::complex<double> >
141 {
142 typedef double T1_result;
143 typedef std::complex<double> T2_result;
144
145 arma_inline static double apply(const float x) { return double(x); }
146 arma_inline static const std::complex<double>& apply(const std::complex<double>& x) { return x; }
147 };
148
149
150
151 //! @}