eOn 3.2.0
Long-timescale dynamics: aKMC, NEB, parallel replica
☾
Toggle main menu visibility
Loading...
Searching...
No Matches
ExactReduction.h
Go to the documentation of this file.
1
/*
2
** This file is part of eOn.
3
**
4
** SPDX-License-Identifier: BSD-3-Clause
5
**
6
** Copyright (c) 2010--present, eOn Development Team
7
** All rights reserved.
8
**
9
** Repo:
10
** https://github.com/TheochemUI/eOn
11
*/
12
#pragma once
13
14
// Correctly rounded dot products and norms.
15
//
16
// Every finite double is an integer times a power of two, so x_i * y_i is
17
// the 106-bit integer product of the two significands times 2^(e_x + e_y),
18
// with no rounding. The products are added into a fixed-point integer
19
// accumulator that spans the whole exponent range (Kulisch), where addition
20
// is associative, and the exact total is rounded once to nearest, ties to
21
// even. The result is therefore a function of the multiset of products
22
// alone: the same bits for any summation order, vector width, contraction
23
// setting, compiler or Eigen release. This is the integer formulation of
24
// the error-free splitting in Ozaki, Ogita, Oishi and Rump, Numer.
25
// Algorithms 59 (2012), doi:10.1007/s11075-011-9478-1, and of Ozaki,
26
// Uchino and Imamura's scheme II (arXiv:2504.08009), taken to a single
27
// correctly rounded scalar.
28
//
29
// Use these where a reduction decides something (step lengths, curvature
30
// estimates, convergence tests, acceptance); Eigen's own reductions change
31
// their association between releases (3.4 sums two packet accumulators,
32
// 5.0 four) and with the SIMD width.
33
34
#include <cmath>
35
#include <cstddef>
36
37
#include <Eigen/Core>
38
39
namespace
eonc::exact
{
40
44
[[nodiscard]]
double
dot
(
const
double
*x,
const
double
*y, std::size_t n);
45
47
[[nodiscard]]
double
sum
(
const
double
*x, std::size_t n);
48
51
[[nodiscard]]
double
sumStrided
(
const
double
*x, std::size_t n,
52
std::size_t stride);
53
60
[[nodiscard]]
double
orderedDot
(
const
double
*x,
const
double
*y,
61
std::size_t n);
62
63
// Eigen front ends. A plain object or a contiguous block is read in place;
64
// any other expression is evaluated into a plain temporary first. The
65
// result does not depend on the storage order or the stride.
66
template
<
typename
A,
typename
B>
67
[[nodiscard]]
double
dot
(
const
Eigen::MatrixBase<A> &x,
68
const
Eigen::MatrixBase<B> &y) {
69
eigen_assert(x.size() == y.size());
70
const
auto
&xe = x.derived().eval();
71
const
auto
&ye = y.derived().eval();
72
return
dot
(xe.data(), ye.data(),
static_cast<
std::size_t
>
(xe.size()));
73
}
74
75
template
<
typename
A,
typename
B>
76
[[nodiscard]]
double
orderedDot
(
const
Eigen::MatrixBase<A> &x,
77
const
Eigen::MatrixBase<B> &y) {
78
eigen_assert(x.size() == y.size());
79
const
auto
&xe = x.derived().eval();
80
const
auto
&ye = y.derived().eval();
81
return
orderedDot
(xe.data(), ye.data(),
static_cast<
std::size_t
>
(xe.size()));
82
}
83
84
template
<
typename
A>
85
[[nodiscard]]
double
squaredNorm
(
const
Eigen::MatrixBase<A> &x) {
86
const
auto
&xe = x.derived().eval();
87
return
dot
(xe.data(), xe.data(),
static_cast<
std::size_t
>
(xe.size()));
88
}
89
92
template
<
typename
A> [[nodiscard]]
double
norm
(
const
Eigen::MatrixBase<A> &x) {
93
return
std::sqrt(
squaredNorm
(x));
94
}
95
99
template
<
typename
A>
100
[[nodiscard]]
double
orderedNorm
(
const
Eigen::MatrixBase<A> &x) {
101
return
std::sqrt(
orderedDot
(x, x));
102
}
103
105
template
<
typename
A>
106
[[nodiscard]]
typename
A::PlainObject
normalized
(
const
Eigen::MatrixBase<A> &x,
107
double
min_norm = 1e-300) {
108
const
double
n =
norm
(x);
109
if
(n < min_norm) [[unlikely]] {
110
return
A::PlainObject::Zero(x.rows(), x.cols());
111
}
112
return
(x / n).eval();
113
}
114
115
}
// namespace eonc::exact
eonc::exact
Definition
ExactReduction.cpp:32
eonc::exact::squaredNorm
double squaredNorm(const Eigen::MatrixBase< A > &x)
Definition
ExactReduction.h:85
eonc::exact::normalized
A::PlainObject normalized(const Eigen::MatrixBase< A > &x, double min_norm=1e-300)
x / norm(x), or zero below min_norm (the safemath convention).
Definition
ExactReduction.h:106
eonc::exact::sumStrided
double sumStrided(const double *x, std::size_t n, std::size_t stride)
Same sum for x[i * stride].
Definition
ExactReduction.cpp:516
eonc::exact::norm
double norm(const Eigen::MatrixBase< A > &x)
sqrt of the correctly rounded squared norm; IEEE sqrt is itself correctly rounded,...
Definition
ExactReduction.h:92
eonc::exact::dot
double dot(const double *x, const double *y, std::size_t n)
Round-to-nearest-even value of the exact sum of x[i] * y[i].
Definition
ExactReduction.cpp:451
eonc::exact::orderedNorm
double orderedNorm(const Eigen::MatrixBase< A > &x)
sqrt of orderedDot(x, x): reproducible, not correctly rounded.
Definition
ExactReduction.h:100
eonc::exact::sum
double sum(const double *x, std::size_t n)
Round-to-nearest-even value of the exact sum of x[i].
Definition
ExactReduction.cpp:514
eonc::exact::orderedDot
double orderedDot(const double *x, const double *y, std::size_t n)
A fixed summation tree: four lanes (term i goes to lane i mod 4, each lane a left-to-right sum of rou...
Definition
ExactReduction.cpp:483
include
eon
ExactReduction.h
Generated by
1.17.0
Generated by
Doxygen 1.17.0
Analytics by
Antics
provided by
TurtleTech ehf