QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.34
Loading...
Searching...
No Matches
interpolation2d.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, 2006 Ferdinando Ametrano
5 Copyright (C) 2004, 2005, 2006, 2007 StatPro Italia srl
6
7 This file is part of QuantLib, a free-software/open-source library
8 for financial quantitative analysts and developers - http://quantlib.org/
9
10 QuantLib is free software: you can redistribute it and/or modify it
11 under the terms of the QuantLib license. You should have received a
12 copy of the license along with this program; if not, please email
13 <quantlib-dev@lists.sf.net>. The license is also available online at
14 <http://quantlib.org/license.shtml>.
15
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the license for more details.
19*/
20
21/*! \file interpolation2d.hpp
22 \brief abstract base classes for 2-D interpolations
23*/
24
25#ifndef quantlib_interpolation2D_hpp
26#define quantlib_interpolation2D_hpp
27
30#include <ql/math/matrix.hpp>
31#include <ql/errors.hpp>
32#include <ql/types.hpp>
33#include <vector>
34
35namespace QuantLib {
36
37 //! base class for 2-D interpolations.
38 /*! Classes derived from this class will provide interpolated
39 values from two sequences of length \f$ N \f$ and \f$ M \f$,
40 representing the discretized values of the \f$ x \f$ and \f$ y
41 \f$ variables, and a \f$ N \times M \f$ matrix representing
42 the tabulated function values.
43
44 \warning See the Interpolation class for information about the
45 required lifetime of the underlying data.
46 */
48 protected:
49 //! abstract base class for 2-D interpolation implementations
50 class Impl {
51 public:
52 virtual ~Impl() = default;
53 virtual void calculate() = 0;
54 virtual Real xMin() const = 0;
55 virtual Real xMax() const = 0;
56 virtual std::vector<Real> xValues() const = 0;
57 virtual Size locateX(Real x) const = 0;
58 virtual Real yMin() const = 0;
59 virtual Real yMax() const = 0;
60 virtual std::vector<Real> yValues() const = 0;
61 virtual Size locateY(Real y) const = 0;
62 virtual const Matrix& zData() const = 0;
63 virtual bool isInRange(Real x, Real y) const = 0;
64 virtual Real value(Real x, Real y) const = 0;
65 };
66 ext::shared_ptr<Impl> impl_;
67 public:
68 //! basic template implementation
69 template <class I1, class I2, class M>
70 class templateImpl : public Impl {
71 public:
72 templateImpl(const I1& xBegin, const I1& xEnd,
73 const I2& yBegin, const I2& yEnd,
74 const M& zData)
75 : xBegin_(xBegin), xEnd_(xEnd), yBegin_(yBegin), yEnd_(yEnd),
76 zData_(zData) {
78 "not enough x points to interpolate: at least 2 "
79 "required, " << xEnd_-xBegin_ << " provided");
81 "not enough y points to interpolate: at least 2 "
82 "required, " << yEnd_-yBegin_ << " provided");
83 }
84 Real xMin() const override { return *xBegin_; }
85 Real xMax() const override { return *(xEnd_ - 1); }
86 std::vector<Real> xValues() const override { return std::vector<Real>(xBegin_, xEnd_); }
87 Real yMin() const override { return *yBegin_; }
88 Real yMax() const override { return *(yEnd_ - 1); }
89 std::vector<Real> yValues() const override { return std::vector<Real>(yBegin_, yEnd_); }
90 const Matrix& zData() const override { return zData_; }
91 bool isInRange(Real x, Real y) const override {
92#if defined(QL_EXTRA_SAFETY_CHECKS)
93 for (I1 i=xBegin_, j=xBegin_+1; j!=xEnd_; ++i, ++j)
94 QL_REQUIRE(*j > *i, "unsorted x values");
95 #endif
96 Real x1 = xMin(), x2 = xMax();
97 bool xIsInrange = (x >= x1 && x <= x2) ||
98 close(x,x1) ||
99 close(x,x2);
100 if (!xIsInrange) return false;
101
102 #if defined(QL_EXTRA_SAFETY_CHECKS)
103 for (I2 k=yBegin_, l=yBegin_+1; l!=yEnd_; ++k, ++l)
104 QL_REQUIRE(*l > *k, "unsorted y values");
105 #endif
106 Real y1 = yMin(), y2 = yMax();
107 return (y >= y1 && y <= y2) || close(y,y1) || close(y,y2);
108 }
109
110 protected:
111 Size locateX(Real x) const override {
112#if defined(QL_EXTRA_SAFETY_CHECKS)
113 for (I1 i=xBegin_, j=xBegin_+1; j!=xEnd_; ++i, ++j)
114 QL_REQUIRE(*j > *i, "unsorted x values");
115 #endif
116 if (x < *xBegin_)
117 return 0;
118 else if (x > *(xEnd_-1))
119 return xEnd_-xBegin_-2;
120 else
121 return std::upper_bound(xBegin_,xEnd_-1,x)-xBegin_-1;
122 }
123 Size locateY(Real y) const override {
124#if defined(QL_EXTRA_SAFETY_CHECKS)
125 for (I2 k=yBegin_, l=yBegin_+1; l!=yEnd_; ++k, ++l)
126 QL_REQUIRE(*l > *k, "unsorted y values");
127 #endif
128 if (y < *yBegin_)
129 return 0;
130 else if (y > *(yEnd_-1))
131 return yEnd_-yBegin_-2;
132 else
133 return std::upper_bound(yBegin_,yEnd_-1,y)-yBegin_-1;
134 }
137 const M& zData_;
138 };
139
140 Interpolation2D() = default;
142 bool allowExtrapolation = false) const {
143 checkRange(x,y,allowExtrapolation);
144 return impl_->value(x,y);
145 }
146 Real xMin() const {
147 return impl_->xMin();
148 }
149 Real xMax() const {
150 return impl_->xMax();
151 }
152 std::vector<Real> xValues() const {
153 return impl_->xValues();
154 }
155 Size locateX(Real x) const {
156 return impl_->locateX(x);
157 }
158 Real yMin() const {
159 return impl_->yMin();
160 }
161 Real yMax() const {
162 return impl_->yMax();
163 }
164 std::vector<Real> yValues() const {
165 return impl_->yValues();
166 }
168 return impl_->locateY(y);
169 }
170 const Matrix& zData() const {
171 return impl_->zData();
172 }
173 bool isInRange(Real x, Real y) const {
174 return impl_->isInRange(x,y);
175 }
176 void update() {
177 impl_->calculate();
178 }
179 protected:
180 void checkRange(Real x, Real y, bool extrapolate) const {
181 QL_REQUIRE(extrapolate || allowsExtrapolation() ||
182 impl_->isInRange(x,y),
183 "interpolation range is ["
184 << impl_->xMin() << ", " << impl_->xMax()
185 << "] x ["
186 << impl_->yMin() << ", " << impl_->yMax()
187 << "]: extrapolation at ("
188 << x << ", " << y << ") not allowed");
189 }
190 };
191
192}
193
194
195#endif
base class for classes possibly allowing extrapolation
bool allowsExtrapolation() const
tells whether extrapolation is enabled
abstract base class for 2-D interpolation implementations
virtual Size locateX(Real x) const =0
virtual const Matrix & zData() const =0
virtual bool isInRange(Real x, Real y) const =0
virtual Real yMin() const =0
virtual Size locateY(Real y) const =0
virtual Real xMin() const =0
virtual std::vector< Real > yValues() const =0
virtual Real value(Real x, Real y) const =0
virtual Real xMax() const =0
virtual std::vector< Real > xValues() const =0
virtual Real yMax() const =0
basic template implementation
const Matrix & zData() const override
templateImpl(const I1 &xBegin, const I1 &xEnd, const I2 &yBegin, const I2 &yEnd, const M &zData)
std::vector< Real > xValues() const override
std::vector< Real > yValues() const override
bool isInRange(Real x, Real y) const override
base class for 2-D interpolations.
std::vector< Real > xValues() const
void checkRange(Real x, Real y, bool extrapolate) const
std::vector< Real > yValues() const
bool isInRange(Real x, Real y) const
const Matrix & zData() const
Size locateY(Real y) const
Size locateX(Real x) const
ext::shared_ptr< Impl > impl_
Real operator()(Real x, Real y, bool allowExtrapolation=false) const
Matrix used in linear algebra.
Definition: matrix.hpp:41
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
matrix used in linear algebra.
Definition: any.hpp:35
bool close(const Quantity &m1, const Quantity &m2, Size n)
Definition: quantity.cpp:163
Custom types.