QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
interpolation2d.hpp
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
25#ifndef quantlib_interpolation2D_hpp
26#define quantlib_interpolation2D_hpp
27
28#include <ql/math/interpolations/extrapolation.hpp>
29#include <ql/math/comparison.hpp>
30#include <ql/math/matrix.hpp>
31#include <ql/errors.hpp>
32#include <ql/types.hpp>
33#include <vector>
34
35namespace QuantLib {
36
38
48 protected:
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:
71 QL_DEPRECATED
73
77 QL_DEPRECATED
79
83 QL_DEPRECATED
86 template <class I1, class I2, class M>
87 class templateImpl : public Impl {
88 public:
89 templateImpl(const I1& xBegin, const I1& xEnd,
90 const I2& yBegin, const I2& yEnd,
91 const M& zData)
92 : xBegin_(xBegin), xEnd_(xEnd), yBegin_(yBegin), yEnd_(yEnd),
93 zData_(zData) {
94 QL_REQUIRE(xEnd_-xBegin_ >= 2,
95 "not enough x points to interpolate: at least 2 "
96 "required, " << xEnd_-xBegin_ << " provided");
97 QL_REQUIRE(yEnd_-yBegin_ >= 2,
98 "not enough y points to interpolate: at least 2 "
99 "required, " << yEnd_-yBegin_ << " provided");
100 }
101 Real xMin() const override { return *xBegin_; }
102 Real xMax() const override { return *(xEnd_ - 1); }
103 std::vector<Real> xValues() const override { return std::vector<Real>(xBegin_, xEnd_); }
104 Real yMin() const override { return *yBegin_; }
105 Real yMax() const override { return *(yEnd_ - 1); }
106 std::vector<Real> yValues() const override { return std::vector<Real>(yBegin_, yEnd_); }
107 const Matrix& zData() const override { return zData_; }
108 bool isInRange(Real x, Real y) const override {
109#if defined(QL_EXTRA_SAFETY_CHECKS)
110 for (I1 i=xBegin_, j=xBegin_+1; j!=xEnd_; ++i, ++j)
111 QL_REQUIRE(*j > *i, "unsorted x values");
112 #endif
113 Real x1 = xMin(), x2 = xMax();
114 bool xIsInrange = (x >= x1 && x <= x2) ||
115 close(x,x1) ||
116 close(x,x2);
117 if (!xIsInrange) return false;
118
119 #if defined(QL_EXTRA_SAFETY_CHECKS)
120 for (I2 k=yBegin_, l=yBegin_+1; l!=yEnd_; ++k, ++l)
121 QL_REQUIRE(*l > *k, "unsorted y values");
122 #endif
123 Real y1 = yMin(), y2 = yMax();
124 return (y >= y1 && y <= y2) || close(y,y1) || close(y,y2);
125 }
126
127 protected:
128 Size locateX(Real x) const override {
129#if defined(QL_EXTRA_SAFETY_CHECKS)
130 for (I1 i=xBegin_, j=xBegin_+1; j!=xEnd_; ++i, ++j)
131 QL_REQUIRE(*j > *i, "unsorted x values");
132 #endif
133 if (x < *xBegin_)
134 return 0;
135 else if (x > *(xEnd_-1))
136 return xEnd_-xBegin_-2;
137 else
138 return std::upper_bound(xBegin_,xEnd_-1,x)-xBegin_-1;
139 }
140 Size locateY(Real y) const override {
141#if defined(QL_EXTRA_SAFETY_CHECKS)
142 for (I2 k=yBegin_, l=yBegin_+1; l!=yEnd_; ++k, ++l)
143 QL_REQUIRE(*l > *k, "unsorted y values");
144 #endif
145 if (y < *yBegin_)
146 return 0;
147 else if (y > *(yEnd_-1))
148 return yEnd_-yBegin_-2;
149 else
150 return std::upper_bound(yBegin_,yEnd_-1,y)-yBegin_-1;
151 }
154 const M& zData_;
155 };
156
157 Interpolation2D() = default;
159 bool allowExtrapolation = false) const {
160 checkRange(x,y,allowExtrapolation);
161 return impl_->value(x,y);
162 }
163 Real xMin() const {
164 return impl_->xMin();
165 }
166 Real xMax() const {
167 return impl_->xMax();
168 }
169 std::vector<Real> xValues() const {
170 return impl_->xValues();
171 }
172 Size locateX(Real x) const {
173 return impl_->locateX(x);
174 }
175 Real yMin() const {
176 return impl_->yMin();
177 }
178 Real yMax() const {
179 return impl_->yMax();
180 }
181 std::vector<Real> yValues() const {
182 return impl_->yValues();
183 }
184 Size locateY(Real y) const {
185 return impl_->locateY(y);
186 }
187 const Matrix& zData() const {
188 return impl_->zData();
189 }
190 bool isInRange(Real x, Real y) const {
191 return impl_->isInRange(x,y);
192 }
193 void update() {
194 impl_->calculate();
195 }
196 protected:
197 void checkRange(Real x, Real y, bool extrapolate) const {
198 QL_REQUIRE(extrapolate || allowsExtrapolation() ||
199 impl_->isInRange(x,y),
200 "interpolation range is ["
201 << impl_->xMin() << ", " << impl_->xMax()
202 << "] x ["
203 << impl_->yMin() << ", " << impl_->yMax()
204 << "]: extrapolation at ("
205 << x << ", " << y << ") not allowed");
206 }
207 };
208
209}
210
211
212#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
QL_DEPRECATED typedef Real second_argument_type
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
QL_DEPRECATED typedef Real first_argument_type
QL_DEPRECATED typedef Real result_type
ext::shared_ptr< Impl > impl_
Real operator()(Real x, Real y, bool allowExtrapolation=false) const
Matrix used in linear algebra.
Definition: matrix.hpp:41
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