1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 
3 /*
4  Copyright (C) 2011 Klaus Spanderen
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 fdmhullwhiteop.cpp */
21 
22 
23 #include <ql/models/shortrate/onefactormodels/hullwhite.hpp>
24 #include <ql/methods/finitedifferences/meshers/fdmmesher.hpp>
25 #include <ql/methods/finitedifferences/operators/fdmlinearoplayout.hpp>
26 #include <ql/methods/finitedifferences/operators/fdmhullwhiteop.hpp>
27 #include <ql/methods/finitedifferences/operators/firstderivativeop.hpp>
28 #include <ql/methods/finitedifferences/operators/secondderivativeop.hpp>
29 
30 namespace QuantLib {
31 
FdmHullWhiteOp(const ext::shared_ptr<FdmMesher> & mesher,const ext::shared_ptr<HullWhite> & model,Size direction)32     FdmHullWhiteOp::FdmHullWhiteOp(
33         const ext::shared_ptr<FdmMesher>& mesher,
34         const ext::shared_ptr<HullWhite>& model,
35         Size direction)
36     : direction_(direction),
37       x_(mesher->locations(direction)),
38       dzMap_(FirstDerivativeOp(direction, mesher).mult(-x_*model->a()).add(
39                 SecondDerivativeOp(direction, mesher)
40                     .mult(0.5*model->sigma()*model->sigma()
41                           *Array(mesher->layout()->size(), 1.0)))),
42       mapT_(direction, mesher),
43       model_(model) {
44     }
45 
size() const46     Size FdmHullWhiteOp::size() const { return 1U; }
47 
setTime(Time t1,Time t2)48     void FdmHullWhiteOp::setTime(Time t1, Time t2) {
49 
50         const ext::shared_ptr<OneFactorModel::ShortRateDynamics> dynamics =
51             model_->dynamics();
52 
53         const Real phi = 0.5*(  dynamics->shortRate(t1, 0.0)
54                               + dynamics->shortRate(t2, 0.0));
55 
56         mapT_.axpyb(Array(), dzMap_, dzMap_, -(x_+phi));
57     }
58 
apply(const Array & r) const59     Disposable<Array> FdmHullWhiteOp::apply(const Array& r) const {
60         return mapT_.apply(r);
61     }
62 
apply_mixed(const Array & r) const63     Disposable<Array> FdmHullWhiteOp::apply_mixed(const Array& r) const {
64         Array retVal(r.size(), 0.0);
65         return retVal;
66     }
67 
68     Disposable<Array>
apply_direction(Size direction,const Array & r) const69     FdmHullWhiteOp::apply_direction(Size direction, const Array& r) const {
70         if (direction == direction_)
71             return mapT_.apply(r);
72         else {
73             Array retVal(r.size(), 0.0);
74             return retVal;
75         }
76     }
77 
solve_splitting(Size direction,const Array & r,Real a) const78     Disposable<Array> FdmHullWhiteOp::solve_splitting(
79         Size direction, const Array& r, Real a) const {
80 
81         if (direction == direction_) {
82             return mapT_.solve_splitting(r, a, 1.0);
83         }
84         else {
85             Array retVal(r.size(), 0.0);
86             return retVal;
87         }
88     }
89 
90     Disposable<Array>
preconditioner(const Array & r,Real dt) const91     FdmHullWhiteOp::preconditioner(const Array& r, Real dt) const {
92         return solve_splitting(direction_, r, dt);
93     }
94 
95 #if !defined(QL_NO_UBLAS_SUPPORT)
96     Disposable<std::vector<SparseMatrix> >
toMatrixDecomp() const97     FdmHullWhiteOp::toMatrixDecomp() const {
98         std::vector<SparseMatrix> retVal(1, mapT_.toMatrix());
99         return retVal;
100     }
101 #endif
102 }
103 
104