Logo Search packages:      
Sourcecode: quantlib version File versions  Download package


Go to the documentation of this file.
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

 Copyright (C) 2001, 2002, 2003 Sadruddin Rejeb
 Copyright (C) 2004, 2005 StatPro Italia srl

 This file is part of QuantLib, a free-software/open-source library
 for financial quantitative analysts and developers - http://quantlib.org/

 QuantLib is free software: you can redistribute it and/or modify it
 under the terms of the QuantLib license.  You should have received a
 copy of the license along with this program; if not, please email
 <quantlib-dev@lists.sf.net>. The license is also available online at

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the license for more details.

/*! \file lattice.hpp
    \brief Lattice method class

#ifndef quantlib_lattice_hpp
#define quantlib_lattice_hpp

#include <ql/numericalmethod.hpp>
#include <ql/discretizedasset.hpp>
#include <ql/Patterns/curiouslyrecurring.hpp>

namespace QuantLib {

    //! Lattice-method base class
    /*! This class defines a lattice method that is able to rollback
        (with discount) a discretized asset object. It will usually be
        based on one or more trees.

        Derived classes must implement the following interface:
          DiscountFactor discount(Size i, Size index) const;
          Size descendant(Size i, Size index, Size branch) const;
          Real probability(Size i, Size index, Size branch) const;
        and may implement the following:
          void stepback(Size i,
                        const Array& values,
                        Array& newValues) const;

        \ingroup lattices
    template <class Impl>
00057     class Lattice : public NumericalMethod,
                    public CuriouslyRecurringTemplate<Impl> {
        Lattice(const TimeGrid& timeGrid,
                Size n)
        : NumericalMethod(timeGrid), n_(n) {
            QL_REQUIRE(n>0, "there is no zeronomial lattice!");
            statePrices_ = std::vector<Array>(1, Array(1, 1.0));
            statePricesLimit_ = 0;

        //! \name NumericalMethod interface
        void initialize(DiscretizedAsset&, Time t) const;
        void rollback(DiscretizedAsset&, Time to) const;
        void partialRollback(DiscretizedAsset&, Time to) const;
        //! Computes the present value of an asset using Arrow-Debrew prices
        Real presentValue(DiscretizedAsset&) const;

        const Array& statePrices(Size i) const;

        void stepback(Size i,
                      const Array& values,
                      Array& newValues) const;

        void computeStatePrices(Size until) const;

        // Arrow-Debrew state prices
        mutable std::vector<Array> statePrices_;

        Size n_;
        mutable Size statePricesLimit_;

    // template definitions

    template <class Impl>
    void Lattice<Impl>::computeStatePrices(Size until) const {
        for (Size i=statePricesLimit_; i<until; i++) {
            statePrices_.push_back(Array(this->impl().size(i+1), 0.0));
            for (Size j=0; j<this->impl().size(i); j++) {
                DiscountFactor disc = this->impl().discount(i,j);
                Real statePrice = statePrices_[i][j];
                for (Size l=0; l<n_; l++) {
                    statePrices_[i+1][this->impl().descendant(i,j,l)] +=
        statePricesLimit_ = until;

    template <class Impl>
    const Array& Lattice<Impl>::statePrices(Size i) const {
        if (i>statePricesLimit_)
        return statePrices_[i];

    template <class Impl>
00121     Real Lattice<Impl>::presentValue(DiscretizedAsset& asset) const {
        Size i = t_.findIndex(asset.time());
        return DotProduct(asset.values(), statePrices(i));

    template <class Impl>
00127     void Lattice<Impl>::initialize(DiscretizedAsset& asset, Time t) const {
        Size i = t_.findIndex(t);
        asset.time() = t;

    template <class Impl>
00134     void Lattice<Impl>::rollback(DiscretizedAsset& asset, Time to) const {

    template <class Impl>
00140     void Lattice<Impl>::partialRollback(DiscretizedAsset& asset,
                                        Time to) const {

        Time from = asset.time();

        if (close(from,to))

        QL_REQUIRE(from > to,
                   "cannot roll the asset back to" << to
                   << " (it is already at t = " << from << ")");

        Integer iFrom = Integer(t_.findIndex(from));
        Integer iTo = Integer(t_.findIndex(to));

        for (Integer i=iFrom-1; i>=iTo; i--) {
            Array newValues(this->impl().size(i));
            this->impl().stepback(i, asset.values(), newValues);
            asset.time() = t_[i];
            asset.values() = newValues;
            // skip the very last adjustment
            if (i != iTo)

    template <class Impl>
    void Lattice<Impl>::stepback(Size i, const Array& values,
                                 Array& newValues) const {
        for (Size j=0; j<this->impl().size(i); j++) {
            Real value = 0.0;
            for (Size l=0; l<n_; l++) {
                value += this->impl().probability(i,j,l) *
            value *= this->impl().discount(i,j);
            newValues[j] = value;



Generated by  Doxygen 1.6.0   Back to index