Program Listing for File splinefunctions.h

Return to documentation for file (include/amici/splinefunctions.h)

#ifndef AMICI_SPLINEFUNCTIONS_H
#define AMICI_SPLINEFUNCTIONS_H

#include "amici/defines.h"

#include <vector>

#include <gsl/gsl-lite.hpp>

namespace amici {

class Model;
class AbstractSpline {
  public:
    AbstractSpline() = default;

    AbstractSpline(
        std::vector<realtype> nodes, std::vector<realtype> node_values,
        bool equidistant_spacing, bool logarithmic_parametrization
    );

    virtual ~AbstractSpline() = default;

    virtual void compute_coefficients() = 0;

    virtual void compute_coefficients_sensi(
        int nplist, int spline_offset, gsl::span<realtype> dvaluesdp,
        gsl::span<realtype> dslopesdp
    ) = 0;

    realtype get_value(realtype t) const;

    [[nodiscard]] virtual realtype get_value_scaled(realtype t) const = 0;

    [[nodiscard]] realtype get_node_value(int i) const;

    [[nodiscard]] realtype get_node_value_scaled(int i) const;

    realtype get_sensitivity(realtype t, int ip) const;

    [[nodiscard]] realtype
    get_sensitivity(realtype t, int ip, realtype value) const;

    [[nodiscard]] virtual realtype
    get_sensitivity_scaled(realtype t, int ip) const
        = 0;

    virtual void compute_final_value() = 0;

    virtual void compute_final_sensitivity(
        int nplist, int spline_offset, gsl::span<realtype> dspline_valuesdp,
        gsl::span<realtype> dspline_slopesdp
    ) = 0;

    [[nodiscard]] realtype get_final_value() const;

    [[nodiscard]] realtype get_final_value_scaled() const;

    [[nodiscard]] realtype get_final_sensitivity(int ip) const;

    [[nodiscard]] realtype get_final_sensitivity_scaled(int ip) const;

    [[nodiscard]] bool get_equidistant_spacing() const;

    [[nodiscard]] bool get_logarithmic_parametrization() const;

    [[nodiscard]] int n_nodes() const {
        return static_cast<int>(nodes_.size());
    }

  protected:
    std::vector<realtype> nodes_;

    std::vector<realtype> node_values_;

    std::vector<realtype> coefficients;

    std::vector<realtype> coefficients_extrapolate;

    std::vector<realtype> coefficients_sensi;

    std::vector<realtype> coefficients_extrapolate_sensi;

    void set_final_value_scaled(realtype finalValue);

    void set_final_sensitivity_scaled(std::vector<realtype> finalSensitivity);

  private:
    realtype final_value_scaled_;

    std::vector<realtype> final_sensitivity_scaled_;

    bool equidistant_spacing_ = false;

    bool logarithmic_parametrization_ = false;

}; // class SplineFunction

class HermiteSpline : public AbstractSpline {
  public:
    HermiteSpline() = default;

    HermiteSpline(
        std::vector<realtype> nodes, std::vector<realtype> node_values,
        std::vector<realtype> node_values_derivative,
        SplineBoundaryCondition firstNodeBC, SplineBoundaryCondition lastNodeBC,
        SplineExtrapolation firstNodeExtrapol,
        SplineExtrapolation lastNodeExtrapol, bool node_derivative_by_FD,
        bool equidistant_spacing, bool logarithmic_parametrization
    );

    void compute_coefficients() override;

    void compute_coefficients_sensi(
        int nplist, int spline_offset, gsl::span<realtype> dvaluesdp,
        gsl::span<realtype> dslopesdp
    ) override;

    void compute_final_value() override;

    void compute_final_sensitivity(
        int nplist, int spline_offset, gsl::span<realtype> dspline_valuesdp,
        gsl::span<realtype> dspline_slopesdp
    ) override;

    [[nodiscard]] realtype get_value_scaled(realtype t) const override;

    [[nodiscard]] realtype get_node_derivative(int i) const;

    [[nodiscard]] realtype get_node_derivative_scaled(int i) const;

    [[nodiscard]] realtype
    get_sensitivity_scaled(realtype t, int ip) const override;

    [[nodiscard]] bool get_node_derivative_by_fd() const {
        return node_derivative_by_FD_;
    }

  private:
    void compute_slope_sensitivities_by_fd(
        int nplist, int spline_offset, int ip, gsl::span<realtype> dvaluesdp,
        gsl::span<realtype> dslopesdp
    );

    void get_coeffs_sensi_lowlevel(
        int ip, int i_node, int nplist, int n_spline_coefficients,
        int spline_offset, realtype len, gsl::span<realtype> dnodesdp,
        gsl::span<realtype> dslopesdp, gsl::span<realtype> coeffs
    ) const;

    void handle_inner_derivatives();

    void handle_boundary_conditions();

    void compute_coefficients_extrapolation();

    void compute_coefficients_extrapolation_sensi(
        int nplist, int spline_offset, gsl::span<realtype> dspline_valuesdp,
        gsl::span<realtype> dspline_slopesdp
    );

    std::vector<realtype> node_values_derivative_;

    SplineBoundaryCondition first_node_bc_ = SplineBoundaryCondition::given;

    SplineBoundaryCondition last_node_bc_ = SplineBoundaryCondition::given;

    SplineExtrapolation first_node_ep_ = SplineExtrapolation::linear;

    SplineExtrapolation last_node_ep_ = SplineExtrapolation::linear;

    bool node_derivative_by_FD_ = false;

}; // class HermiteSpline

} // namespace amici

#endif /* AMICI_SPLINEFUNCTIONS_H */