scalar_covariance.h

Back to Statistics

pastel/math/statistic/

// Description: Covariance between scalar sequences
// Documentation: statistics.txt

#ifndef PASTELMATH_SCALAR_COVARIANCE_H
#define PASTELMATH_SCALAR_COVARIANCE_H

#include "pastel/sys/real/real_concept.h"
#include "pastel/sys/set/set_concept.h"

// Implementation

#include "pastel/math/statistic/scalar_covariance.h"
#include "pastel/math/statistic/scalar_mean.h"

namespace Pastel
{

    //! Returns the covariance between scalar sequences.
    /*!
   Time complexity: 
   O(n)
   where n = min(size(aSet), size(bSet)).

   Optional arguments
   ------------------

   biased (bool : true):
   Whether to return a biased estimate.

   aMean (Real : scalarMean<Real>(aSet)):
   The mean of 'aSet'.

   bMean (Real : scalarMean<Real>(bSet)):
   The mean of 'bSet'.

   Returns
   -------

   returns:
   [sum_{i = 1}^n (a_i - m_a) * (b_i - m_b)] / n', if biased and n > 0,
   [sum_{i = 1}^n (a_i - m_a) * (b_i - m_b)] / (n - 1), if !biased and n > 1,
   0, otherwise.
   */
    template <
        typename Real,
        typename A_Real_Set,
        typename B_Real_Set,
        typename... ArgumentSet,
        Requires<
            Models<Real, Real_Concept>,
            Models<A_Real_Set, Set_Concept>,
            Models<B_Real_Set, Set_Concept>
        > = 0
    >
    Real scalarCovariance(
        const A_Real_Set& aSet,
        const B_Real_Set& bSet,
        ArgumentSet&&... argumentSet)
    {
        bool biased = PASTEL_ARG_S(biased, true);
        Real aMean = PASTEL_ARG_S(aMean, scalarMean<Real>(aSet));
        Real bMean = PASTEL_ARG_S(bMean, scalarMean<Real>(bSet));

        integer n = 0;
        Real covariance = 0;
        RANGES_FOR(auto&& elements, zipSet(aSet, bSet))
        {
            covariance += 
                (elements.first - aMean) * 
                (elements.second - bMean);
            ++n;
        }

        if (n == 0)
        {
            return 0;
        }

        if (biased)
        {
            covariance /= n;
        }
        else
        {
            if (n > 1)
            {
                covariance /= n - 1;
            }
            else
            {
                covariance = 0;
            }
        }

        return covariance;
    }

}

#endif