reconstruct_rbf.h

Back to Reconstruction

pastel/gfx/reconstruction/

// Description: Interpolation based on Radial Basis Functions
// Documentation: reconstruction.txt

#ifndef PASTELGFX_RECONSTRUCT_RBF_H
#define PASTELGFX_RECONSTRUCT_RBF_H

#include "pastel/sys/vector.h"

#include "pastel/gfx/filter.h"

#include "pastel/geometry/shape/alignedbox.h"

#include <vector>

namespace Pastel
{

    class MultiQuadric_Rbf
        : public Filter
    {
    public:
        // Using default copy constructor.
        // Using default assignment.

        explicit MultiQuadric_Rbf(real beta = 1)
            : Filter((real)Infinity(), "multiquadric")
            , beta_(beta)
        {
        }

        virtual ~MultiQuadric_Rbf()
        {
        }

        virtual real evaluateInRange(real x) const
        {
            return std::sqrt(x + square(beta_));
        }

    private:
        MultiQuadric_Rbf(const MultiQuadric_Rbf& that) = delete;
        MultiQuadric_Rbf& operator=(const MultiQuadric_Rbf& that) = delete;

        real beta_;
    };

    template <typename Real, integer N, typename Data, typename Output_View>
    void reconstructRbf(
        const std::vector<Vector<Data, N> >& positionList,
        const std::vector<Data>& dataList,
        const AlignedBox<Real, N>& region,
        const FilterPtr& radialBasisFunction,
        const View<N, Data, Output_View>& view);

}

#include "pastel/sys/vector/vector_tools.h"

namespace Pastel
{

    namespace ReconstructRbf_
    {

        template <typename Real, integer N, typename Data>
        class ReconstructFunctor
        {
        public:
            explicit ReconstructFunctor(
                const std::vector<Vector<Real, N> >& positionList,
                const Vector<Real, Dynamic>& w,
                const Vector<Data, Dynamic>& b,
                const Vector<Real, N>& scaling,
                const FilterPtr& radialBasisFunction)
                : positionList_(positionList)
                , w_(w)
                , b_(b)
                , scaling_(scaling)
                , radialBasisFunction_(radialBasisFunction)
            {
            }

            void operator()(
                const Vector<integer, N>& position,
                Data& data) const
            {
                integer n = w_.size();

                Real result = 0;
                for (integer i = 0;i < n;++i)
                {

                    result += w_[i] * radialBasisFunction_->evaluate(
                        dot(((Vector<Real, N>(position) + 0.5) - positionList_[i]) * scaling_));
                }

                data = result;
            }

        private:
            const std::vector<Vector<Real, N> >& positionList_;
            const Vector<Real, Dynamic>& w_;
            const Vector<Data, Dynamic>& b_;
            Vector<Real, N> scaling_;

            const FilterPtr& radialBasisFunction_;
        };

    }

    template <typename Real, integer N, typename Data, typename Output_View>
    void reconstructRbf(
        const std::vector<Vector<Real, N> >& positionList,
        const std::vector<Data>& dataList,
        const AlignedBox<Real, N>& region,
        const FilterPtr& radialBasisFunction,
        const View<N, Data, Output_View>& view)
    {
        integer n = positionList.size();

        Matrix<Real> a(n, n);

        for (integer i = 0;i < n;++i)
        {
            a(i, i) = radialBasisFunction->evaluate(0);
        }

        Vector<Real, N> scaling = region.extent() / Vector<Real, N>(view.extent());

        for (integer i = 0;i < n;++i)
        {
            for (integer j = i + 1;j < n;++j)
            {
                Real value = 
                    radialBasisFunction->evaluate(
                    dot(positionList[j] - positionList[i]));

                a(i, j) = value;
                a(j, i) = value;
            }
        }

        Vector<Real, Dynamic> b(ofDimension(n));
        for (integer i = 0;i < n;++i)
        {
            b[i] = dataList[i];
        }

        Vector<Real, Dynamic> w = solveLinear(a, b);

        ReconstructRbf_::ReconstructFunctor<Real, N, Data>
            reconstructFunctor(positionList, w, b, scaling, radialBasisFunction);

        visitPosition(view, reconstructFunctor);
    }

}

#endif