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 
41 namespace 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
auto exp(const framed_multi< Scalar_T, LO, HI, Tune_P > &val) -> const framed_multi< Scalar_T, LO, HI, Tune_P >
Exponential of multivector.
static auto isNaN_or_isInf(const Scalar_T &val) -> bool
Smart isnan or isinf.
Definition: scalar.h:103
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 to_int(const Scalar_T &val) -> int
Cast to int.
Definition: scalar.h:126
static auto fmod(const Scalar_T &lhs, const Scalar_T &rhs) -> Scalar_T
Modulo function for scalar.
Definition: scalar.h:154
static auto pow(const Scalar_T &val, int n) -> Scalar_T
Integer power.
Definition: scalar.h:203
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 sinh(const Multivector< Scalar_T, LO, HI, Tune_P > &val) -> const Multivector< Scalar_T, LO, HI, Tune_P >
Hyperbolic sine of multivector.
static auto ln_2() -> Scalar_T
log(2)
Definition: scalar.h:196
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 tanh(const Multivector< Scalar_T, LO, HI, Tune_P > &val) -> const Multivector< Scalar_T, LO, HI, Tune_P >
Hyperbolic tangent of multivector.
auto abs(const Multivector< Scalar_T, LO, HI, Tune_P > &val) -> Scalar_T
Absolute value == sqrt(norm)
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.
static auto to_double(const Scalar_T &val) -> double
Cast to double.
Definition: scalar.h:133
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 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.
static auto pi() -> Scalar_T
Pi.
Definition: scalar.h:189
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 cosh(const Multivector< Scalar_T, LO, HI, Tune_P > &val) -> const Multivector< Scalar_T, LO, HI, Tune_P >
Hyperbolic cosine of multivector.
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
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.