1 | /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | |
3 | /* |
4 | Copyright (C) 2005 Joseph Wang |
5 | |
6 | This file is part of QuantLib, a free-software/open-source library |
7 | for financial quantitative analysts and developers - http://quantlib.org/ |
8 | |
9 | QuantLib is free software: you can redistribute it and/or modify it |
10 | under the terms of the QuantLib license. You should have received a |
11 | copy of the license along with this program; if not, please email |
12 | <quantlib-dev@lists.sf.net>. The license is also available online at |
13 | <http://quantlib.org/license.shtml>. |
14 | |
15 | This program is distributed in the hope that it will be useful, but WITHOUT |
16 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
17 | FOR A PARTICULAR PURPOSE. See the license for more details. |
18 | */ |
19 | |
20 | /*! \file sampledcurve.hpp |
21 | \brief a class that contains a sampled curve |
22 | */ |
23 | |
24 | #ifndef quantlib_sampled_curve_hpp |
25 | #define quantlib_sampled_curve_hpp |
26 | |
27 | #include <ql/math/array.hpp> |
28 | #include <ql/grid.hpp> |
29 | #include <ql/math/interpolations/cubicinterpolation.hpp> |
30 | |
31 | namespace QuantLib { |
32 | |
33 | /*! \deprecated Use the new finite-differences framework instead. |
34 | Deprecated in version 1.32. |
35 | */ |
36 | class [[deprecated("Use the new finite-differences framework instead" )]] SampledCurve { |
37 | public: |
38 | SampledCurve(Size gridSize = 0); |
39 | SampledCurve(const Array &grid); |
40 | |
41 | //! \name inspectors |
42 | //@{ |
43 | const Array& grid() const; |
44 | Array& grid(); |
45 | const Array& values() const; |
46 | Array& values(); |
47 | Real gridValue(Size i) const; |
48 | Real& gridValue(Size i); |
49 | Real value(Size i) const; |
50 | Real& value(Size i); |
51 | Size size() const; |
52 | bool empty() const; |
53 | //@} |
54 | |
55 | //! \name modifiers |
56 | //@{ |
57 | void setGrid(const Array&); |
58 | void setValues(const Array&); |
59 | template <class F> |
60 | void sample(const F& f) { |
61 | Array::iterator i, j; |
62 | for(i=grid_.begin(), j = values_.begin(); |
63 | i != grid_.end(); ++i, ++j) |
64 | *j = f(*i); |
65 | } |
66 | //@} |
67 | |
68 | //! \name calculations |
69 | //@{ |
70 | /*! \todo replace or complement with a more general function |
71 | valueAt(spot) |
72 | */ |
73 | Real valueAtCenter() const; |
74 | /*! \todo replace or complement with a more general function |
75 | firstDerivativeAt(spot) |
76 | */ |
77 | Real firstDerivativeAtCenter() const; |
78 | /*! \todo replace or complement with a more general function |
79 | secondDerivativeAt(spot) |
80 | */ |
81 | Real secondDerivativeAtCenter() const; |
82 | //@} |
83 | |
84 | //! \name utilities |
85 | //@{ |
86 | QL_DEPRECATED_DISABLE_WARNING |
87 | void swap(SampledCurve&) noexcept; |
88 | QL_DEPRECATED_ENABLE_WARNING |
89 | void setLogGrid(Real min, Real max) { |
90 | setGrid(BoundedLogGrid(xMin: min, xMax: max, steps: size()-1)); |
91 | } |
92 | void regridLogGrid(Real min, Real max) { |
93 | regrid(new_grid: BoundedLogGrid(xMin: min, xMax: max, steps: size() - 1), |
94 | func: [](Real x) -> Real { return std::log(x: x); }); |
95 | } |
96 | void shiftGrid(Real s) { |
97 | grid_ += s; |
98 | } |
99 | void scaleGrid(Real s) { |
100 | grid_ *= s; |
101 | } |
102 | |
103 | void regrid(const Array &new_grid); |
104 | |
105 | #if defined(__GNUC__) && (__GNUC__ >= 7) |
106 | #pragma GCC diagnostic push |
107 | #pragma GCC diagnostic ignored "-Wnoexcept-type" |
108 | #endif |
109 | |
110 | template <class T> |
111 | void regrid(const Array &new_grid, |
112 | T func) { |
113 | Array transformed_grid(grid_.size()); |
114 | |
115 | std::transform(grid_.begin(), grid_.end(), |
116 | transformed_grid.begin(), func); |
117 | CubicInterpolation priceSpline(transformed_grid.begin(), |
118 | transformed_grid.end(), |
119 | values_.begin(), |
120 | CubicInterpolation::Spline, false, |
121 | CubicInterpolation::SecondDerivative, 0.0, |
122 | CubicInterpolation::SecondDerivative, 0.0); |
123 | priceSpline.update(); |
124 | |
125 | Array newValues = new_grid; |
126 | std::transform(newValues.begin(), newValues.end(), |
127 | newValues.begin(), func); |
128 | for (Real& newValue : newValues) { |
129 | newValue = priceSpline(newValue, true); |
130 | } |
131 | values_.swap(from&: newValues); |
132 | grid_ = new_grid; |
133 | } |
134 | |
135 | #if defined(__GNUC__) && (__GNUC__ >= 7) |
136 | #pragma GCC diagnostic pop |
137 | #endif |
138 | |
139 | QL_DEPRECATED_DISABLE_WARNING |
140 | template <class T> |
141 | inline const SampledCurve& transform(T x) { |
142 | std::transform(values_.begin(), values_.end(), |
143 | values_.begin(), x); |
144 | return *this; |
145 | } |
146 | |
147 | template <class T> |
148 | inline const SampledCurve& transformGrid(T x) { |
149 | std::transform(grid_.begin(), grid_.end(), |
150 | grid_.begin(), x); |
151 | return *this; |
152 | } |
153 | QL_DEPRECATED_ENABLE_WARNING |
154 | //@} |
155 | private: |
156 | Array grid_; |
157 | Array values_; |
158 | }; |
159 | |
160 | QL_DEPRECATED_DISABLE_WARNING |
161 | |
162 | /* \relates SampledCurve */ |
163 | void swap(SampledCurve&, SampledCurve&) noexcept; |
164 | |
165 | /*! \deprecated Use the new finite-differences framework instead. |
166 | Deprecated in version 1.32. |
167 | */ |
168 | [[deprecated("Use the new finite-differences framework instead" )]] |
169 | typedef SampledCurve SampledCurveSet; |
170 | |
171 | QL_DEPRECATED_ENABLE_WARNING |
172 | |
173 | |
174 | // inline definitions |
175 | |
176 | QL_DEPRECATED_DISABLE_WARNING |
177 | |
178 | inline SampledCurve::SampledCurve(Size gridSize) |
179 | : grid_(gridSize), values_(gridSize) {} |
180 | |
181 | inline SampledCurve::SampledCurve(const Array& grid) |
182 | : grid_(grid), values_(grid.size()) {} |
183 | |
184 | inline Array& SampledCurve::grid() { |
185 | return grid_; |
186 | } |
187 | |
188 | inline const Array& SampledCurve::grid() const { |
189 | return grid_; |
190 | } |
191 | |
192 | inline const Array& SampledCurve::values() const { |
193 | return values_; |
194 | } |
195 | |
196 | inline Array& SampledCurve::values() { |
197 | return values_; |
198 | } |
199 | |
200 | inline Real SampledCurve::gridValue(Size i) const { |
201 | return grid_[i]; |
202 | } |
203 | |
204 | inline Real& SampledCurve::gridValue(Size i) { |
205 | return grid_[i]; |
206 | } |
207 | |
208 | inline Real SampledCurve::value(Size i) const { |
209 | return values_[i]; |
210 | } |
211 | |
212 | inline Real& SampledCurve::value(Size i) { |
213 | return values_[i]; |
214 | } |
215 | |
216 | inline Size SampledCurve::size() const { |
217 | return grid_.size(); |
218 | } |
219 | |
220 | inline bool SampledCurve::empty() const { |
221 | return grid_.empty(); |
222 | } |
223 | |
224 | inline void SampledCurve::setGrid(const Array &g) { |
225 | grid_ = g; |
226 | } |
227 | |
228 | inline void SampledCurve::setValues(const Array &g) { |
229 | values_ = g; |
230 | } |
231 | |
232 | inline void SampledCurve::swap(SampledCurve& from) noexcept { |
233 | grid_.swap(from&: from.grid_); |
234 | values_.swap(from&: from.values_); |
235 | } |
236 | |
237 | inline void swap(SampledCurve& c1, SampledCurve& c2) noexcept { |
238 | c1.swap(from&: c2); |
239 | } |
240 | |
241 | inline std::ostream& operator<<(std::ostream& out, |
242 | const SampledCurve& a) { |
243 | out << "[ " << a.grid() << "; " |
244 | << a.values() << " ]" ; |
245 | return out; |
246 | } |
247 | |
248 | QL_DEPRECATED_ENABLE_WARNING |
249 | |
250 | } |
251 | |
252 | |
253 | #endif |
254 | |
255 | |