Mercurial > hg > segmenter-vamp-plugin
comparison armadillo-2.4.4/include/armadillo_bits/eop_aux.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) 2010-2011 NICTA (www.nicta.com.au) | |
2 // Copyright (C) 2010-2011 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 eop_aux | |
15 //! @{ | |
16 | |
17 | |
18 | |
19 template<typename eT> | |
20 struct eop_aux_randu | |
21 { | |
22 arma_inline | |
23 operator eT () | |
24 { | |
25 return eT(std::rand()) / eT(RAND_MAX); | |
26 } | |
27 }; | |
28 | |
29 | |
30 | |
31 template<typename T> | |
32 struct eop_aux_randu< std::complex<T> > | |
33 { | |
34 arma_inline | |
35 operator std::complex<T> () | |
36 { | |
37 return std::complex<T>( T(eop_aux_randu<T>()), T(eop_aux_randu<T>()) ); | |
38 } | |
39 }; | |
40 | |
41 | |
42 | |
43 template<typename eT> | |
44 struct eop_aux_randn | |
45 { | |
46 // // rudimentary method, based on the central limit theorem | |
47 // // http://en.wikipedia.org/wiki/Central_limit_theorem | |
48 // inline | |
49 // operator eT () const | |
50 // { | |
51 // const uword N = 12; // N must be >= 12 and an even number | |
52 // const uword N2 = N/2; | |
53 // | |
54 // eT acc = eT(0); | |
55 // | |
56 // for(uword i=0; i<N2; ++i) | |
57 // { | |
58 // const eT tmp1 = eT(std::rand()) / eT(RAND_MAX); | |
59 // const eT tmp2 = eT(std::rand()) / eT(RAND_MAX); | |
60 // acc += tmp1+tmp2; | |
61 // } | |
62 // | |
63 // return acc - eT(N2); | |
64 // } | |
65 | |
66 | |
67 // polar form of the Box-Muller transformation | |
68 // http://en.wikipedia.org/wiki/Box-Muller_transformation | |
69 // http://en.wikipedia.org/wiki/Marsaglia_polar_method | |
70 inline | |
71 operator eT () const | |
72 { | |
73 // make sure we are internally using at least floats | |
74 typedef typename promote_type<eT,float>::result eTp; | |
75 | |
76 eTp tmp1; | |
77 eTp tmp2; | |
78 eTp w; | |
79 | |
80 do | |
81 { | |
82 tmp1 = eTp(2) * eTp(std::rand()) / eTp(RAND_MAX) - eTp(1); | |
83 tmp2 = eTp(2) * eTp(std::rand()) / eTp(RAND_MAX) - eTp(1); | |
84 w = tmp1*tmp1 + tmp2*tmp2; | |
85 } | |
86 while ( w >= eTp(1) ); | |
87 | |
88 return eT( tmp1 * std::sqrt( (eTp(-2) * std::log(w)) / w) ); | |
89 } | |
90 | |
91 | |
92 // other methods: | |
93 // http://en.wikipedia.org/wiki/Ziggurat_algorithm | |
94 // | |
95 // Marsaglia and Tsang Ziggurat technique to transform from a uniform to a normal distribution. | |
96 // G. Marsaglia, W.W. Tsang. | |
97 // "Ziggurat method for generating random variables", | |
98 // J. Statistical Software, vol 5, 2000. | |
99 // http://www.jstatsoft.org/v05/i08/ | |
100 }; | |
101 | |
102 | |
103 | |
104 template<typename T> | |
105 struct eop_aux_randn< std::complex<T> > | |
106 { | |
107 arma_inline | |
108 operator std::complex<T> () const | |
109 { | |
110 return std::complex<T>( T(eop_aux_randn<T>()), T(eop_aux_randn<T>()) ); | |
111 } | |
112 | |
113 }; | |
114 | |
115 | |
116 //! use of the SFINAE approach to work around compiler limitations | |
117 //! http://en.wikipedia.org/wiki/SFINAE | |
118 | |
119 class eop_aux | |
120 { | |
121 public: | |
122 | |
123 template<typename eT> arma_inline static typename arma_integral_only<eT>::result acos (const eT x) { return eT( std::acos(double(x)) ); } | |
124 template<typename eT> arma_inline static typename arma_integral_only<eT>::result asin (const eT x) { return eT( std::asin(double(x)) ); } | |
125 template<typename eT> arma_inline static typename arma_integral_only<eT>::result atan (const eT x) { return eT( std::atan(double(x)) ); } | |
126 | |
127 template<typename eT> arma_inline static typename arma_float_only<eT>::result acos (const eT x) { return std::acos(x); } | |
128 template<typename eT> arma_inline static typename arma_float_only<eT>::result asin (const eT x) { return std::asin(x); } | |
129 template<typename eT> arma_inline static typename arma_float_only<eT>::result atan (const eT x) { return std::atan(x); } | |
130 | |
131 template<typename eT> arma_inline static typename arma_cx_only<eT>::result acos (const eT x) { return arma_acos(x); } | |
132 template<typename eT> arma_inline static typename arma_cx_only<eT>::result asin (const eT x) { return arma_asin(x); } | |
133 template<typename eT> arma_inline static typename arma_cx_only<eT>::result atan (const eT x) { return arma_atan(x); } | |
134 | |
135 template<typename eT> arma_inline static typename arma_integral_only<eT>::result acosh (const eT x) { return eT( arma_acosh(double(x)) ); } | |
136 template<typename eT> arma_inline static typename arma_integral_only<eT>::result asinh (const eT x) { return eT( arma_asinh(double(x)) ); } | |
137 template<typename eT> arma_inline static typename arma_integral_only<eT>::result atanh (const eT x) { return eT( arma_atanh(double(x)) ); } | |
138 | |
139 template<typename eT> arma_inline static typename arma_float_or_cx_only<eT>::result acosh (const eT x) { return arma_acosh(x); } | |
140 template<typename eT> arma_inline static typename arma_float_or_cx_only<eT>::result asinh (const eT x) { return arma_asinh(x); } | |
141 template<typename eT> arma_inline static typename arma_float_or_cx_only<eT>::result atanh (const eT x) { return arma_atanh(x); } | |
142 | |
143 template<typename eT> arma_inline static typename arma_not_cx<eT>::result conj(const eT x) { return x; } | |
144 template<typename T> arma_inline static std::complex<T> conj(const std::complex<T>& x) { return std::conj(x); } | |
145 | |
146 template<typename eT> arma_inline static typename arma_integral_only<eT>::result sqrt (const eT x) { return eT( std::sqrt (double(x)) ); } | |
147 template<typename eT> arma_inline static typename arma_integral_only<eT>::result log10 (const eT x) { return eT( std::log10(double(x)) ); } | |
148 template<typename eT> arma_inline static typename arma_integral_only<eT>::result log (const eT x) { return eT( std::log (double(x)) ); } | |
149 template<typename eT> arma_inline static typename arma_integral_only<eT>::result exp (const eT x) { return eT( std::exp (double(x)) ); } | |
150 template<typename eT> arma_inline static typename arma_integral_only<eT>::result cos (const eT x) { return eT( std::cos (double(x)) ); } | |
151 template<typename eT> arma_inline static typename arma_integral_only<eT>::result sin (const eT x) { return eT( std::sin (double(x)) ); } | |
152 template<typename eT> arma_inline static typename arma_integral_only<eT>::result tan (const eT x) { return eT( std::tan (double(x)) ); } | |
153 template<typename eT> arma_inline static typename arma_integral_only<eT>::result cosh (const eT x) { return eT( std::cosh (double(x)) ); } | |
154 template<typename eT> arma_inline static typename arma_integral_only<eT>::result sinh (const eT x) { return eT( std::sinh (double(x)) ); } | |
155 template<typename eT> arma_inline static typename arma_integral_only<eT>::result tanh (const eT x) { return eT( std::tanh (double(x)) ); } | |
156 | |
157 template<typename eT> arma_inline static typename arma_float_or_cx_only<eT>::result sqrt (const eT x) { return std::sqrt (x); } | |
158 template<typename eT> arma_inline static typename arma_float_or_cx_only<eT>::result log10 (const eT x) { return std::log10(x); } | |
159 template<typename eT> arma_inline static typename arma_float_or_cx_only<eT>::result log (const eT x) { return std::log (x); } | |
160 template<typename eT> arma_inline static typename arma_float_or_cx_only<eT>::result exp (const eT x) { return std::exp (x); } | |
161 template<typename eT> arma_inline static typename arma_float_or_cx_only<eT>::result cos (const eT x) { return std::cos (x); } | |
162 template<typename eT> arma_inline static typename arma_float_or_cx_only<eT>::result sin (const eT x) { return std::sin (x); } | |
163 template<typename eT> arma_inline static typename arma_float_or_cx_only<eT>::result tan (const eT x) { return std::tan (x); } | |
164 template<typename eT> arma_inline static typename arma_float_or_cx_only<eT>::result cosh (const eT x) { return std::cosh (x); } | |
165 template<typename eT> arma_inline static typename arma_float_or_cx_only<eT>::result sinh (const eT x) { return std::sinh (x); } | |
166 template<typename eT> arma_inline static typename arma_float_or_cx_only<eT>::result tanh (const eT x) { return std::tanh (x); } | |
167 | |
168 template<typename eT> arma_inline static typename arma_unsigned_integral_only<eT>::result neg (const eT x) { return x; } | |
169 template<typename eT> arma_inline static typename arma_signed_only<eT>::result neg (const eT x) { return -x; } | |
170 | |
171 template<typename eT> arma_inline static typename arma_integral_only<eT>::result floor(const eT x) { return x; } | |
172 template<typename eT> arma_inline static typename arma_float_only<eT>::result floor(const eT x) { return std::floor(x); } | |
173 template<typename eT> arma_inline static typename arma_cx_only<eT>::result floor(const eT& x) { return eT( std::floor(x.real()), std::floor(x.imag()) ); } | |
174 | |
175 template<typename eT> arma_inline static typename arma_integral_only<eT>::result ceil(const eT x) { return x; } | |
176 template<typename eT> arma_inline static typename arma_float_only<eT>::result ceil(const eT x) { return std::ceil(x); } | |
177 template<typename eT> arma_inline static typename arma_cx_only<eT>::result ceil(const eT& x) { return eT( std::ceil(x.real()), std::ceil(x.imag()) ); } | |
178 | |
179 template<typename eT> | |
180 arma_inline | |
181 static | |
182 typename arma_integral_only<eT>::result | |
183 log2 (const eT x) | |
184 { | |
185 return eT( std::log(double(x))/ double(0.69314718055994530942) ); | |
186 } | |
187 | |
188 | |
189 template<typename eT> | |
190 arma_inline | |
191 static | |
192 typename arma_float_or_cx_only<eT>::result | |
193 log2 (const eT x) | |
194 { | |
195 typedef typename get_pod_type<eT>::result T; | |
196 return std::log(x) / T(0.69314718055994530942); | |
197 } | |
198 | |
199 | |
200 template<typename eT> | |
201 arma_inline | |
202 static | |
203 typename arma_integral_only<eT>::result | |
204 exp10 (const eT x) | |
205 { | |
206 return eT( std::pow(double(10), double(x)) ); | |
207 } | |
208 | |
209 | |
210 template<typename eT> | |
211 arma_inline | |
212 static | |
213 typename | |
214 arma_float_or_cx_only<eT>::result | |
215 exp10 (const eT x) | |
216 { | |
217 typedef typename get_pod_type<eT>::result T; | |
218 return std::pow( T(10), x); | |
219 } | |
220 | |
221 | |
222 template<typename eT> | |
223 arma_inline | |
224 static | |
225 typename arma_integral_only<eT>::result | |
226 exp2 (const eT x) | |
227 { | |
228 return eT( std::pow(double(2), double(x)) ); | |
229 } | |
230 | |
231 | |
232 template<typename eT> | |
233 arma_inline | |
234 static | |
235 typename arma_float_or_cx_only<eT>::result | |
236 exp2 (const eT x) | |
237 { | |
238 typedef typename get_pod_type<eT>::result T; | |
239 return std::pow( T(2), x); | |
240 } | |
241 | |
242 | |
243 template<typename T1, typename T2> | |
244 arma_inline | |
245 static | |
246 typename arma_float_or_cx_only<T1>::result | |
247 pow(const T1 base, const T2 exponent) | |
248 { | |
249 return std::pow(base, exponent); | |
250 } | |
251 | |
252 | |
253 | |
254 template<typename T1, typename T2> | |
255 arma_inline | |
256 static | |
257 typename arma_integral_only<T1>::result | |
258 pow(const T1 base, const T2 exponent) | |
259 { | |
260 return T1( std::pow( double(base), double(exponent) ) ); | |
261 } | |
262 | |
263 | |
264 | |
265 template<typename eT> | |
266 arma_inline | |
267 static | |
268 typename arma_integral_only<eT>::result | |
269 direct_eps(const eT) | |
270 { | |
271 return eT(0); | |
272 } | |
273 | |
274 | |
275 | |
276 template<typename eT> | |
277 inline | |
278 static | |
279 typename arma_float_only<eT>::result | |
280 direct_eps(const eT x) | |
281 { | |
282 //arma_extra_debug_sigprint(); | |
283 | |
284 // acording to IEEE Standard for Floating-Point Arithmetic (IEEE 754) | |
285 // the mantissa length for double is 53 bits = std::numeric_limits<double>::digits | |
286 // the mantissa length for float is 24 bits = std::numeric_limits<float >::digits | |
287 | |
288 //return std::pow( std::numeric_limits<eT>::radix, (std::floor(std::log10(std::abs(x))/std::log10(std::numeric_limits<eT>::radix))-(std::numeric_limits<eT>::digits-1)) ); | |
289 | |
290 const eT radix_eT = eT(std::numeric_limits<eT>::radix); | |
291 const eT digits_m1_eT = eT(std::numeric_limits<eT>::digits - 1); | |
292 | |
293 // return std::pow( radix_eT, eT(std::floor(std::log10(std::abs(x))/std::log10(radix_eT)) - digits_m1_eT) ); | |
294 return eop_aux::pow( radix_eT, eT(std::floor(std::log10(std::abs(x))/std::log10(radix_eT)) - digits_m1_eT) ); | |
295 } | |
296 | |
297 | |
298 | |
299 template<typename T> | |
300 inline | |
301 static | |
302 typename arma_float_only<T>::result | |
303 direct_eps(const std::complex<T> x) | |
304 { | |
305 //arma_extra_debug_sigprint(); | |
306 | |
307 //return std::pow( std::numeric_limits<T>::radix, (std::floor(std::log10(std::abs(x))/std::log10(std::numeric_limits<T>::radix))-(std::numeric_limits<T>::digits-1)) ); | |
308 | |
309 const T radix_T = T(std::numeric_limits<T>::radix); | |
310 const T digits_m1_T = T(std::numeric_limits<T>::digits - 1); | |
311 | |
312 return std::pow( radix_T, T(std::floor(std::log10(std::abs(x))/std::log10(radix_T)) - digits_m1_T) ); | |
313 } | |
314 | |
315 | |
316 | |
317 //! work around a bug in GCC 4.4 | |
318 template<typename eT> arma_inline static | |
319 typename arma_unsigned_integral_only<eT>::result arma_abs(const eT x) { return x; } | |
320 | |
321 template<typename eT> arma_inline static | |
322 typename arma_signed_integral_only<eT>::result arma_abs(const eT x) { return std::abs(x); } | |
323 | |
324 template<typename eT> arma_inline static | |
325 typename arma_float_only<eT>::result arma_abs(const eT x) { return std::abs(x); } | |
326 | |
327 template<typename T> arma_inline static | |
328 typename arma_float_only<T>::result arma_abs(const std::complex<T> x) { return std::abs(x); } | |
329 | |
330 }; | |
331 | |
332 | |
333 | |
334 //! @} | |
335 |