예제 #1
0
        public FdmHestonEquityPart(FdmMesher mesher,
                                   YieldTermStructure rTS,
                                   YieldTermStructure qTS,
                                   FdmQuantoHelper quantoHelper      = null,
                                   LocalVolTermStructure leverageFct = null)
        {
            varianceValues_ = new Vector(0.5 * mesher.locations(1));
            dxMap_          = new FirstDerivativeOp(0, mesher);
            dxxMap_         = new SecondDerivativeOp(0, mesher).mult(0.5 * mesher.locations(1));
            mapT_           = new TripleBandLinearOp(0, mesher);
            mesher_         = mesher;
            rTS_            = rTS;
            qTS_            = qTS;
            quantoHelper_   = quantoHelper;
            leverageFct_    = leverageFct;

            // on the boundary s_min and s_max the second derivative
            // d^2V/dS^2 is zero and due to Ito's Lemma the variance term
            // in the drift should vanish.
            FdmLinearOpLayout   layout  = mesher_.layout();
            FdmLinearOpIterator endIter = layout.end();

            for (FdmLinearOpIterator iter = layout.begin(); iter != endIter;
                 ++iter)
            {
                if (iter.coordinates()[0] == 0 ||
                    iter.coordinates()[0] == layout.dim()[0] - 1)
                {
                    varianceValues_[iter.index()] = 0.0;
                }
            }
            volatilityValues_ = Vector.Sqrt(2 * varianceValues_);
        }
예제 #2
0
        public void axpyb(Vector a, TripleBandLinearOp x, TripleBandLinearOp y, Vector b)
        {
            int size = mesher_.layout().size();

            if (a.empty())
            {
                if (b.empty())
                {
                    //#pragma omp parallel for
                    for (int i = 0; i < size; ++i)
                    {
                        diag_[i]  = y.diag_[i];
                        lower_[i] = y.lower_[i];
                        upper_[i] = y.upper_[i];
                    }
                }
                else
                {
                    int binc = (b.size() > 1) ? 1 : 0;
                    //#pragma omp parallel for
                    for (int i = 0; i < size; ++i)
                    {
                        diag_[i]  = y.diag_[i] + b[i * binc];
                        lower_[i] = y.lower_[i];
                        upper_[i] = y.upper_[i];
                    }
                }
            }
            else if (b.empty())
            {
                int ainc = (a.size() > 1) ? 1 : 0;

                //#pragma omp parallel for
                for (int i = 0; i < size; ++i)
                {
                    double s = a[i * ainc];
                    diag_[i]  = y.diag_[i] + s * x.diag_[i];
                    lower_[i] = y.lower_[i] + s * x.lower_[i];
                    upper_[i] = y.upper_[i] + s * x.upper_[i];
                }
            }
            else
            {
                int binc = (b.size() > 1) ? 1 : 0;
                int ainc = (a.size() > 1) ? 1 : 0;

                //#pragma omp parallel for
                for (int i = 0; i < size; ++i)
                {
                    double s = a[i * ainc];
                    diag_[i]  = y.diag_[i] + s * x.diag_[i] + b[i * binc];
                    lower_[i] = y.lower_[i] + s * x.lower_[i];
                    upper_[i] = y.upper_[i] + s * x.upper_[i];
                }
            }
        }
예제 #3
0
 public void swap(TripleBandLinearOp m)
 {
     Utils.swap(ref mesher_, ref m.mesher_);
     Utils.swap(ref direction_, ref m.direction_);
     Utils.swap(ref i0_, ref m.i0_);
     Utils.swap(ref i2_, ref m.i2_);
     Utils.swap(ref reverseIndex_, ref m.reverseIndex_);
     Utils.swap(ref lower_, ref m.lower_);
     Utils.swap(ref diag_, ref m.diag_);
     Utils.swap(ref upper_, ref m.upper_);
 }
예제 #4
0
 public FdmHestonVariancePart(
     FdmMesher mesher,
     YieldTermStructure rTS,
     double sigma, double kappa, double theta)
 {
     dyMap_ = new SecondDerivativeOp(1, mesher)
              .mult(0.5 * sigma * sigma * mesher.locations(1))
              .add(new FirstDerivativeOp(1, mesher)
                   .mult(kappa * (theta - mesher.locations(1))));
     mapT_ = new TripleBandLinearOp(1, mesher);
     rTS_  = rTS;
 }
