point_patterns.hpp

Back to Deprecated

pastel/geometry/

#ifndef PASTELGEOMETRY_POINT_PATTERNS_HPP
#define PASTELGEOMETRY_POINT_PATTERNS_HPP

#include "pastel/geometry/point_patterns.h"

#include "pastel/sys/random.h"

#include "pastel/math/sampling/uniform_sampling.h"
#include "pastel/math/matrix/orthonormal.h"

namespace Pastel
{

    template <typename Real, integer N>
    void generateUniformBallPointSet(
        integer points,
        integer dimension,
        std::vector<Vector<Real, N> >& pointSet)
    {
        ENSURE_OP(points, >, 0);
        ENSURE_OP(dimension, >, 0);
        ENSURE2(N == Dynamic || N == dimension, N, dimension);

        std::vector<Vector<Real, N> > result;
        result.reserve(points);

        for (integer i = 0;i < points;++i)
        {
            result.push_back(randomVectorBall<Real, N>(dimension));
        }

        result.swap(pointSet);
    }

    template <typename Real, integer N>
    void generateClusteredPointSet(
        integer points,
        integer dimension,
        integer clusters,
        std::vector<Vector<Real, N> >& pointSet)
    {
        ENSURE_OP(points, >, 0);
        ENSURE_OP(dimension, >, 0);
        ENSURE_OP(clusters, >, 0);
        ENSURE2(N == Dynamic || N == dimension, N, dimension);

        std::vector<Vector<Real, N> > result;
        result.reserve(points);

        Real realPointsCreated = 0;
        Real realClusterPoints = (Real)points / clusters;

        integer pointsCreated = 0;

        for (integer j = 0;j < clusters;++j)
        {
            integer clusterPoints = 
                (realPointsCreated + realClusterPoints) - pointsCreated;
            if (j == clusters - 1)
            {
                clusterPoints = points - pointsCreated;
            }

            Vector<Real, N> clusterCenter(
                randomVectorCube<Real, N>(dimension));

            const Real clusterRadius = random<Real>() * 0.1;

            for (integer i = 0;i < clusterPoints;++i)
            {
                result.push_back(
                    clusterCenter + 
                    randomGaussianVector<Real, N>(dimension) * clusterRadius);
            }

            realPointsCreated += realClusterPoints;
            pointsCreated += clusterPoints;
        }

        result.swap(pointSet);
    }

    template <typename Real, integer N>
    void generateUniformCubePointSet(
        integer points,
        integer dimension,
        std::vector<Vector<Real, N> >& pointSet)
    {
        ENSURE_OP(points, >, 0);
        ENSURE_OP(dimension, >, 0);
        ENSURE2(N == Dynamic || N == dimension, N, dimension);

        std::vector<Vector<Real, N> > result;
        result.reserve(points);

        for (integer i = 0;i < points;++i)
        {
            result.push_back(
                randomVectorCube<Real, N>(dimension));
        }

        result.swap(pointSet);
    }

    template <typename Real, integer N>
    void generateGaussianPointSet(
        integer points,
        integer dimension,
        std::vector<Vector<Real, N> >& pointSet)
    {
        ENSURE_OP(points, >, 0);
        ENSURE_OP(dimension, >, 0);
        ENSURE2(N == Dynamic || N == dimension, N, dimension);

        std::vector<Vector<Real, N> > result;
        result.reserve(points);

        for (integer i = 0;i < points;++i)
        {
            result.push_back(
                randomGaussianVector<Real, N>(dimension));
        }

        result.swap(pointSet);
    }

    template <typename Real, integer N>
    void scale(
        const Vector<Real, N>& scaling,
        std::vector<Vector<Real, N> >& pointSet)
    {
        if (pointSet.empty())
        {
            return;
        }

        integer points = pointSet.size();
        for (integer i = 0;i < points;++i)
        {
            pointSet[i] *= scaling;
        }
    }

    template <typename Real, integer N>
    void randomlyRotate(
        std::vector<Vector<Real, N> >& pointSet)
    {
        if (pointSet.empty())
        {
            return;
        }

        integer points = pointSet.size();
        integer dimension = pointSet.front().n();

        Matrix<Real> rotation = randomRotation(dimension);
        for (integer i = 0;i < points;++i)
        {
            pointSet[i] = pointSet[i] * rotation;
        }
    }

    template <typename Real, integer N>
    void randomlyReduceDimensionality(
        integer dimensionality,
        std::vector<Vector<Real, N> >& pointSet)
    {
        ENSURE_OP(dimensionality, >, 0);

        integer dimension = pointSet.front().n();

        ENSURE_OP(dimensionality, <=, dimension);

        if (pointSet.empty() || dimensionality == dimension)
        {
            return;
        }

        std::vector<integer> indexSet;
        for (integer i = 0;i < dimension;++i)
        {
            indexSet.push_back(i);
        }

        std::random_shuffle(
            indexSet.begin(), indexSet.end());

        integer dimensionsToRemove = dimension - dimensionality;

        integer points = pointSet.size();
        for (integer i = 0;i < points;++i)
        {
            for (integer j = 0;j < dimensionsToRemove;++j)
            {
                pointSet[i][indexSet[j]] = 0;
            }
        }
    }

}

#endif