1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 3 /* 4 Copyright (C) 2009 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 #include <ql/methods/finitedifferences/schemes/modifiedcraigsneydscheme.hpp> 21 22 namespace QuantLib { 23 ModifiedCraigSneydScheme(Real theta,Real mu,const ext::shared_ptr<FdmLinearOpComposite> & map,const bc_set & bcSet)24 ModifiedCraigSneydScheme::ModifiedCraigSneydScheme( 25 Real theta, Real mu, 26 const ext::shared_ptr<FdmLinearOpComposite> & map, 27 const bc_set& bcSet) 28 : dt_(Null<Real>()), 29 theta_(theta), 30 mu_ (mu), 31 map_ (map), 32 bcSet_(bcSet) { 33 } 34 step(array_type & a,Time t)35 void ModifiedCraigSneydScheme::step(array_type& a, Time t) { 36 QL_REQUIRE(t-dt_ > -1e-8, "a step towards negative time given"); 37 map_->setTime(std::max(0.0, t-dt_), t); 38 bcSet_.setTime(std::max(0.0, t-dt_)); 39 40 bcSet_.applyBeforeApplying(*map_); 41 Array y = a + dt_*map_->apply(a); 42 bcSet_.applyAfterApplying(y); 43 44 Array y0 = y; 45 46 for (Size i=0; i < map_->size(); ++i) { 47 Array rhs = y - theta_*dt_*map_->apply_direction(i, a); 48 y = map_->solve_splitting(i, rhs, -theta_*dt_); 49 } 50 51 bcSet_.applyBeforeApplying(*map_); 52 Array yt = y0 + mu_*dt_*map_->apply_mixed(y-a) 53 +(0.5-mu_)*dt_*map_->apply(y-a);; 54 bcSet_.applyAfterApplying(yt); 55 56 for (Size i=0; i < map_->size(); ++i) { 57 Array rhs = yt - theta_*dt_*map_->apply_direction(i, a); 58 yt = map_->solve_splitting(i, rhs, -theta_*dt_); 59 } 60 bcSet_.applyAfterSolving(yt); 61 62 a = yt; 63 } 64 setStep(Time dt)65 void ModifiedCraigSneydScheme::setStep(Time dt) { 66 dt_=dt; 67 } 68 } 69