boostorg / accumulators

An awesome library from Boost
http://boost.org/libs/accumulators
22 stars 54 forks source link

Condition number of summation #24

Closed NAThompson closed 5 years ago

NAThompson commented 5 years ago

Would you be interested in accepting a PR for the condition number of summation?

It's not a complicated algorithm, of course, but still it's a very useful diagnostic. Here's a sketch:

template<class Real>
class summation_condition_number {
public:
    summation_condition_number(Real x = 0)
    {
        using std::abs;
        m_l1 = abs(x);
        m_sum = x;
    }

    void operator+=(Real x)
    {
        using std::abs;
        m_l1 += abs(x);
        m_sum += x;
    }

    [[nodiscard]] Real operator()() const
    {
        using std::abs;
        if (m_sum == Real(0) && m_l1 != Real(0))
        {
            return std::numeric_limits<Real>::infinity();
        }
        return m_l1/abs(m_sum);
    }

    [[nodiscard]] Real sum() const
    {
        return m_sum;
    }

private:
    Real m_l1;
    Real m_sum;
};

and usage:

    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_real_distribution<Real> dist(-1,1);
    cond = summation_condition_number<Real>();
    int i = 0;
    while(i++ < 1000000)
    {
        cond += dist(gen);
    }
    std::cout << "Condition number = " << cond() << "\n";
    std::cout << "Sum = " << cond.sum() << "\n";
NAThompson commented 5 years ago

Sorry for the noise, actually I don't think accumulators is the correct place for this; it should be grouped with the other condition numbers (like function evaluation and matrix condition numbers.)