Skip to main content

laddu_data/data/dataset/
accurate.rs

1//! Numerically accurate accumulators used by parallel reductions.
2
3use accurate::{sum::Sum2, traits::*};
4use num::complex::Complex64;
5
6/// Compensated accumulator for real values.
7#[derive(Clone)]
8pub struct AccurateF64 {
9    sum: Sum2<f64>,
10}
11
12impl AccurateF64 {
13    /// Creates a zero accumulator.
14    pub fn zero() -> Self {
15        Self { sum: Sum2::zero() }
16    }
17
18    /// Adds one value.
19    pub fn push(&mut self, value: f64) {
20        let sum = std::mem::replace(&mut self.sum, Sum2::zero());
21        self.sum = sum + value;
22    }
23
24    /// Merges another accumulator.
25    pub fn merge(&mut self, other: Self) {
26        self.push(other.finish());
27    }
28
29    /// Returns the accumulated sum.
30    pub fn finish(self) -> f64 {
31        self.sum.sum()
32    }
33}
34
35/// Pair of compensated accumulators for complex values.
36#[derive(Clone)]
37pub struct AccurateComplex64 {
38    re: AccurateF64,
39    im: AccurateF64,
40}
41
42impl AccurateComplex64 {
43    /// Creates a zero accumulator.
44    pub fn zero() -> Self {
45        Self {
46            re: AccurateF64::zero(),
47            im: AccurateF64::zero(),
48        }
49    }
50
51    /// Adds one complex value.
52    pub fn push(&mut self, value: Complex64) {
53        self.re.push(value.re);
54        self.im.push(value.im);
55    }
56
57    /// Merges another accumulator.
58    pub fn merge(&mut self, other: Self) {
59        self.re.merge(other.re);
60        self.im.merge(other.im);
61    }
62
63    /// Returns the accumulated complex sum.
64    pub fn finish(self) -> Complex64 {
65        Complex64::new(self.re.finish(), self.im.finish())
66    }
67}