// 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