QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.34
Loading...
Searching...
No Matches
interpolation.hpp
Go to the documentation of this file.
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2002, 2003 Ferdinando Ametrano
5 Copyright (C) 2000, 2001, 2002, 2003 RiskMap srl
6 Copyright (C) 2003, 2004, 2005, 2006 StatPro Italia srl
7
8 This file is part of QuantLib, a free-software/open-source library
9 for financial quantitative analysts and developers - http://quantlib.org/
10
11 QuantLib is free software: you can redistribute it and/or modify it
12 under the terms of the QuantLib license. You should have received a
13 copy of the license along with this program; if not, please email
14 <quantlib-dev@lists.sf.net>. The license is also available online at
15 <http://quantlib.org/license.shtml>.
16
17 This program is distributed in the hope that it will be useful, but WITHOUT
18 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19 FOR A PARTICULAR PURPOSE. See the license for more details.
20*/
21
22/*! \file interpolation.hpp
23 \brief base class for 1-D interpolations
24*/
25
26#ifndef quantlib_interpolation_hpp
27#define quantlib_interpolation_hpp
28
31#include <ql/errors.hpp>
32#include <vector>
33#include <algorithm>
34
35namespace QuantLib {
36
37 //! base class for 1-D interpolations.
38 /*! Classes derived from this class will provide interpolated
39 values from two sequences of equal length, representing
40 discretized values of a variable and a function of the former,
41 respectively.
42
43 \warning Interpolations don't copy their underlying data;
44 instead, they store iterators through which they
45 access them. This allow them to see changes in the
46 underlying data without having to propagate them
47 manually, but adds the requirement that the lifetime
48 of the underlying data exceeds or equals the lifetime
49 of the interpolation. It is up to the user to ensure
50 this: usually, a class will store as data members
51 both the data and the interpolation (see, e.g., the
52 InterpolatedCurve class) and call the update() method
53 on the latter when the data change.
54 */
55 class Interpolation : public Extrapolator {
56 protected:
57 //! abstract base class for interpolation implementations
58 class Impl {
59 public:
60 virtual ~Impl() = default;
61 virtual void update() = 0;
62 virtual Real xMin() const = 0;
63 virtual Real xMax() const = 0;
64 virtual std::vector<Real> xValues() const = 0;
65 virtual std::vector<Real> yValues() const = 0;
66 virtual bool isInRange(Real) const = 0;
67 virtual Real value(Real) const = 0;
68 virtual Real primitive(Real) const = 0;
69 virtual Real derivative(Real) const = 0;
70 virtual Real secondDerivative(Real) const = 0;
71 };
72 ext::shared_ptr<Impl> impl_;
73 public:
74 //! basic template implementation
75 template <class I1, class I2>
76 class templateImpl : public Impl {
77 public:
78 templateImpl(const I1& xBegin, const I1& xEnd, const I2& yBegin,
79 const int requiredPoints = 2)
80 : xBegin_(xBegin), xEnd_(xEnd), yBegin_(yBegin) {
81 QL_REQUIRE(static_cast<int>(xEnd_-xBegin_) >= requiredPoints,
82 "not enough points to interpolate: at least " <<
83 requiredPoints <<
84 " required, " << static_cast<int>(xEnd_-xBegin_)<< " provided");
85 }
86 Real xMin() const override { return *xBegin_; }
87 Real xMax() const override { return *(xEnd_ - 1); }
88 std::vector<Real> xValues() const override { return std::vector<Real>(xBegin_, xEnd_); }
89 std::vector<Real> yValues() const override {
90 return std::vector<Real>(yBegin_,yBegin_+(xEnd_-xBegin_));
91 }
92 bool isInRange(Real x) const override {
93#if defined(QL_EXTRA_SAFETY_CHECKS)
94 for (I1 i=xBegin_, j=xBegin_+1; j!=xEnd_; ++i, ++j)
95 QL_REQUIRE(*j > *i, "unsorted x values");
96 #endif
97 Real x1 = xMin(), x2 = xMax();
98 return (x >= x1 && x <= x2) || close(x,x1) || close(x,x2);
99 }
100
101 protected:
102 Size locate(Real x) const {
103 #if defined(QL_EXTRA_SAFETY_CHECKS)
104 for (I1 i=xBegin_, j=xBegin_+1; j!=xEnd_; ++i, ++j)
105 QL_REQUIRE(*j > *i, "unsorted x values");
106 #endif
107 if (x < *xBegin_)
108 return 0;
109 else if (x > *(xEnd_-1))
110 return xEnd_-xBegin_-2;
111 else
112 return std::upper_bound(xBegin_,xEnd_-1,x)-xBegin_-1;
113 }
116 };
117
118 Interpolation() = default;
119 ~Interpolation() override = default;
120 bool empty() const { return !impl_; }
121 Real operator()(Real x, bool allowExtrapolation = false) const {
122 checkRange(x,allowExtrapolation);
123 return impl_->value(x);
124 }
125 Real primitive(Real x, bool allowExtrapolation = false) const {
126 checkRange(x,allowExtrapolation);
127 return impl_->primitive(x);
128 }
129 Real derivative(Real x, bool allowExtrapolation = false) const {
130 checkRange(x,allowExtrapolation);
131 return impl_->derivative(x);
132 }
133 Real secondDerivative(Real x, bool allowExtrapolation = false) const {
134 checkRange(x,allowExtrapolation);
135 return impl_->secondDerivative(x);
136 }
137 Real xMin() const {
138 return impl_->xMin();
139 }
140 Real xMax() const {
141 return impl_->xMax();
142 }
143 bool isInRange(Real x) const {
144 return impl_->isInRange(x);
145 }
146 void update() {
147 impl_->update();
148 }
149 protected:
150 void checkRange(Real x, bool extrapolate) const {
151 QL_REQUIRE(extrapolate || allowsExtrapolation() ||
152 impl_->isInRange(x),
153 "interpolation range is ["
154 << impl_->xMin() << ", " << impl_->xMax()
155 << "]: extrapolation at " << x << " not allowed");
156 }
157 };
158
159}
160
161#endif
base class for classes possibly allowing extrapolation
bool allowsExtrapolation() const
tells whether extrapolation is enabled
abstract base class for interpolation implementations
virtual Real secondDerivative(Real) const =0
virtual Real value(Real) const =0
virtual Real xMin() const =0
virtual std::vector< Real > yValues() const =0
virtual Real xMax() const =0
virtual std::vector< Real > xValues() const =0
virtual bool isInRange(Real) const =0
virtual Real derivative(Real) const =0
virtual Real primitive(Real) const =0
basic template implementation
std::vector< Real > xValues() const override
std::vector< Real > yValues() const override
templateImpl(const I1 &xBegin, const I1 &xEnd, const I2 &yBegin, const int requiredPoints=2)
bool isInRange(Real x) const override
base class for 1-D interpolations.
Real secondDerivative(Real x, bool allowExtrapolation=false) const
Real derivative(Real x, bool allowExtrapolation=false) const
~Interpolation() override=default
ext::shared_ptr< Impl > impl_
Real operator()(Real x, bool allowExtrapolation=false) const
Real primitive(Real x, bool allowExtrapolation=false) const
void checkRange(Real x, bool extrapolate) const
bool isInRange(Real x) const
floating-point comparisons
Classes and functions for error handling.
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Definition: errors.hpp:117
class-wide extrapolation settings
QL_REAL Real
real number
Definition: types.hpp:50
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35
bool close(const Quantity &m1, const Quantity &m2, Size n)
Definition: quantity.cpp:163