point_variance.h

Back to Statistics

pastel/math/statistic/

// Description: Variance of a point-set
// Documentation: statistics.txt

#ifndef PASTELMATH_POINT_VARIANCE_H
#define PASTELMATH_POINT_VARIANCE_H

#include "pastel/sys/pointset/pointset_concept.h"
#include "pastel/sys/vector.h"

// Implementation

#include "pastel/math/statistic/point_mean.h"

namespace Pastel
{

    //! Returns the point-set variance.
    /*!
   Time complexity:
   O(nd)
   where
   n = size(pointSet), and
   d = locator.n().
   */
    template <
        typename PointSet,
        typename Real = PointSet_Real<PointSet>,
        typename Locator = PointSet_Locator<PointSet>,
        typename... ArgumentSet,
        Requires<
            Models<PointSet, PointSet_Concept>
        > = 0>
    auto pointVariance(
        PointSet pointSet,
        ArgumentSet&&... argumentSet)
        -> Vector<Real, Locator::N>
    {
        bool biased = PASTEL_ARG_S(biased, true);
        Vector<Real, Locator::N> mean = PASTEL_ARG_S(mean, pointMean(pointSet));

        auto&& locator = pointSetLocator(pointSet);

        integer d = locator.n();
        ENSURE_OP(d, >=, 0);

        Vector<Real, Locator::N> result(ofDimension(d), 0);

        if (pointSet.empty() || d == 0)
        {
            return result;
        }

        integer n = 0;
        RANGES_FOR(auto&& point, pointSet)
        {
            for (integer i = 0; i < d;++i)
            {
                result[i] += 
                    square(pointAxis(point, i) - mean[i]);
            }
            ++n;
        }

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

        if (biased)
        {
            return result / n;
        }
        else
        {
            if (n > 1)
            {
                return result / (n - 1);
            }
            else
            {
                result.set(0);
            }
        }

        return result;
    }

}

#endif