21 #ifndef quantext_quadratic_interpolation_hpp
22 #define quantext_quadratic_interpolation_hpp
24 #include <ql/math/interpolation.hpp>
25 #include <ql/math/matrix.hpp>
32 template<
class I1,
class I2>
class QuadraticInterpolationImpl;
43 template <
class I1,
class I2>
46 Real x_mul = 1, Real x_offset = 0,
47 Real y_mul = 1, Real y_offset = 0,
49 impl_ = ext::shared_ptr<Interpolation::Impl>(
new
51 xBegin + skip, xEnd, yBegin + skip,
52 x_mul, x_offset, y_mul, y_offset));
55 template <
class I1,
class I2>
57 ext::shared_ptr<detail::QuadraticInterpolationImpl<I1,I2> > p =
58 ext::dynamic_pointer_cast<
60 QL_REQUIRE(p,
"unable to cast impl to "
61 "QuadraticInterpolationImpl<I1,I2>");
71 Real y_mul = 1, Real y_offset = 0,
76 template <
class I1,
class I2>
78 const I2& yBegin)
const {
83 template <
class I1,
class I2>
85 const I1& xBegin,
const I1& xEnd,
86 const I2& yBegin)
const {
87 return QuantLib::ext::make_shared<QuadraticInterpolation>(
102 template <
class I1,
class I2>
104 :
public Interpolation::templateImpl<I1,I2> {
112 : Interpolation::templateImpl<I1,I2>(xBegin, xEnd, yBegin,
114 n_(static_cast<int>(xEnd-xBegin)),
117 x_(std::vector<Real>(
n_)),
118 y_(std::vector<Real>(
n_+1)),
125 for(Size i=0; i <
n_; ++i) {
134 for(Size i=0; i <
n_; ++i) {
135 if(
x_[i] <= 0 || QuantLib::close_enough(
y_[i], 0.0)) {
141 Matrix q(
n_+1,
n_+1, 0.0);
142 for(Size i=0; i<
n_; ++i) {
143 q[i][0] = q[
n_][i+1] =
x_[i];
145 for(Size j=0; j<i; ++j) {
146 q[i][j+1] += std::pow(
x_[i] -
x_[j], 3) / 6.0;
148 Time t = -std::pow(
x_[i], 3) / 6.0;
149 for(Size j=1; j<
n_+1; ++j) {
153 Matrix q_inv = QuantLib::inverse(q);
154 Array l(
y_.begin(),
y_.end());
156 Array lambdaArray = q_inv * l;
157 lambdas_ = std::vector<Real>(lambdaArray.begin(),
161 for(Size i=1; i <
n_+1; ++i) {
162 p_ += lambdaArray[i];
166 QL_REQUIRE(
p_ != Null<Real>(),
"failed to calibrate lambda");
170 for (Size i=0; i<
n_ &&
x_[i]<x; ++i) {
173 l += (b -
p_ * std::pow(x, 3)) / 6.0;
177 QL_FAIL(
"QuadraticInterpolation primitive is not implemented");
180 QL_REQUIRE(
p_ != 0.0,
"failed to calibrate lambda");
184 for (Size i=0; i<
n_ &&
x_[i]<x; ++i) {
187 l += (b -
p_ * std::pow(x, 2)) / 2.0;
191 QL_REQUIRE(
p_ != 0.0,
"failed to calibrate lambda");
195 for (Size i=0; i<
n_ &&
x_[i]<x; ++i) {
208 std::vector<Real>
x_;
209 std::vector<Real>
y_;
Quadratic-interpolation factory and traits
Quadratic(Real x_mul=1, Real x_offset=0, Real y_mul=1, Real y_offset=0, Size skip=0)
static const Size requiredPoints
QuantLib::ext::shared_ptr< QuadraticInterpolation > interpolatePtr(const I1 &xBegin, const I1 &xEnd, const I2 &yBegin) const
Interpolation interpolate(const I1 &xBegin, const I1 &xEnd, const I2 &yBegin) const
Quadratic interpolation between discrete points
std::vector< Real > lambdas() const
QuadraticInterpolation(const I1 &xBegin, const I1 &xEnd, const I2 &yBegin, Real x_mul=1, Real x_offset=0, Real y_mul=1, Real y_offset=0, Size skip=0)
QuadraticInterpolationImpl(const I1 &xBegin, const I1 &xEnd, const I2 &yBegin, Real x_mul=1, Real x_offset=0, Real y_mul=1, Real y_offset=0)
std::vector< Real > lambdas_
Real value(Real x) const override
Real derivative(Real x) const override
std::vector< Real > lambdas() const
Real primitive(Real x) const override
Real secondDerivative(Real x) const override