46class ExtendedPrecision {
53 ExtendedPrecision() =
default;
54 ~ExtendedPrecision() =
default;
55#pragma hila loop_function
56 ExtendedPrecision(
const ExtendedPrecision &rhs)
57 : value(rhs.value), compensation(rhs.compensation), compensation2(rhs.compensation2) {}
58 ExtendedPrecision(
double v) : value(v), compensation(0), compensation2(0) {}
59 ExtendedPrecision(
double v,
double c,
double c2)
60 : value(v), compensation(c), compensation2(c2) {}
63#pragma hila loop_function
64 ExtendedPrecision &operator=(
const ExtendedPrecision &rhs) {
67 compensation = rhs.compensation;
68 compensation2 = rhs.compensation2;
72#pragma hila loop_function
73 template <typename T, std::enable_if_t<hila::is_arithmetic<T>::value,
int> = 0>
74 ExtendedPrecision &operator=(
const T &v) {
76 compensation = compensation2 = 0;
81 ExtendedPrecision operator+()
const {
93 inline ExtendedPrecision operator-()
const {
94 return ExtendedPrecision(-value, -compensation, -compensation2);
105#pragma hila loop_function
106 template <typename T, std::enable_if_t<std::is_arithmetic<T>::value,
int> = 0>
107 inline const ExtendedPrecision &operator+=(
const T &rhs_) {
109 double t = value + rhs;
111 if (
abs(value) >=
abs(rhs)) {
112 c = (value - t) + rhs;
114 c = (rhs - t) + value;
117 t = compensation + c;
118 if (
abs(compensation) >=
abs(c)) {
119 cc = (compensation - t) + c;
121 cc = (c - t) + compensation;
134#pragma hila loop_function
136 inline const ExtendedPrecision &operator+=(ExtendedPrecision rhs) {
137 *
this += rhs.compensation2;
138 *
this += rhs.compensation;
143 inline const ExtendedPrecision &operator-=(
const ExtendedPrecision &rhs) {
144 return *
this += -rhs;
147 template <typename T, std::enable_if_t<std::is_arithmetic<T>::value,
int> = 0>
148 inline const ExtendedPrecision &operator-=(
const T &rhs) {
149 return *
this += -rhs;
152 template <typename T, std::enable_if_t<std::is_arithmetic<T>::value,
int> = 0>
153 inline const ExtendedPrecision &operator*=(T rhs) {
154 static_assert(std::is_integral<T>::value,
155 "ExtendedPrecision can be multiplied only by integral value without losing "
156 "precision! Convert to double for more general operations");
161 bool negative = (!std::is_unsigned<T>::value && (rhs < 0));
166 while (rhs % 2 == 0) {
173 this->compensation *=
mult;
174 this->compensation2 *=
mult;
182 while (2 *
mult < rhs) {
187 b.value = a.value *
mult;
188 b.compensation = a.compensation *
mult;
189 b.compensation2 = a.compensation2 *
mult;
195 this->value = -this->value;
196 this->compensation = -this->compensation;
197 this->compensation2 = -this->compensation2;
220 explicit operator double()
const {
221 return value + (compensation + compensation2);
227 double to_double()
const {
228 return value + (compensation + compensation2);
237struct is_extended : std::integral_constant<bool, std::is_same<T, ExtendedPrecision>::value> {};
240struct is_arithmetic_or_extended
241 : std::integral_constant<bool, hila::is_arithmetic<T>::value || hila::is_extended<T>::value> {};
243template <
typename A,
typename B>
245 : std::integral_constant<
246 bool, (hila::is_extended<A>::value && hila::is_arithmetic_or_extended<B>::value) ||
247 (hila::is_extended<B>::value && std::is_arithmetic<A>::value)> {};
256template <typename T, std::enable_if_t<std::is_arithmetic<T>::value,
int> = 0>
257inline ExtendedPrecision
operator+(ExtendedPrecision a,
const T b) {
260template <typename T, std::enable_if_t<std::is_arithmetic<T>::value,
int> = 0>
261inline ExtendedPrecision
operator+(
const T b, ExtendedPrecision a) {
264inline ExtendedPrecision
operator+(ExtendedPrecision a,
const ExtendedPrecision &b) {
269template <typename A, typename B, std::enable_if_t<hila::AorB_extended<A, B>::value,
int> = 0>
270inline ExtendedPrecision operator-(
const A &a,
const B &b) {
275template <typename T, std::enable_if_t<std::is_arithmetic<T>::value,
int> = 0>
276inline ExtendedPrecision operator*(ExtendedPrecision a, T v) {
277 static_assert(std::is_integral<T>::value,
278 "ExtendedPrecision can be multiplied only by integral value without losing "
279 "precision! Convert to double for more general operations");
282template <typename T, std::enable_if_t<std::is_arithmetic<T>::value,
int> = 0>
283inline ExtendedPrecision operator*(T v, ExtendedPrecision a) {
284 static_assert(std::is_integral<T>::value,
285 "ExtendedPrecision can be multiplied only by integral value without losing "
286 "precision! Convert to double for more general operations");
296template <typename A, typename B, std::enable_if_t<hila::AorB_extended<A, B>::value,
int> = 0>
298 ExtendedPrecision tmp = a - b;
299 return (tmp.to_double() == 0.0);
301template <typename A, typename B, std::enable_if_t<hila::AorB_extended<A, B>::value,
int> = 0>
302inline bool operator!=(
const A &a,
const B &b) {
303 ExtendedPrecision tmp = a - b;
304 return (tmp.to_double() != 0.0);
306template <typename A, typename B, std::enable_if_t<hila::AorB_extended<A, B>::value,
int> = 0>
307inline bool operator>(
const A &a,
const B &b) {
308 ExtendedPrecision tmp = a - b;
309 return (tmp.to_double() > 0.0);
311template <typename A, typename B, std::enable_if_t<hila::AorB_extended<A, B>::value,
int> = 0>
312inline bool operator<(
const A &a,
const B &b) {
313 ExtendedPrecision tmp = a - b;
314 return (tmp.to_double() < 0.0);
316template <typename A, typename B, std::enable_if_t<hila::AorB_extended<A, B>::value,
int> = 0>
317inline bool operator>=(
const A &a,
const B &b) {
318 ExtendedPrecision tmp = a - b;
319 return (tmp.to_double() >= 0.0);
321template <typename A, typename B, std::enable_if_t<hila::AorB_extended<A, B>::value,
int> = 0>
322inline bool operator<=(
const A &a,
const B &b) {
323 ExtendedPrecision tmp = a - b;
324 return (tmp.to_double() <= 0.0);
328inline std::ostream &
operator<<(std::ostream &strm,
const ExtendedPrecision &var) {
329 return strm << var.to_double();
334template <
typename Ntype>
335Ntype
cast_to(
const ExtendedPrecision &ep) {
336 if constexpr (std::is_same<Ntype, ExtendedPrecision>::value)
339 return static_cast<Ntype
>(ep.to_double());
342inline std::string prettyprint(
const ExtendedPrecision &val,
int prec = 8) {
343 return prettyprint(val.to_double(), prec);
std::ostream & operator<<(std::ostream &strm, const Array< n, m, T > &A)
Stream operator.
T abs(const Complex< T > &a)
Return absolute value of Complex number.
This file defines all includes for HILA.
ExtendedPrecision operator+(ExtendedPrecision a, const T b)
ExtendedPrecision precision operators + - * / – also ext * arithm.
bool operator==(const A &a, const B &b)
comparison operators
void mult(const Mt1 &a, const Mt2 &b, Mt3 &res)
compute product of two matrices and write result to existing matrix
Implement hila::swap for gauge fields.
Array< n, m, Ntype > cast_to(const Array< n, m, T > &mat)
Array casting operation.