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