8 #ifndef IMPSCORE_FUNCTOR_OPEN_CUBIC_SPLINE_H
9 #define IMPSCORE_FUNCTOR_OPEN_CUBIC_SPLINE_H
11 #include <IMP/score_functor/score_functor_config.h>
13 #include "internal/RawOpenCubicSpline.h"
14 IMPSCOREFUNCTOR_BEGIN_NAMESPACE
25 double inverse_spacing_;
26 internal::RawOpenCubicSpline spline_;
39 Float spacing,
bool extend=
false) :
40 spacing_(spacing), inverse_spacing_(1.0/spacing_),
41 spline_(values, spacing_, inverse_spacing_),
42 minrange_(minrange), maxrange_(minrange_ + spacing_ * (values.size() - 1)),
45 IMP_USAGE_CHECK(spacing >0,
"The spacing between values must be positive.");
46 IMP_USAGE_CHECK(values.size() >=1,
"You must provide at least one value.");
49 template <
unsigned int D>
51 double distance)
const {
53 if (distance < minrange_ || distance > maxrange_) {
55 if (distance < minrange_)
return spline_.get_first();
56 else return spline_.get_last();
58 IMP_THROW(
"Spline out of domain", ModelException);
61 return spline_.evaluate(distance-minrange_, spacing_, inverse_spacing_);
63 template <
unsigned int D>
65 const base::Array<D, ParticleIndex>&,
66 double distance)
const {
68 if (distance < minrange_ || distance > maxrange_) {
70 if (distance < minrange_)
return std::make_pair(spline_.get_first(),
72 else return std::make_pair(spline_.get_last(), 0.0);
74 IMP_THROW(
"Spline out of domain", ModelException);
77 return spline_.evaluate_with_derivative(distance-minrange_, spacing_,
80 template <
unsigned int D>
81 double get_maximum_range(
Model *,
82 const base::Array<D, ParticleIndex>& )
const {
83 if (!extend_ || spline_.get_last()==0)
return maxrange_;
84 else return std::numeric_limits<double>::max();
86 template <
unsigned int D>
87 bool get_is_trivially_zero(
Model *,
88 const base::Array<D, ParticleIndex>& ,
89 double squared_distance)
const {
90 if (!extend_ || spline_.get_last()==0) {
91 return squared_distance > algebra::get_squared(maxrange_);
96 IMPSCOREFUNCTOR_END_NAMESPACE