예제 #5
0
 public FdmHullWhiteOp(FdmMesher mesher,
                       HullWhite model,
                       int direction)
 {
     x_     = mesher.locations(direction);
     dzMap_ = new TripleBandLinearOp(new FirstDerivativeOp(direction, mesher).mult(-1.0 * x_ * model.a()).add(
                                         new SecondDerivativeOp(direction, mesher).mult(0.5 * model.sigma() * model.sigma()
                                                                                        * new Vector(mesher.layout().size(), 1.0))));
     mapT_      = new TripleBandLinearOp(direction, mesher);
     direction_ = direction;
     model_     = model;
 }
예제 #6
0
        public TripleBandLinearOp add
            (TripleBandLinearOp m)
        {
            TripleBandLinearOp retVal = new TripleBandLinearOp(direction_, mesher_);
            int size = mesher_.layout().size();

            //#pragma omp parallel for
            for (int i = 0; i < size; ++i)
            {
                retVal.lower_[i] = lower_[i] + m.lower_[i];
                retVal.diag_[i]  = diag_[i] + m.diag_[i];
                retVal.upper_[i] = upper_[i] + m.upper_[i];
            }

            return(retVal);
        }
예제 #7
0
        public TripleBandLinearOp mult(Vector u)
        {
            TripleBandLinearOp retVal = new TripleBandLinearOp(direction_, mesher_);

            int size = mesher_.layout().size();

            //#pragma omp parallel for
            for (int i = 0; i < size; ++i)
            {
                double s = u[i];
                retVal.lower_[i] = lower_[i] * s;
                retVal.diag_[i]  = diag_[i] * s;
                retVal.upper_[i] = upper_[i] * s;
            }

            return(retVal);
        }
예제 #8
0
        public TripleBandLinearOp(TripleBandLinearOp m)
        {
            direction_    = m.direction_;
            i0_           = new InitializedList <int>(m.mesher_.layout().size());
            i2_           = new InitializedList <int>(m.mesher_.layout().size());
            reverseIndex_ = new InitializedList <int>(m.mesher_.layout().size());
            lower_        = new InitializedList <double>(m.mesher_.layout().size());
            diag_         = new InitializedList <double>(m.mesher_.layout().size());
            upper_        = new InitializedList <double>(m.mesher_.layout().size());
            mesher_       = m.mesher_;

            int len = m.mesher_.layout().size();

            m.i0_.copy(0, len, 0, i0_);
            m.i2_.copy(0, len, 0, i2_);
            m.reverseIndex_.copy(0, len, 0, reverseIndex_);
            m.lower_.copy(0, len, 0, lower_);
            m.diag_.copy(0, len, 0, diag_);
            m.upper_.copy(0, len, 0, upper_);
        }
예제 #9
0
        public TripleBandLinearOp multR(Vector u)
        {
            FdmLinearOpLayout layout = mesher_.layout();
            int size = layout.size();

            Utils.QL_REQUIRE(u.size() == size, () => "inconsistent size of rhs");
            TripleBandLinearOp retVal = new TripleBandLinearOp(direction_, mesher_);

            for (int i = 0; i < size; ++i)
            {
                double sm1 = i > 0 ? u[i - 1] : 1.0;
                double s0  = u[i];
                double sp1 = i < size - 1 ? u[i + 1] : 1.0;
                retVal.lower_[i] = lower_[i] * sm1;
                retVal.diag_[i]  = diag_[i] * s0;
                retVal.upper_[i] = upper_[i] * sp1;
            }

            return(retVal);
        }
예제 #10
0
 public FdmBlackScholesOp(FdmMesher mesher,
                          GeneralizedBlackScholesProcess bsProcess,
                          double strike,
                          bool localVol = false,
                          double?illegalLocalVolOverwrite = null,
                          int direction = 0,
                          FdmQuantoHelper quantoHelper = null)
 {
     mesher_   = mesher;
     rTS_      = bsProcess.riskFreeRate().currentLink();
     qTS_      = bsProcess.dividendYield().currentLink();
     volTS_    = bsProcess.blackVolatility().currentLink();
     localVol_ = (localVol) ? bsProcess.localVolatility().currentLink()
              : null;
     x_      = (localVol) ? new Vector(Vector.Exp(mesher.locations(direction))) : null;
     dxMap_  = new FirstDerivativeOp(direction, mesher);
     dxxMap_ = new SecondDerivativeOp(direction, mesher);
     mapT_   = new TripleBandLinearOp(direction, mesher);
     strike_ = strike;
     illegalLocalVolOverwrite_ = illegalLocalVolOverwrite;
     direction_    = direction;
     quantoHelper_ = quantoHelper;
 }