Program Listing for File CRSSTDistance.h
↰ Return to documentation for file (include/gwmodelpp/spatialweight/CRSSTDistance.h)
#ifndef CRSSTDISTANCE_H
#define CRSSTDISTANCE_H
#include "CRSDistance.h"
#include "OneDimDistance.h"
#include <math.h>
namespace gwm
{
class CRSSTDistance : public Distance
{
public:
typedef arma::vec (*CalculatorType)(const std::unique_ptr<Distance>&, const std::unique_ptr<OneDimDistance>&, arma::uword, double, double);
static arma::vec OrthogonalSTDistance(const std::unique_ptr<Distance>& spatial, const std::unique_ptr<OneDimDistance>& temporal, arma::uword focus, double lambda, double angle);
static arma::vec ObliqueSTDistance(const std::unique_ptr<Distance>& spatial, const std::unique_ptr<OneDimDistance>& temporal, arma::uword focus, double lambda, double angle);
public:
CRSSTDistance() :
mSpatialDistance(nullptr),
mTemporalDistance(nullptr),
mLambda(0.0),
mAngle(arma::datum::pi / 2.0)
{
mCalculator = &OrthogonalSTDistance;
};
explicit CRSSTDistance(const Distance& spatialDistance, const OneDimDistance& temporalDistance, double lambda):
mSpatialDistance(spatialDistance.clone()),
mTemporalDistance(static_cast<OneDimDistance*>(temporalDistance.clone().release())),
mLambda(lambda),
mAngle(arma::datum::pi / 2.0),
mCalculator(&OrthogonalSTDistance)
{}
explicit CRSSTDistance(const Distance& spatialDistance, const OneDimDistance& temporalDistance, double lambda, double angle):
CRSSTDistance(spatialDistance, temporalDistance, lambda)
{
mAngle = atan(tan(angle)),
mCalculator = (abs(mAngle - arma::datum::pi / 2.0) < 1e-15) ? &OrthogonalSTDistance : &ObliqueSTDistance;
}
explicit CRSSTDistance(Distance&& spatialDistance, OneDimDistance&& temporalDistance, double lambda):
mSpatialDistance(spatialDistance.clone()),
mTemporalDistance(static_cast<OneDimDistance*>(temporalDistance.clone().release())),
mLambda(lambda),
mAngle(arma::datum::pi / 2.0),
mCalculator(&OrthogonalSTDistance)
{}
explicit CRSSTDistance(Distance&& spatialDistance, OneDimDistance&& temporalDistance, double lambda, double angle):
CRSSTDistance(spatialDistance, temporalDistance, lambda)
{
mAngle = atan(tan(angle)),
mCalculator = (abs(mAngle - arma::datum::pi / 2.0) < 1e-15) ? &OrthogonalSTDistance : &ObliqueSTDistance;
}
explicit CRSSTDistance(const std::unique_ptr<Distance>& spatialDistance, const std::unique_ptr<OneDimDistance>& temporalDistance, double lambda):
mSpatialDistance(spatialDistance->clone()),
mTemporalDistance(static_cast<OneDimDistance*>(temporalDistance->clone().release())),
mLambda(lambda),
mAngle(arma::datum::pi / 2.0),
mCalculator(&OrthogonalSTDistance)
{}
explicit CRSSTDistance(const std::unique_ptr<Distance>& spatialDistance, const std::unique_ptr<OneDimDistance>& temporalDistance, double lambda, double angle):
CRSSTDistance(spatialDistance, temporalDistance, lambda)
{
mAngle = atan(tan(angle)),
mCalculator = (abs(mAngle - arma::datum::pi / 2.0) < 1e-15) ? &OrthogonalSTDistance : &ObliqueSTDistance;
}
explicit CRSSTDistance(std::unique_ptr<Distance>&& spatialDistance, std::unique_ptr<OneDimDistance>&& temporalDistance, double lambda):
mSpatialDistance(std::move(spatialDistance)),
mTemporalDistance(std::move(temporalDistance)),
mLambda(lambda),
mAngle(arma::datum::pi / 2.0),
mCalculator(&OrthogonalSTDistance)
{}
explicit CRSSTDistance(std::unique_ptr<Distance>&& spatialDistance, std::unique_ptr<OneDimDistance>&& temporalDistance, double lambda, double angle):
CRSSTDistance(std::move(spatialDistance), std::move(temporalDistance), lambda)
{
mAngle = atan(tan(angle)),
mCalculator = (abs(mAngle - arma::datum::pi / 2.0) < 1e-15) ? &OrthogonalSTDistance : &ObliqueSTDistance;
}
CRSSTDistance(const CRSSTDistance& distance):
mSpatialDistance(distance.mSpatialDistance->clone()),
mTemporalDistance(static_cast<OneDimDistance*>(distance.mTemporalDistance->clone().release())),
mAngle(distance.mAngle),
mCalculator(distance.mCalculator)
{
if (distance.mLambda >= 0 && distance.mLambda <= 1)
{
mLambda = distance.mLambda;
}
else throw std::runtime_error("The lambda must be in [0,1].");
}
std::unique_ptr<Distance> clone() const override
{
return std::make_unique<CRSSTDistance>(*this);
}
DistanceType type() override { return DistanceType::CRSSTDistance; }
void makeParameter(std::initializer_list<DistParamVariant> plist) override;
arma::vec distance(arma::uword focus) override
{
return mCalculator(mSpatialDistance, mTemporalDistance, focus, mLambda, mAngle);
}
double minDistance() override;
double maxDistance() override;
public:
//const gwm::CRSDistance* spatialDistance() const { return mSpatialDistance; }
const std::unique_ptr<Distance>& spatialDistance() const { return mSpatialDistance; }
const std::unique_ptr<OneDimDistance>& temporalDistance() const { return mTemporalDistance; }
// unused code to set lambda
const double lambda(){ return mLambda; }
void setLambda(const double lambda) {
if (lambda >= 0 && lambda <= 1)
{
mLambda = lambda;
}
else
throw std::runtime_error("The lambda must be in [0,1].");
}
const double angle() { return mAngle; }
void setAngle(const double angle) {
mAngle = angle;
}
protected:
std::unique_ptr<Distance> mSpatialDistance = nullptr;
std::unique_ptr<OneDimDistance> mTemporalDistance = nullptr;
double mLambda = 0.0;
double mAngle = arma::datum::pi / 2;
private:
std::unique_ptr<Parameter> mParameter;
CalculatorType mCalculator = &OrthogonalSTDistance;
};
}
#endif // CRSSTDISTANCE_H