1#ifndef LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_INTERPOLATE_IMPLEMENTATION_H_
2#define LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_INTERPOLATE_IMPLEMENTATION_H_
4#include <molpro/linalg/itsolv/Interpolate.h>
6#include <molpro/linalg/itsolv/IterativeSolver.h>
7#include <molpro/linalg/itsolv/SolverFactory-implementation.h>
8#include <molpro/linalg/itsolv/SolverFactory.h>
9#include <molpro/linalg/itsolv/helper.h>
18namespace interpolate_detail {
21template <
typename value_type>
28 (parameters[1] / 2) *
pow((1 -
exp(-parameters[2] * (
y - parameters[3]))) / parameters[2], 2);
29 result.f1 = (parameters[1] / parameters[2]) *
exp(-parameters[2] * (
y - parameters[3])) *
30 (1 -
exp(-parameters[2] * (
y - parameters[3])));
31 result.f2 = -parameters[1] * (1 - 2 *
exp(-parameters[2] * (
y - parameters[3])));
36template <
typename value_type>
38 using R = std::vector<value_type>;
61template <
typename value_type>
65 if (m_interpolant ==
"cubic") {
73 m_parameters[1] = value_type(-0.25) *
g1pg0 + value_type(1.5) *
f1mf0 /
x1mx0;
74 m_parameters[2] = value_type(0.5) *
g1mg0 /
x1mx0;
76 }
else if (m_interpolant ==
"morse") {
79 using R = std::vector<value_type>;
90 solver->set_verbosity(verbosity);
91 if (!solver->solve(m_parameters, residual, problem))
92 throw std::runtime_error(
"Cannot find Morse interpolant");
93 solver->solution(m_parameters, residual);
95 throw std::runtime_error(
"Unknown interpolant: " + m_interpolant);
98template <
typename value_type>
100 return std::vector<std::string>{
"cubic",
"morse"};
103template <
typename value_type>
105 if (m_interpolant ==
"cubic") {
106 auto xbar = value_type(0.5) * (m_p1.x + m_p0.x);
107 auto f = m_parameters[0] +
108 (x -
xbar) * (m_parameters[1] + (x -
xbar) * (m_parameters[2] + (x -
xbar) * m_parameters[3]));
109 auto f1 = m_parameters[1] + (x -
xbar) * (2 * m_parameters[2] + 3 * (x -
xbar) * m_parameters[3]);
110 auto f2 = 2 * m_parameters[2] + 6 * (x -
xbar) * m_parameters[3];
111 return point{x, f, f1, f2};
112 }
else if (m_interpolant ==
"morse") {
113 return interpolate_detail::Morse<value_type>(x, m_parameters);
115 throw std::logic_error(
"Unknown interpolant: " + m_interpolant);
118template <
typename value_type>
123 if (m_interpolant !=
"cubic")
124 throw std::logic_error(
"minimize_cubic called with non-cubic interpolant");
125 const auto c = m_parameters[1];
126 const auto b = 2 * m_parameters[2];
127 const auto a = 3 * m_parameters[3];
134 return {std::numeric_limits<value_type>::quiet_NaN()};
135 auto xbar = value_type(0.5) * (m_p1.x + m_p0.x);
138 return pm.
f < pp.f ?
pm : pp;
141template <
typename value_type>
149 if (
analytic && m_interpolant ==
"cubic")
150 return minimize_cubic();
154 auto p0 = (*this)(
xa).f > (*
this)(
xb).f ?
plow : (*this)(
xb);
164 if (p0.f1 < 0
and p1.f1 > 0) {
169 2 * std::numeric_limits<value_type>::epsilon() * std::max(value_type(1),
abs(
pnew.x));
171 pnew = (*this)((p1.x * p0.f1 - p0.x * p1.f1) / (p0.f1 - p1.f1));
172 if (
pnew.f1 * p0.f1 < 0)
180 return (*
this)(
xa).f > (*
this)(
xb).f ? (*
this)(
xb) : (*this)(
xa);
The interpolant, in the precision of the problem it is used for.
Definition Interpolate.h:31
point minimize(value_type xa, value_type xb, size_t bracket_grid=100, size_t max_bracket_grid=100000, bool analytic=true) const
Find the minimum of the interpolant within a range.
Definition Interpolate-implementation.h:142
point operator()(value_type x) const
Evaluate the interpolant and its derivative at a given point.
Definition Interpolate-implementation.h:104
point minimize_cubic() const
Definition Interpolate-implementation.h:119
Interpolator(point p0, point p1, std::string interpolant="cubic", int verbosity=0)
Construct the interpolant.
Definition Interpolate-implementation.h:62
static std::vector< std::string > interpolants()
Definition Interpolate-implementation.h:99
Abstract class defining the problem-specific interface for the simplified solver interface to Iterati...
Definition IterativeSolver.h:85
typename R::value_type value_t
Definition IterativeSolver.h:91
Fits the four Morse parameters to the two defining points.
Definition Interpolate-implementation.h:37
Morse_problem(point p0, point p1)
Definition Interpolate-implementation.h:43
Problem< R >::value_t residual(const R ¶meters, R &residual) const override
Calculate the residual vector. Used by non-linear solvers (NonLinearEquations, Optimize) only.
Definition Interpolate-implementation.h:48
Interpolator< value_type >::point Morse(value_type y, const std::vector< value_type > ¶meters)
The Morse interpolant and its first two derivatives at y.
Definition Interpolate-implementation.h:22
4-parameter interpolation of a 1-dimensional function given two points for which function values and ...
Definition helper.h:14
std::unique_ptr< LinearEigensystem< R, Q, P > > create_LinearEigensystem(const LinearEigensystemOptions &options, const std::shared_ptr< ArrayHandlers< R, Q, P > > &handlers=std::make_shared< molpro::linalg::itsolv::ArrayHandlers< R, Q, P > >())
Definition SolverFactory.h:111
Definition Interpolate.h:39
value_type f
Definition Interpolate.h:41
value_type f1
Definition Interpolate.h:42
value_type x
Definition Interpolate.h:40