libMesh
float128_shims.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2019 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 #ifndef LIBMESH_FLOAT128_SHIMS_H
19 #define LIBMESH_FLOAT128_SHIMS_H
20 
21 # include <boost/multiprecision/float128.hpp>
22 
23 // Boost doesn't add float128 overloads to namespace std. But, we
24 // expect to be able to explicitly specify std::foo(Real) in trailing
25 // return types, where a using-declaration + ADL isn't an option. So
26 // we add overloads ourselves.
27 namespace std
28 {
29 #define LIBMESH_FLOAT128_UNARY(funcname) \
30 inline boost::multiprecision::float128 funcname \
31  (const boost::multiprecision::float128 in) \
32 { \
33  return boost::multiprecision::funcname(in); \
34 }
35 
36 #define LIBMESH_FLOAT128_MATH_BOOL(funcname) \
37 inline bool funcname \
38  (const boost::multiprecision::float128 in) \
39 { \
40  return boost::math::funcname(in); \
41 }
42 
43 #define LIBMESH_FLOAT128_BINARY(funcname) \
44 inline boost::multiprecision::float128 funcname \
45  (const boost::multiprecision::float128 in1, \
46  const boost::multiprecision::float128 in2) \
47 { \
48  return boost::multiprecision::funcname(in1, in2); \
49 }
50 
68 // LIBMESH_FLOAT128_UNARY(norm)
69 
70 inline boost::multiprecision::float128 norm
71  (const boost::multiprecision::float128 in)
72 {
73  return in * in;
74 }
75 
76 inline boost::multiprecision::float128 real
77  (const boost::multiprecision::float128 in)
78 {
79  return in;
80 }
81 
82 inline boost::multiprecision::float128 imag
83  (const boost::multiprecision::float128 /*in*/)
84 {
85  return 0;
86 }
87 
88 template <>
89 struct plus<boost::multiprecision::float128>
90 {
91  boost::multiprecision::float128 operator ()
92  (const boost::multiprecision::float128 a,
93  const boost::multiprecision::float128 b)
94  {
95  return a + b;
96  }
97 };
98 
99 template <>
100 struct multiplies<boost::multiprecision::float128>
101 {
102  boost::multiprecision::float128 operator ()
103  (const boost::multiprecision::float128 a,
104  const boost::multiprecision::float128 b)
105  {
106  return a * b;
107  }
108 };
109 
110 
113 
114 // Shimming modf by hand since Boost didn't add a shim until 1.62 and
115 // I'd like to still support systems with older Boost in /usr/include/
116 inline boost::multiprecision::float128 modf
117  (const boost::multiprecision::float128 in,
118  boost::multiprecision::float128 * intpart)
119 {
120 #ifdef BOOST_MP_USE_QUAD
121  return __modfq(in.backend().value(), &intpart->backend().value());
122 #elif defined(BOOST_MP_USE_FLOAT128)
123  return modfq(in.backend().value(), &intpart->backend().value());
124 #endif
125 }
126 
129 // LIBMESH_FLOAT128_BINARY(max)
130 // LIBMESH_FLOAT128_BINARY(min)
132 
133 inline boost::multiprecision::float128 pow
134  (const boost::multiprecision::float128 in1,
135  const int in2)
136 {
137  return boost::multiprecision::pow(in1, in2);
138 }
139 
140 // Boost leaves a lot of C++11 math undefined??
141 
142 // LIBMESH_FLOAT128_UNARY(exp2)
143 // LIBMESH_FLOAT128_UNARY(expm1)
144 // LIBMESH_FLOAT128_UNARY(log2)
145 // LIBMESH_FLOAT128_UNARY(log1p)
146 // LIBMESH_FLOAT128_UNARY(cbrt)
147 // LIBMESH_FLOAT128_UNARY(asinh)
148 // LIBMESH_FLOAT128_UNARY(acosh)
149 // LIBMESH_FLOAT128_UNARY(atanh)
150 // LIBMESH_FLOAT128_UNARY(erf)
151 // LIBMESH_FLOAT128_UNARY(erfc)
154 // LIBMESH_FLOAT128_UNARY(nearbyint)
155 // LIBMESH_FLOAT128_UNARY(rint)
156 
157 // LIBMESH_FLOAT128_BINARY(remainder)
158 // LIBMESH_FLOAT128_BINARY(fmax)
159 // LIBMESH_FLOAT128_BINARY(fmin)
160 // LIBMESH_FLOAT128_BINARY(fdim)
161 // LIBMESH_FLOAT128_BINARY(hypot)
162 
163 }
164 
165 #endif // LIBMESH_FLOAT128_SHIMS_H
std::sqrt
MetaPhysicL::DualNumber< T, D > sqrt(const MetaPhysicL::DualNumber< T, D > &in)
boost
Definition: numeric_vector.h:1002
std::abs
MetaPhysicL::DualNumber< T, D > abs(const MetaPhysicL::DualNumber< T, D > &in)
std::pow
double pow(double a, int b)
Definition: libmesh_augment_std_namespace.h:58
std::LIBMESH_FLOAT128_BINARY
LIBMESH_FLOAT128_BINARY(pow) LIBMESH_FLOAT128_BINARY(atan2) LIBMESH_FLOAT128_BINARY(fmod) inline boost
Definition: float128_shims.h:127
std::LIBMESH_FLOAT128_MATH_BOOL
LIBMESH_FLOAT128_MATH_BOOL(isinf) LIBMESH_FLOAT128_MATH_BOOL(isnan) inline boost
Definition: float128_shims.h:111
std::LIBMESH_FLOAT128_UNARY
LIBMESH_FLOAT128_UNARY(sqrt) LIBMESH_FLOAT128_UNARY(exp) LIBMESH_FLOAT128_UNARY(log) LIBMESH_FLOAT128_UNARY(log10) LIBMESH_FLOAT128_UNARY(sin) LIBMESH_FLOAT128_UNARY(cos) LIBMESH_FLOAT128_UNARY(tan) LIBMESH_FLOAT128_UNARY(asin) LIBMESH_FLOAT128_UNARY(acos) LIBMESH_FLOAT128_UNARY(atan) LIBMESH_FLOAT128_UNARY(sinh) LIBMESH_FLOAT128_UNARY(cosh) LIBMESH_FLOAT128_UNARY(tanh) LIBMESH_FLOAT128_UNARY(abs) LIBMESH_FLOAT128_UNARY(fabs) LIBMESH_FLOAT128_UNARY(ceil) LIBMESH_FLOAT128_UNARY(floor) inline boost
Definition: float128_shims.h:51
std
Definition: float128_shims.h:27
std::norm
MetaPhysicL::DualNumber< T, D > norm(const MetaPhysicL::DualNumber< T, D > &in)
std::imag
boost::multiprecision::float128 imag(const boost::multiprecision::float128)
Definition: float128_shims.h:83
std::real
boost::multiprecision::float128 real(const boost::multiprecision::float128 in)
Definition: float128_shims.h:77