Coverage Report

Created: 2024-10-11 06:23

/builds/MusicScience37Projects/numerical-analysis/numerical-collection-cpp/include/num_collect/util/kahan_adder.h
Line
Count
Source
1
/*
2
 * Copyright 2021 MusicScience37 (Kenta Kabashima)
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
/*!
17
 * \file
18
 * \brief Definition of kahan_adder class.
19
 */
20
#pragma once
21
22
#include "num_collect/util/concepts/kahan_addable.h"
23
24
namespace num_collect::util {
25
26
/*!
27
 * \brief Class to add numbers using Kahan summation \cite Kahan1965.
28
 *
29
 * \tparam T Type of numbers.
30
 */
31
template <concepts::kahan_addable T>
32
class kahan_adder {
33
public:
34
    /*!
35
     * \brief Constructor.
36
     *
37
     * \note This won't work for Eigen's vectors and matrices.
38
     * Use another constructor for them.
39
     */
40
36
    kahan_adder() : kahan_adder(static_cast<T>(0)) {}
_ZN11num_collect4util11kahan_adderIfEC2Ev
Line
Count
Source
40
16
    kahan_adder() : kahan_adder(static_cast<T>(0)) {}
_ZN11num_collect4util11kahan_adderINSt3__17complexIfEEEC2Ev
Line
Count
Source
40
2
    kahan_adder() : kahan_adder(static_cast<T>(0)) {}
_ZN11num_collect4util11kahan_adderIdEC2Ev
Line
Count
Source
40
16
    kahan_adder() : kahan_adder(static_cast<T>(0)) {}
_ZN11num_collect4util11kahan_adderINSt3__17complexIdEEEC2Ev
Line
Count
Source
40
2
    kahan_adder() : kahan_adder(static_cast<T>(0)) {}
41
42
    /*!
43
     * \brief Construct with zero number.
44
     *
45
     * This constructor is useful for Eigen's vectors and matrices.
46
     *
47
     * \param[in] zero Zero.
48
     */
49
    explicit kahan_adder(const T& zero)
50
36
        : sum_(zero), rem_(zero), prev_sum_(zero) {}
_ZN11num_collect4util11kahan_adderINSt3__17complexIfEEEC2ERKS4_
Line
Count
Source
50
2
        : sum_(zero), rem_(zero), prev_sum_(zero) {}
_ZN11num_collect4util11kahan_adderINSt3__17complexIdEEEC2ERKS4_
Line
Count
Source
50
2
        : sum_(zero), rem_(zero), prev_sum_(zero) {}
_ZN11num_collect4util11kahan_adderIfEC2ERKf
Line
Count
Source
50
16
        : sum_(zero), rem_(zero), prev_sum_(zero) {}
_ZN11num_collect4util11kahan_adderIdEC2ERKd
Line
Count
Source
50
16
        : sum_(zero), rem_(zero), prev_sum_(zero) {}
51
52
    /*!
53
     * \brief Add a number.
54
     *
55
     * \param[in] value Added value.
56
     * \return This.
57
     */
58
21.0k
    auto add(const T& value) -> kahan_adder& {
59
21.0k
        prev_sum_ = sum_;
60
21.0k
        rem_ += value;
61
21.0k
        sum_ += rem_;
62
21.0k
        rem_ -= sum_ - prev_sum_;
63
21.0k
        return *this;
64
21.0k
    }
_ZN11num_collect4util11kahan_adderIfE3addERKf
Line
Count
Source
58
10.4k
    auto add(const T& value) -> kahan_adder& {
59
10.4k
        prev_sum_ = sum_;
60
10.4k
        rem_ += value;
61
10.4k
        sum_ += rem_;
62
10.4k
        rem_ -= sum_ - prev_sum_;
63
10.4k
        return *this;
64
10.4k
    }
_ZN11num_collect4util11kahan_adderINSt3__17complexIfEEE3addERKS4_
Line
Count
Source
58
82
    auto add(const T& value) -> kahan_adder& {
59
82
        prev_sum_ = sum_;
60
82
        rem_ += value;
61
82
        sum_ += rem_;
62
82
        rem_ -= sum_ - prev_sum_;
63
82
        return *this;
64
82
    }
_ZN11num_collect4util11kahan_adderIdE3addERKd
Line
Count
Source
58
10.4k
    auto add(const T& value) -> kahan_adder& {
59
10.4k
        prev_sum_ = sum_;
60
10.4k
        rem_ += value;
61
10.4k
        sum_ += rem_;
62
10.4k
        rem_ -= sum_ - prev_sum_;
63
10.4k
        return *this;
64
10.4k
    }
_ZN11num_collect4util11kahan_adderINSt3__17complexIdEEE3addERKS4_
Line
Count
Source
58
82
    auto add(const T& value) -> kahan_adder& {
59
82
        prev_sum_ = sum_;
60
82
        rem_ += value;
61
82
        sum_ += rem_;
62
82
        rem_ -= sum_ - prev_sum_;
63
82
        return *this;
64
82
    }
65
66
    /*!
67
     * \brief Subtract a number.
68
     *
69
     * \param[in] value Added value.
70
     * \return This.
71
     */
72
4
    auto sub(const T& value) -> kahan_adder& {
73
4
        prev_sum_ = sum_;
74
4
        rem_ += -value;
75
4
        sum_ += rem_;
76
4
        rem_ -= sum_ - prev_sum_;
77
4
        return *this;
78
4
    }
_ZN11num_collect4util11kahan_adderIfE3subERKf
Line
Count
Source
72
2
    auto sub(const T& value) -> kahan_adder& {
73
2
        prev_sum_ = sum_;
74
2
        rem_ += -value;
75
2
        sum_ += rem_;
76
2
        rem_ -= sum_ - prev_sum_;
77
2
        return *this;
78
2
    }
_ZN11num_collect4util11kahan_adderIdE3subERKd
Line
Count
Source
72
2
    auto sub(const T& value) -> kahan_adder& {
73
2
        prev_sum_ = sum_;
74
2
        rem_ += -value;
75
2
        sum_ += rem_;
76
2
        rem_ -= sum_ - prev_sum_;
77
2
        return *this;
78
2
    }
79
80
    /*!
81
     * \brief Add a number.
82
     *
83
     * \param[in] value Added value.
84
     * \return This.
85
     */
86
21.0k
    auto operator+=(const T& value) -> kahan_adder& {
87
21.0k
        add(value);
88
21.0k
        return *this;
89
21.0k
    }
_ZN11num_collect4util11kahan_adderIfEpLERKf
Line
Count
Source
86
10.4k
    auto operator+=(const T& value) -> kahan_adder& {
87
10.4k
        add(value);
88
10.4k
        return *this;
89
10.4k
    }
_ZN11num_collect4util11kahan_adderINSt3__17complexIfEEEpLERKS4_
Line
Count
Source
86
82
    auto operator+=(const T& value) -> kahan_adder& {
87
82
        add(value);
88
82
        return *this;
89
82
    }
_ZN11num_collect4util11kahan_adderIdEpLERKd
Line
Count
Source
86
10.4k
    auto operator+=(const T& value) -> kahan_adder& {
87
10.4k
        add(value);
88
10.4k
        return *this;
89
10.4k
    }
_ZN11num_collect4util11kahan_adderINSt3__17complexIdEEEpLERKS4_
Line
Count
Source
86
82
    auto operator+=(const T& value) -> kahan_adder& {
87
82
        add(value);
88
82
        return *this;
89
82
    }
90
91
    /*!
92
     * \brief Subtract a number.
93
     *
94
     * \param[in] value Added value.
95
     * \return This.
96
     */
97
4
    auto operator-=(const T& value) -> kahan_adder& {
98
4
        sub(value);
99
4
        return *this;
100
4
    }
_ZN11num_collect4util11kahan_adderIfEmIERKf
Line
Count
Source
97
2
    auto operator-=(const T& value) -> kahan_adder& {
98
2
        sub(value);
99
2
        return *this;
100
2
    }
_ZN11num_collect4util11kahan_adderIdEmIERKd
Line
Count
Source
97
2
    auto operator-=(const T& value) -> kahan_adder& {
98
2
        sub(value);
99
2
        return *this;
100
2
    }
101
102
    /*!
103
     * \brief Get sum.
104
     *
105
     * \return Sum.
106
     */
107
36
    [[nodiscard]] auto sum() const noexcept -> const T& { return sum_; }
_ZNK11num_collect4util11kahan_adderIfE3sumEv
Line
Count
Source
107
16
    [[nodiscard]] auto sum() const noexcept -> const T& { return sum_; }
_ZNK11num_collect4util11kahan_adderINSt3__17complexIfEEE3sumEv
Line
Count
Source
107
2
    [[nodiscard]] auto sum() const noexcept -> const T& { return sum_; }
_ZNK11num_collect4util11kahan_adderIdE3sumEv
Line
Count
Source
107
16
    [[nodiscard]] auto sum() const noexcept -> const T& { return sum_; }
_ZNK11num_collect4util11kahan_adderINSt3__17complexIdEEE3sumEv
Line
Count
Source
107
2
    [[nodiscard]] auto sum() const noexcept -> const T& { return sum_; }
108
109
    /*!
110
     * \brief Get sum.
111
     *
112
     * \return Sum.
113
     */
114
    operator T() const {  // NOLINT: Allow implicit conversion.
115
        return sum_;
116
    }
117
118
private:
119
    //! Sum.
120
    T sum_;
121
122
    //! Remaining.
123
    T rem_;
124
125
    //! Previous sum.
126
    T prev_sum_;
127
};
128
129
}  // namespace num_collect::util