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