glucat 0.12.0
qd.h
Go to the documentation of this file.
1#ifndef _GLUCAT_QD_H
2#define _GLUCAT_QD_H
3/***************************************************************************
4 GluCat : Generic library of universal Clifford algebra templates
5 qd.h : Define functions for dd_real and qd_real as scalar_t
6 -------------------
7 begin : 2010-03-23
8 copyright : (C) 2010-2016 by Paul C. Leopardi
9 ***************************************************************************
10
11 This library is free software: you can redistribute it and/or modify
12 it under the terms of the GNU Lesser General Public License as published
13 by the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
15
16 This library is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU Lesser General Public License for more details.
20
21 You should have received a copy of the GNU Lesser General Public License
22 along with this library. If not, see <http://www.gnu.org/licenses/>.
23
24 ***************************************************************************
25 This library is based on a prototype written by Arvind Raja and was
26 licensed under the LGPL with permission of the author. See Arvind Raja,
27 "Object-oriented implementations of Clifford algebras in C++: a prototype",
28 in Ablamowicz, Lounesto and Parra (eds.)
29 "Clifford algebras with numeric and symbolic computations, Birkhauser, 1996."
30 ***************************************************************************
31 See also Arvind Raja's original header comments and references in glucat.h
32 ***************************************************************************/
33
34#include "glucat/global.h"
35#include "glucat/scalar.h"
36
37#if defined(_GLUCAT_USE_QD)
38# include <qd/qd_real.h>
39#endif
40
41namespace glucat
42{
44 // Reference: [AA], 2.4, p. 30-31
45
46#if defined(_GLUCAT_USE_QD) && defined(QD_API)
47
49# define _GLUCAT_QD_F(_T, _F) \
50 template<> \
51 inline \
52 auto \
53 numeric_traits<_T>:: \
54 _F(const _T& val) -> _T \
55 { return ::_F(val); }
56
58 template<>
59 inline
60 auto
62 isNaN(const dd_real& val) -> bool
63 { return val.isnan(); }
64
66 template<>
67 inline
68 auto
70 isInf(const dd_real& val) -> bool
71 { return val.isinf(); }
72
74 template<>
75 inline
76 auto
78 isNaN_or_isInf(const dd_real& val) -> bool
79 { return val.isnan() || val.isinf(); }
80
82 template<>
83 inline
84 auto
86 to_int(const dd_real& val) -> int
87 { return ::to_int(val); }
88
90 template<>
91 inline
92 auto
94 to_double(const dd_real& val) -> double
95 { return ::to_double(val); }
96
98 template<>
99 inline
100 auto
102 fmod(const dd_real& lhs, const dd_real& rhs) -> dd_real
103 { return ::fmod(lhs, rhs); }
104
106 template<>
107 inline
108 auto
110 pow(const dd_real& val, int n) -> dd_real
111 {
112 if (val == dd_real(0))
113 {
114 return
115 (n < 0)
116 ? NaN()
117 : (n == 0)
118 ? dd_real(1)
119 : dd_real(0);
120 }
121 auto result = dd_real(1);
122 auto power =
123 (n < 0)
124 ? dd_real(1)/val
125 : val;
126 for (auto
127 k = std::abs(n);
128 k != 0;
129 k /= 2)
130 {
131 if (k % 2)
132 result *= power;
133 power *= power;
134 }
135 return result;
136 }
137
139 template<>
140 inline
141 auto
143 pi() -> dd_real
144 { return dd_real::_pi; }
145
147 template<>
148 inline
149 auto
151 ln_2() -> dd_real
152 { return dd_real::_log2; }
153
155 _GLUCAT_QD_F(dd_real, exp)
156
157
158 _GLUCAT_QD_F(dd_real, log)
159
160
161 _GLUCAT_QD_F(dd_real, cos)
162
163
164 _GLUCAT_QD_F(dd_real, acos)
165
166
167 _GLUCAT_QD_F(dd_real, cosh)
168
169
170 _GLUCAT_QD_F(dd_real, sin)
171
172
173 _GLUCAT_QD_F(dd_real, asin)
174
175
176 _GLUCAT_QD_F(dd_real, sinh)
177
178
179 _GLUCAT_QD_F(dd_real, tan)
180
181
182 _GLUCAT_QD_F(dd_real, atan)
183
184
185 _GLUCAT_QD_F(dd_real, tanh)
186
187
188 template<>
189 inline
190 auto
192 isNaN(const qd_real& val) -> bool
193 { return val.isnan(); }
194
196 template<>
197 inline
198 auto
200 isInf(const qd_real& val) -> bool
201 { return val.isinf(); }
202
204 template<>
205 inline
206 auto
208 isNaN_or_isInf(const qd_real& val) -> bool
209 { return val.isnan() || val.isinf(); }
210
212 template<>
213 inline
214 auto
216 to_int(const qd_real& val) -> int
217 { return ::to_int(val); }
218
220 template<>
221 inline
222 auto
224 to_double(const qd_real& val) -> double
225 { return ::to_double(val); }
226
228 template<>
229 inline
230 auto
232 fmod(const qd_real& lhs, const qd_real& rhs) -> qd_real
233 { return ::fmod(lhs, rhs); }
234
236 template<>
237 inline
238 auto
240 pow(const qd_real& val, int n) -> qd_real
241 {
242 if (val == qd_real(0))
243 {
244 return
245 (n < 0)
246 ? NaN()
247 : (n == 0)
248 ? qd_real(1)
249 : qd_real(0);
250 }
251 auto result = qd_real(1);
252 auto power =
253 (n < 0)
254 ? qd_real(1)/val
255 : val;
256 for (auto
257 k = std::abs(n);
258 k != 0;
259 k /= 2)
260 {
261 if (k % 2)
262 result *= power;
263 power *= power;
264 }
265 return result;
266 }
267
269 template<>
270 inline
271 auto
273 pi() -> qd_real
274 { return qd_real::_pi; }
275
277 template<>
278 inline
279 auto
281 ln_2() -> qd_real
282 { return qd_real::_log2; }
283
285 _GLUCAT_QD_F(qd_real, exp)
286
287
288 _GLUCAT_QD_F(qd_real, log)
289
290
291 _GLUCAT_QD_F(qd_real, cos)
292
293
294 _GLUCAT_QD_F(qd_real, acos)
295
296
297 _GLUCAT_QD_F(qd_real, cosh)
298
299
300 _GLUCAT_QD_F(qd_real, sin)
301
302
303 _GLUCAT_QD_F(qd_real, asin)
304
305
306 _GLUCAT_QD_F(qd_real, sinh)
307
308
309 _GLUCAT_QD_F(qd_real, tan)
310
311
312 _GLUCAT_QD_F(qd_real, atan)
313
314
315 _GLUCAT_QD_F(qd_real, tanh)
316
317#endif // !defined(_GLUCAT_USE_QD) || !defined(QD_API)
318
319} // namespace glucat
320
321#endif // _GLUCAT_QD_H
static auto isNaN(const Scalar_T &val, bool_to_type< false >) -> bool
Smart isnan specialised for Scalar_T without quiet NaN.
Definition: scalar.h:68
static auto fmod(const Scalar_T &lhs, const Scalar_T &rhs) -> Scalar_T
Modulo function for scalar.
Definition: scalar.h:154
static auto isNaN_or_isInf(const Scalar_T &val) -> bool
Smart isnan or isinf.
Definition: scalar.h:103
static auto ln_2() -> Scalar_T
log(2)
Definition: scalar.h:196
static auto to_double(const Scalar_T &val) -> double
Cast to double.
Definition: scalar.h:133
static auto isInf(const Scalar_T &val, bool_to_type< false >) -> bool
Smart isinf specialised for Scalar_T without infinity.
Definition: scalar.h:54
static auto pi() -> Scalar_T
Pi.
Definition: scalar.h:189
static auto pow(const Scalar_T &val, int n) -> Scalar_T
Integer power.
Definition: scalar.h:203
static auto to_int(const Scalar_T &val) -> int
Cast to int.
Definition: scalar.h:126
auto exp(const framed_multi< Scalar_T, LO, HI, Tune_P > &val) -> const framed_multi< Scalar_T, LO, HI, Tune_P >
Exponential of multivector.
auto cosh(const Multivector< Scalar_T, LO, HI, Tune_P > &val) -> const Multivector< Scalar_T, LO, HI, Tune_P >
Hyperbolic cosine of multivector.
auto tanh(const Multivector< Scalar_T, LO, HI, Tune_P > &val) -> const Multivector< Scalar_T, LO, HI, Tune_P >
Hyperbolic tangent of multivector.
auto tan(const Multivector< Scalar_T, LO, HI, Tune_P > &val, const Multivector< Scalar_T, LO, HI, Tune_P > &i, const bool prechecked=false) -> const Multivector< Scalar_T, LO, HI, Tune_P >
Tangent of multivector with specified complexifier.
auto sinh(const Multivector< Scalar_T, LO, HI, Tune_P > &val) -> const Multivector< Scalar_T, LO, HI, Tune_P >
Hyperbolic sine of multivector.
auto sin(const Multivector< Scalar_T, LO, HI, Tune_P > &val, const Multivector< Scalar_T, LO, HI, Tune_P > &i, const bool prechecked=false) -> const Multivector< Scalar_T, LO, HI, Tune_P >
Sine of multivector with specified complexifier.
auto atan(const Multivector< Scalar_T, LO, HI, Tune_P > &val, const Multivector< Scalar_T, LO, HI, Tune_P > &i, const bool prechecked=false) -> const Multivector< Scalar_T, LO, HI, Tune_P >
Inverse tangent of multivector with specified complexifier.
auto cos(const Multivector< Scalar_T, LO, HI, Tune_P > &val, const Multivector< Scalar_T, LO, HI, Tune_P > &i, const bool prechecked=false) -> const Multivector< Scalar_T, LO, HI, Tune_P >
Cosine of multivector with specified complexifier.
auto log(const Multivector< Scalar_T, LO, HI, Tune_P > &val, const Multivector< Scalar_T, LO, HI, Tune_P > &i, const bool prechecked=false) -> const Multivector< Scalar_T, LO, HI, Tune_P >
Natural logarithm of multivector with specified complexifier.
auto asin(const Multivector< Scalar_T, LO, HI, Tune_P > &val, const Multivector< Scalar_T, LO, HI, Tune_P > &i, const bool prechecked=false) -> const Multivector< Scalar_T, LO, HI, Tune_P >
Inverse sine of multivector with specified complexifier.
auto acos(const Multivector< Scalar_T, LO, HI, Tune_P > &val, const Multivector< Scalar_T, LO, HI, Tune_P > &i, const bool prechecked=false) -> const Multivector< Scalar_T, LO, HI, Tune_P >
Inverse cosine of multivector with specified complexifier.