Program Listing for File BandwidthWeight.h

Return to documentation for file (include/gwmodelpp/spatialweight/BandwidthWeight.h)

#ifndef BANDWIDTHWEIGHT_H
#define BANDWIDTHWEIGHT_H

#include <unordered_map>
#include <string>
#include "Weight.h"

#ifdef ENABLE_CUDA
#include "gwmodelpp/utils/CudaUtils.h"
#include "gwmodelpp/spatialweight/cuda/BandwidthWeightKernel.h"
#endif // ENABLE_CUDA

namespace gwm
{

class BandwidthWeight : public Weight
{
public:

    enum KernelFunctionType
    {
        Gaussian,
        Exponential,
        Bisquare,
        Tricube,
        Boxcar
    };
    static std::unordered_map<KernelFunctionType, std::string> KernelFunctionTypeNameMapper;
    static std::unordered_map<bool, std::string> BandwidthTypeNameMapper;

    typedef arma::vec (*KernelFunction)(arma::vec, double);

    static KernelFunction Kernel[];

    static arma::vec GaussianKernelFunction(arma::vec dist, double bw)
    {
        return exp((dist % dist) / ((-2.0) * (bw * bw)));
    }

    static arma::vec ExponentialKernelFunction(arma::vec dist, double bw)
    {
        return exp(-dist / bw);
    }

    static arma::vec BisquareKernelFunction(arma::vec dist, double bw)
    {
        arma::vec d2_d_b2 = 1.0 - (dist % dist) / (bw * bw);
        return (dist < bw) % (d2_d_b2 % d2_d_b2);
    }

    static arma::vec TricubeKernelFunction(arma::vec dist, double bw)
    {
        arma::vec d3_d_b3 = 1.0 - (dist % dist % dist) / (bw * bw * bw);
        return (dist < bw) % (d3_d_b3 % d3_d_b3 % d3_d_b3);
    }

    static arma::vec BoxcarKernelFunction(arma::vec dist, double bw)
    {
        return (dist < bw) % arma::vec(arma::size(dist), arma::fill::ones);
    }

public:

    BandwidthWeight() {}

    BandwidthWeight(double size, bool adaptive, KernelFunctionType kernel)
    {
        mBandwidth = size;
        mAdaptive = adaptive;
        mKernel = kernel;
    }

    BandwidthWeight(const BandwidthWeight& bandwidthWeight) : Weight(bandwidthWeight)
    {
        mBandwidth = bandwidthWeight.mBandwidth;
        mAdaptive = bandwidthWeight.mAdaptive;
        mKernel = bandwidthWeight.mKernel;
#ifdef ENABLE_CUDA
        mUseCuda = bandwidthWeight.mUseCuda;
        if (mUseCuda)
        {
            prepareCuda(bandwidthWeight.mGpuID);
        }
#endif // ENABLE_CUDA
    }

    BandwidthWeight(const BandwidthWeight* bandwidthWeight)
    {
        mBandwidth = bandwidthWeight->bandwidth();
        mAdaptive = bandwidthWeight->adaptive();
        mKernel = bandwidthWeight->kernel();
    }

    virtual Weight * clone() const override
    {
        return new BandwidthWeight(*this);
    }

public:
    virtual arma::vec weight(arma::vec dist) override;

#ifdef ENABLE_CUDA
    virtual cudaError_t weight(double* d_dists, double* d_weights, size_t elems) override;
#endif // ENABLE_CUDA

    double bandwidth() const
    {
        return mBandwidth;
    }

    void setBandwidth(double bandwidth)
    {
        mBandwidth = bandwidth;
    }

    bool adaptive() const
    {
        return mAdaptive;
    }

    void setAdaptive(bool adaptive)
    {
        mAdaptive = adaptive;
    }

    KernelFunctionType kernel() const
    {
        return mKernel;
    }

    void setKernel(const KernelFunctionType &kernel)
    {
        mKernel = kernel;
    }

#ifdef ENABLE_CUDA
    cudaError_t prepareCuda(size_t gpuId) override
    {
        checkCudaErrors(Weight::prepareCuda(gpuId));
        mCudaPrepared = true;
        return cudaSuccess;
    }
#endif // ENABLE_CUDA

private:
    double mBandwidth;
    bool mAdaptive;
    KernelFunctionType mKernel;
};

}

#endif // BANDWIDTHWEIGHT_H