QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.34
Loading...
Searching...
No Matches
finitedifferencemodel.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) 2000, 2001, 2002, 2003 RiskMap srl
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 finitedifferencemodel.hpp
21 \brief generic finite difference model
22*/
23
24#ifndef quantlib_finite_difference_model_hpp
25#define quantlib_finite_difference_model_hpp
26
30#include <utility>
31
32namespace QuantLib {
33
34 //! Generic finite difference model
35 /*! \ingroup findiff */
36 template<class Evolver>
38 public:
39 typedef typename Evolver::traits traits;
40 typedef typename traits::operator_type operator_type;
41 typedef typename traits::array_type array_type;
42 typedef typename traits::bc_set bc_set;
43 typedef typename traits::condition_type condition_type;
44 // constructors
46 const bc_set& bcs,
47 std::vector<Time> stoppingTimes = std::vector<Time>())
48 : evolver_(L, bcs), stoppingTimes_(std::move(stoppingTimes)) {
49 std::sort(stoppingTimes_.begin(), stoppingTimes_.end());
50 auto last = std::unique(stoppingTimes_.begin(), stoppingTimes_.end());
51 stoppingTimes_.erase(last, stoppingTimes_.end());
52 }
54 std::vector<Time> stoppingTimes = std::vector<Time>())
55 : evolver_(std::move(evolver)), stoppingTimes_(std::move(stoppingTimes)) {
56 std::sort(stoppingTimes_.begin(), stoppingTimes_.end());
57 auto last = std::unique(stoppingTimes_.begin(), stoppingTimes_.end());
58 stoppingTimes_.erase(last, stoppingTimes_.end());
59 }
60 // methods
61 // array_type grid() const { return evolver.xGrid(); }
62 const Evolver& evolver() const{ return evolver_; }
63 /*! solves the problem between the given times.
64 \warning being this a rollback, <tt>from</tt> must be a later
65 time than <tt>to</tt>.
66 */
68 Time from,
69 Time to,
70 Size steps) {
71 rollbackImpl(a, from, to, steps, (const condition_type*)nullptr);
72 }
73 /*! solves the problem between the given times,
74 applying a condition at every step.
75 \warning being this a rollback, <tt>from</tt> must be a later
76 time than <tt>to</tt>.
77 */
79 Time from,
80 Time to,
81 Size steps,
82 const condition_type& condition) {
83 rollbackImpl(a,from,to,steps,&condition);
84 }
85 private:
87 Time from,
88 Time to,
89 Size steps,
90 const condition_type* condition) {
91
92 QL_REQUIRE(from >= to,
93 "trying to roll back from " << from << " to " << to);
94
95 Time dt = (from-to)/steps, t = from;
96 evolver_.setStep(dt);
97
98 if(!stoppingTimes_.empty() && stoppingTimes_.back() == from) {
99 if (condition)
100 condition->applyTo(a,from);
101 }
102 for (Size i=0; i<steps; ++i, t -= dt) {
103 Time now = t;
104 // make sure last step ends exactly on "to" in order to not
105 // miss a stopping time at "to" due to numerical issues
106 Time next = (i < steps -1)? t-dt : to;
107
108 if (std::fabs(to-next) < std::sqrt(QL_EPSILON)) next = to;
109 bool hit = false;
110 for (Integer j = static_cast<Integer>(stoppingTimes_.size())-1; j >= 0 ; --j) {
111 if (next <= stoppingTimes_[j] && stoppingTimes_[j] < now) {
112 // a stopping time was hit
113 hit = true;
114
115 // perform a small step to stoppingTimes_[j]...
116 evolver_.setStep(now-stoppingTimes_[j]);
117 evolver_.step(a,now);
118 if (condition)
119 condition->applyTo(a,stoppingTimes_[j]);
120 // ...and continue the cycle
121 now = stoppingTimes_[j];
122 }
123 }
124 // if we did hit...
125 if (hit) {
126 // ...we might have to make a small step to
127 // complete the big one...
128 if (now > next) {
129 evolver_.setStep(now - next);
130 evolver_.step(a,now);
131 if (condition)
132 condition->applyTo(a,next);
133 }
134 // ...and in any case, we have to reset the
135 // evolver to the default step.
136 evolver_.setStep(dt);
137 } else {
138 // if we didn't, the evolver is already set to the
139 // default step, which is ok for us.
140 evolver_.step(a,now);
141 if (condition)
142 condition->applyTo(a, next);
143 }
144 }
145 }
146 Evolver evolver_;
147 std::vector<Time> stoppingTimes_;
148 };
149
150}
151
152
153#endif
boundary conditions for differential operators
Generic finite difference model.
FiniteDifferenceModel(const operator_type &L, const bc_set &bcs, std::vector< Time > stoppingTimes=std::vector< Time >())
void rollback(array_type &a, Time from, Time to, Size steps)
void rollbackImpl(array_type &a, Time from, Time to, Size steps, const condition_type *condition)
void rollback(array_type &a, Time from, Time to, Size steps, const condition_type &condition)
FiniteDifferenceModel(Evolver evolver, std::vector< Time > stoppingTimes=std::vector< Time >())
const DefaultType & t
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Definition: errors.hpp:117
#define QL_EPSILON
Definition: qldefines.hpp:178
Real Time
continuous quantity with 1-year units
Definition: types.hpp:62
QL_INTEGER Integer
integer number
Definition: types.hpp:35
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35
STL namespace.
Differential operator traits.
conditions to be applied at every time step