• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lballabio / QuantLib / 18929013373

30 Oct 2025 03:34AM UTC coverage: 74.296% (-0.005%) from 74.301%
18929013373

Pull #2363

github

web-flow
Merge 0c573071c into d823f4ecb
Pull Request #2363: Simplify LogInterpolationImpl and MixedInterpolationImpl

1 of 2 new or added lines in 2 files covered. (50.0%)

3 existing lines in 2 files now uncovered.

56997 of 76716 relevant lines covered (74.3%)

8846170.07 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

84.09
/ql/math/interpolations/loginterpolation.hpp
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2

3
/*
4
 Copyright (C) 2002, 2003, 2008, 2009 Ferdinando Ametrano
5
 Copyright (C) 2004, 2007, 2008 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
 <https://www.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 loginterpolation.hpp
22
    \brief log-linear and log-cubic interpolation between discrete points
23
*/
24

25
#ifndef quantlib_log_interpolation_hpp
26
#define quantlib_log_interpolation_hpp
27

28
#include <ql/math/interpolations/linearinterpolation.hpp>
29
#include <ql/math/interpolations/cubicinterpolation.hpp>
30
#include <ql/math/interpolations/mixedinterpolation.hpp>
31
#include <ql/utilities/dataformatters.hpp>
32

33
namespace QuantLib {
34

35
    namespace detail {
36
        template <class I1, class I2> class LogInterpolationImpl;
37
    }
38

39
    //! %log-linear interpolation between discrete points
40
    /*! \ingroup interpolations
41
        \warning See the Interpolation class for information about the
42
                 required lifetime of the underlying data.
43
    */
44
    class LogLinearInterpolation : public Interpolation {
1,758✔
45
      public:
46
        /*! \pre the \f$ x \f$ values must be sorted. */
47
        template <class I1, class I2>
48
        LogLinearInterpolation(const I1& xBegin, const I1& xEnd,
1,758✔
49
                               const I2& yBegin) {
1,758✔
50
            impl_ = ext::shared_ptr<Interpolation::Impl>(new
1,758✔
51
                detail::LogInterpolationImpl<I1, I2>(xBegin, xEnd, yBegin,
NEW
52
                                                     Linear()));
×
53
            impl_->update();
1,758✔
54
        }
1,758✔
55
    };
56

57
    //! log-linear interpolation factory and traits
58
    /*! \ingroup interpolations */
59
    class LogLinear {
60
      public:
61
        template <class I1, class I2>
62
        Interpolation interpolate(const I1& xBegin, const I1& xEnd,
1,758✔
63
                                  const I2& yBegin) const {
64
            return LogLinearInterpolation(xBegin, xEnd, yBegin);
1,758✔
65
        }
66
        static const bool global = false;
67
        static const Size requiredPoints = 2;
68
    };
69

70
    //! %log-cubic interpolation between discrete points
71
    /*! \ingroup interpolations */
72
    class LogCubicInterpolation : public Interpolation {
23✔
73
      public:
74
        /*! \pre the \f$ x \f$ values must be sorted. */
75
        template <class I1, class I2>
76
        LogCubicInterpolation(const I1& xBegin, const I1& xEnd,
23✔
77
                              const I2& yBegin,
78
                              CubicInterpolation::DerivativeApprox da,
79
                              bool monotonic,
80
                              CubicInterpolation::BoundaryCondition leftC,
81
                              Real leftConditionValue,
82
                              CubicInterpolation::BoundaryCondition rightC,
83
                              Real rightConditionValue) {
23✔
84
            impl_ = ext::shared_ptr<Interpolation::Impl>(new
23✔
85
                detail::LogInterpolationImpl<I1, I2>(
86
                    xBegin, xEnd, yBegin,
87
                    Cubic(da, monotonic,
×
88
                          leftC, leftConditionValue,
89
                          rightC, rightConditionValue)));
90
            impl_->update();
23✔
91
        }
23✔
92
    };
93

94
    //! log-cubic interpolation factory and traits
95
    /*! \ingroup interpolations */
96
    class LogCubic {
97
      public:
98
        LogCubic(CubicInterpolation::DerivativeApprox da,
99
                  bool monotonic = true,
100
                  CubicInterpolation::BoundaryCondition leftCondition
101
                      = CubicInterpolation::SecondDerivative,
102
                  Real leftConditionValue = 0.0,
103
                  CubicInterpolation::BoundaryCondition rightCondition
104
                      = CubicInterpolation::SecondDerivative,
105
                  Real rightConditionValue = 0.0)
106
        : da_(da), monotonic_(monotonic),
4✔
107
          leftType_(leftCondition), rightType_(rightCondition),
4✔
108
          leftValue_(leftConditionValue), rightValue_(rightConditionValue) {}
4✔
109
        template <class I1, class I2>
110
        Interpolation interpolate(const I1& xBegin, const I1& xEnd,
23✔
111
                                  const I2& yBegin) const {
112
            return LogCubicInterpolation(xBegin, xEnd, yBegin,
46✔
113
                                         da_, monotonic_,
23✔
114
                                         leftType_, leftValue_,
23✔
115
                                         rightType_, rightValue_);
23✔
116
        }
117
        static const bool global = true;
118
        static const Size requiredPoints = 2;
119
      private:
120
        CubicInterpolation::DerivativeApprox da_;
121
        bool monotonic_;
122
        CubicInterpolation::BoundaryCondition leftType_, rightType_;
123
        Real leftValue_, rightValue_;
124
    };
125

126
    // convenience classes
127

128
    class DefaultLogCubic : public LogCubic {
129
      public:
130
        DefaultLogCubic()
131
        : LogCubic(CubicInterpolation::Kruger) {}
132
    };
133

134
    class MonotonicLogCubic : public LogCubic {
135
      public:
136
        MonotonicLogCubic()
137
        : LogCubic(CubicInterpolation::Spline, true,
138
                   CubicInterpolation::SecondDerivative, 0.0,
139
                   CubicInterpolation::SecondDerivative, 0.0) {}
140
    };
141

142
    class KrugerLog : public LogCubic {
143
      public:
144
        KrugerLog()
145
        : LogCubic(CubicInterpolation::Kruger, false,
146
                   CubicInterpolation::SecondDerivative, 0.0,
147
                   CubicInterpolation::SecondDerivative, 0.0) {}
148
    };
149

150

151
    class LogCubicNaturalSpline : public LogCubicInterpolation {
152
      public:
153
        /*! \pre the \f$ x \f$ values must be sorted. */
154
        template <class I1, class I2>
155
        LogCubicNaturalSpline(const I1& xBegin,
156
                              const I1& xEnd,
157
                              const I2& yBegin)
158
        : LogCubicInterpolation(xBegin, xEnd, yBegin,
159
                                CubicInterpolation::Spline, false,
160
                                CubicInterpolation::SecondDerivative, 0.0,
161
                                CubicInterpolation::SecondDerivative, 0.0) {}
162
    };
163

164
    class MonotonicLogCubicNaturalSpline : public LogCubicInterpolation {
165
      public:
166
        /*! \pre the \f$ x \f$ values must be sorted. */
167
        template <class I1, class I2>
168
        MonotonicLogCubicNaturalSpline(const I1& xBegin,
169
                                       const I1& xEnd,
170
                                       const I2& yBegin)
171
        : LogCubicInterpolation(xBegin, xEnd, yBegin,
172
                                CubicInterpolation::Spline, true,
173
                                CubicInterpolation::SecondDerivative, 0.0,
174
                                CubicInterpolation::SecondDerivative, 0.0) {}
175
    };
176

177
    class KrugerLogCubic : public LogCubicInterpolation {
178
      public:
179
        /*! \pre the \f$ x \f$ values must be sorted. */
180
        template <class I1, class I2>
181
        KrugerLogCubic(const I1& xBegin,
182
                       const I1& xEnd,
183
                       const I2& yBegin)
184
        : LogCubicInterpolation(xBegin, xEnd, yBegin,
185
                                CubicInterpolation::Kruger, false,
186
                                CubicInterpolation::SecondDerivative, 0.0,
187
                                CubicInterpolation::SecondDerivative, 0.0) {}
188
    };
189

190
    class HarmonicLogCubic : public LogCubicInterpolation {
191
      public:
192
        /*! \pre the \f$ x \f$ values must be sorted. */
193
        template <class I1, class I2>
194
        HarmonicLogCubic(const I1& xBegin,
195
                         const I1& xEnd,
196
                         const I2& yBegin)
197
        : LogCubicInterpolation(xBegin, xEnd, yBegin,
198
                                CubicInterpolation::Harmonic, false,
199
                                CubicInterpolation::SecondDerivative, 0.0,
200
                                CubicInterpolation::SecondDerivative, 0.0) {}
201
    };
202

203
    class FritschButlandLogCubic : public LogCubicInterpolation {
204
      public:
205
        /*! \pre the \f$ x \f$ values must be sorted. */
206
        template <class I1, class I2>
207
        FritschButlandLogCubic(const I1& xBegin,
208
                               const I1& xEnd,
209
                               const I2& yBegin)
210
        : LogCubicInterpolation(xBegin, xEnd, yBegin,
211
                                CubicInterpolation::FritschButland, false,
212
                                CubicInterpolation::SecondDerivative, 0.0,
213
                                CubicInterpolation::SecondDerivative, 0.0) {}
214
    };
215

216
    class LogParabolic : public LogCubicInterpolation {
217
      public:
218
        /*! \pre the \f$ x \f$ values must be sorted. */
219
        template <class I1, class I2>
220
        LogParabolic(const I1& xBegin,
221
                     const I1& xEnd,
222
                     const I2& yBegin)
223
        : LogCubicInterpolation(xBegin, xEnd, yBegin,
224
                                CubicInterpolation::Parabolic, false,
225
                                CubicInterpolation::SecondDerivative, 0.0,
226
                                CubicInterpolation::SecondDerivative, 0.0) {}
227
    };
228

229
    class MonotonicLogParabolic : public LogCubicInterpolation {
230
      public:
231
        /*! \pre the \f$ x \f$ values must be sorted. */
232
        template <class I1, class I2>
233
        MonotonicLogParabolic(const I1& xBegin,
234
                              const I1& xEnd,
235
                              const I2& yBegin)
236
        : LogCubicInterpolation(xBegin, xEnd, yBegin,
237
                                CubicInterpolation::Parabolic, true,
238
                                CubicInterpolation::SecondDerivative, 0.0,
239
                                CubicInterpolation::SecondDerivative, 0.0) {}
240
    };
241

242
    //! %log-mixedlinearcubic interpolation between discrete points
243
    /*! \ingroup interpolations */
244
    class LogMixedLinearCubicInterpolation : public Interpolation {
245
      public:
246
        /*! \pre the \f$ x \f$ values must be sorted. */
247
        template <class I1, class I2>
248
        LogMixedLinearCubicInterpolation(const I1& xBegin, const I1& xEnd,
249
                                         const I2& yBegin, const Size n,
250
                                         MixedInterpolation::Behavior behavior,
251
                                         CubicInterpolation::DerivativeApprox da,
252
                                         bool monotonic,
253
                                         CubicInterpolation::BoundaryCondition leftC,
254
                                         Real leftConditionValue,
255
                                         CubicInterpolation::BoundaryCondition rightC,
256
                                         Real rightConditionValue) {
257
            impl_ = ext::shared_ptr<Interpolation::Impl>(new
258
                detail::LogInterpolationImpl<I1, I2>(
259
                    xBegin, xEnd, yBegin,
260
                    MixedLinearCubic(n, behavior, da, monotonic,
261
                                     leftC, leftConditionValue,
262
                                     rightC, rightConditionValue)));
263
            impl_->update();
264
        }
265
    };
266

267
    //! log-cubic interpolation factory and traits
268
    /*! \ingroup interpolations */
269
    class LogMixedLinearCubic {
270
      public:
271
        LogMixedLinearCubic(const Size n,
272
                            MixedInterpolation::Behavior behavior,
273
                            CubicInterpolation::DerivativeApprox da,
274
                            bool monotonic = true,
275
                            CubicInterpolation::BoundaryCondition leftCondition
276
                                = CubicInterpolation::SecondDerivative,
277
                            Real leftConditionValue = 0.0,
278
                            CubicInterpolation::BoundaryCondition rightCondition
279
                                = CubicInterpolation::SecondDerivative,
280
                            Real rightConditionValue = 0.0)
281
        : n_(n), behavior_(behavior), da_(da), monotonic_(monotonic),
282
          leftType_(leftCondition), rightType_(rightCondition),
283
          leftValue_(leftConditionValue), rightValue_(rightConditionValue) {}
284
        template <class I1, class I2>
285
        Interpolation interpolate(const I1& xBegin, const I1& xEnd,
286
                                  const I2& yBegin) const {
287
            return LogMixedLinearCubicInterpolation(xBegin, xEnd, yBegin,
288
                                                    n_, behavior_,
289
                                                    da_, monotonic_,
290
                                                    leftType_, leftValue_,
291
                                                    rightType_, rightValue_);
292
        }
293
        static const bool global = true;
294
        static const Size requiredPoints = 3;
295
    private:
296
        Size n_;
297
        MixedInterpolation::Behavior behavior_;
298
        CubicInterpolation::DerivativeApprox da_;
299
        bool monotonic_;
300
        CubicInterpolation::BoundaryCondition leftType_, rightType_;
301
        Real leftValue_, rightValue_;
302
    };
303

304
    // convenience classes
305
    
306
    class DefaultLogMixedLinearCubic : public LogMixedLinearCubic {
307
      public:
308
        explicit DefaultLogMixedLinearCubic(const Size n,
309
                                            MixedInterpolation::Behavior behavior
310
                                            = MixedInterpolation::ShareRanges)
311
        : LogMixedLinearCubic(n, behavior,
312
                              CubicInterpolation::Kruger) {}
313
    };
314

315
    class MonotonicLogMixedLinearCubic : public LogMixedLinearCubic {
316
      public:
317
        explicit MonotonicLogMixedLinearCubic(const Size n,
318
                                              MixedInterpolation::Behavior behavior
319
                                              = MixedInterpolation::ShareRanges)
320
        : LogMixedLinearCubic(n, behavior,
321
                              CubicInterpolation::Spline, true,
322
                              CubicInterpolation::SecondDerivative, 0.0,
323
                              CubicInterpolation::SecondDerivative, 0.0) {}
324
    };
325

326
    class KrugerLogMixedLinearCubic: public LogMixedLinearCubic {
327
      public:
328
        explicit KrugerLogMixedLinearCubic(const Size n,
329
                                           MixedInterpolation::Behavior behavior
330
                                           = MixedInterpolation::ShareRanges)
331
        : LogMixedLinearCubic(n, behavior,
332
                              CubicInterpolation::Kruger, false,
333
                              CubicInterpolation::SecondDerivative, 0.0,
334
                              CubicInterpolation::SecondDerivative, 0.0) {}
335
    };
336

337

338
    class LogMixedLinearCubicNaturalSpline : public LogMixedLinearCubicInterpolation {
339
      public:
340
        /*! \pre the \f$ x \f$ values must be sorted. */
341
        template <class I1, class I2>
342
        LogMixedLinearCubicNaturalSpline(const I1& xBegin, const I1& xEnd,
343
                                         const I2& yBegin, const Size n,
344
                                         MixedInterpolation::Behavior behavior
345
                                             = MixedInterpolation::ShareRanges)
346
        : LogMixedLinearCubicInterpolation(xBegin, xEnd, yBegin, n, behavior,
347
                                           CubicInterpolation::Spline, false,
348
                                           CubicInterpolation::SecondDerivative, 0.0,
349
                                           CubicInterpolation::SecondDerivative, 0.0) {}
350
    };
351

352

353
    namespace detail {
354

355
        template <class I1, class I2>
356
        class LogInterpolationImpl
357
            : public Interpolation::templateImpl<I1, I2> {
358
          public:
359
            template <class Interpolator>
360
            LogInterpolationImpl(const I1& xBegin, const I1& xEnd,
1,781✔
361
                                 const I2& yBegin,
362
                                 const Interpolator& factory)
363
            : Interpolation::templateImpl<I1, I2>(xBegin, xEnd, yBegin,
364
                                                  Interpolator::requiredPoints),
365
              logY_(xEnd-xBegin) {
1,781✔
366
                interpolation_ = factory.interpolate(this->xBegin_,
3,562✔
367
                                                     this->xEnd_,
1,781✔
368
                                                     logY_.begin());
1,781✔
369
            }
1,781✔
370
            void update() override {
22,758✔
371
                for (Size i=0; i<logY_.size(); ++i) {
493,585✔
372
                    QL_REQUIRE(this->yBegin_[i]>0.0,
470,827✔
373
                               "invalid value (" << this->yBegin_[i]
374
                               << ") at index " << i);
375
                    logY_[i] = std::log(this->yBegin_[i]);
470,827✔
376
                }
377
                interpolation_.update();
22,758✔
378
            }
22,758✔
379
            Real value(Real x) const override { return std::exp(interpolation_(x, true)); }
31,588,911✔
380
            Real primitive(Real) const override {
×
381
                QL_FAIL("LogInterpolation primitive not implemented");
×
382
            }
383
            Real derivative(Real x) const override {
224✔
384
                return value(x)*interpolation_.derivative(x, true);
224✔
385
            }
386
            Real secondDerivative(Real x) const override {
×
387
                return derivative(x)*interpolation_.derivative(x, true) +
×
388
                            value(x)*interpolation_.secondDerivative(x, true);
×
389
            }
390

391
          private:
392
            std::vector<Real> logY_;
393
            Interpolation interpolation_;
394
        };
395

396
    }
397

398
}
399

400
#endif
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc