1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 
3 /*
4  Copyright (C) 2014 Peter Caspers
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 fdmzabrop.hpp
21     \brief Zabr linear pricing operator
22 */
23 
24 #ifndef quantlib_fdm_zabr_op_hpp
25 #define quantlib_fdm_zabr_op_hpp
26 
27 #include <ql/methods/finitedifferences/meshers/fdmmesher.hpp>
28 #include <ql/methods/finitedifferences/operators/firstderivativeop.hpp>
29 #include <ql/methods/finitedifferences/operators/triplebandlinearop.hpp>
30 #include <ql/methods/finitedifferences/operators/ninepointlinearop.hpp>
31 #include <ql/methods/finitedifferences/operators/fdmlinearopcomposite.hpp>
32 
33 namespace QuantLib {
34 
35 class FdmZabrUnderlyingPart {
36   public:
37     FdmZabrUnderlyingPart(
38         const ext::shared_ptr<FdmMesher>& mesher, Real beta, Real nu, Real rho, Real gamma);
39 
40     void setTime(Time t1, Time t2);
41     const TripleBandLinearOp &getMap() const;
42 
43   protected:
44     const Array volatilityValues_;
45     const Array forwardValues_;
46     TripleBandLinearOp mapT_;
47 
48     const ext::shared_ptr<FdmMesher> mesher_;
49 };
50 
51 class FdmZabrVolatilityPart {
52   public:
53     FdmZabrVolatilityPart(
54         const ext::shared_ptr<FdmMesher>& mesher, Real beta, Real nu, Real rho, Real gamma);
55 
56     void setTime(Time t1, Time t2);
57     const TripleBandLinearOp &getMap() const;
58 
59   protected:
60     const Array volatilityValues_;
61     const Array forwardValues_;
62     TripleBandLinearOp mapT_;
63 
64     const ext::shared_ptr<FdmMesher> mesher_;
65 };
66 
67 class FdmZabrOp : public FdmLinearOpComposite {
68   public:
69     FdmZabrOp(const ext::shared_ptr<FdmMesher>& mesher,
70               Real beta,
71               Real nu,
72               Real rho,
73               Real gamma = 1.0); // gamma=1.0 recovers the classic sabr model
74 
75     Size size() const;
76     void setTime(Time t1, Time t2);
77 
78     Disposable<Array> apply(const Array &r) const;
79     Disposable<Array> apply_mixed(const Array &r) const;
80 
81     Disposable<Array> apply_direction(Size direction, const Array &r) const;
82     Disposable<Array> solve_splitting(Size direction, const Array &r,
83                                       Real s) const;
84     Disposable<Array> preconditioner(const Array &r, Real s) const;
85 
86 #if !defined(QL_NO_UBLAS_SUPPORT)
87     Disposable<std::vector<SparseMatrix> > toMatrixDecomp() const;
88 #endif
89 
90   private:
91     const Array volatilityValues_;
92     const Array forwardValues_;
93     NinePointLinearOp dxyMap_;
94     FdmZabrUnderlyingPart dxMap_;
95     FdmZabrVolatilityPart dyMap_;
96 };
97 }
98 
99 #endif
100