/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2002, 2003 Ferdinando Ametrano Copyright (C) 2000, 2001, 2002, 2003 RiskMap srl Copyright (C) 2003, 2004, 2005, 2006 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 . 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 pathgenerator.hpp \brief Generates random paths using a sequence generator */ #ifndef quantlib_montecarlo_path_generator_hpp #define quantlib_montecarlo_path_generator_hpp #include #include namespace QuantLib { //! Generates random paths using a sequence generator /*! Generates random paths with drift(S,t) and variance(S,t) using a gaussian sequence generator \ingroup mcarlo \test the generated paths are checked against cached results */ template class PathGenerator { public: typedef Sample sample_type; // constructors PathGenerator(const boost::shared_ptr&, Time length, Size timeSteps, const GSG& generator, bool brownianBridge); PathGenerator(const boost::shared_ptr&, const TimeGrid& timeGrid, const GSG& generator, bool brownianBridge); //! \name inspectors //@{ const sample_type& next() const; const sample_type& antithetic() const; Size size() const { return dimension_; } const TimeGrid& timeGrid() const { return timeGrid_; } //@} private: const sample_type& next(bool antithetic) const; bool brownianBridge_; GSG generator_; Size dimension_; TimeGrid timeGrid_; boost::shared_ptr process_; mutable sample_type next_; mutable std::vector temp_; BrownianBridge bb_; }; // template definitions template PathGenerator::PathGenerator( const boost::shared_ptr& process, Time length, Size timeSteps, const GSG& generator, bool brownianBridge) : brownianBridge_(brownianBridge), generator_(generator), dimension_(generator_.dimension()), timeGrid_(length, timeSteps), process_(boost::dynamic_pointer_cast(process)), next_(Path(timeGrid_),1.0), temp_(dimension_), bb_(timeGrid_) { QL_REQUIRE(dimension_==timeSteps, "sequence generator dimensionality (" << dimension_ << ") != timeSteps (" << timeSteps << ")"); } template PathGenerator::PathGenerator( const boost::shared_ptr& process, const TimeGrid& timeGrid, const GSG& generator, bool brownianBridge) : brownianBridge_(brownianBridge), generator_(generator), dimension_(generator_.dimension()), timeGrid_(timeGrid), process_(boost::dynamic_pointer_cast(process)), next_(Path(timeGrid_),1.0), temp_(dimension_), bb_(timeGrid_) { QL_REQUIRE(dimension_==timeGrid_.size()-1, "sequence generator dimensionality (" << dimension_ << ") != timeSteps (" << timeGrid_.size()-1 << ")"); } template const typename PathGenerator::sample_type& PathGenerator::next() const { return next(false); } template const typename PathGenerator::sample_type& PathGenerator::antithetic() const { return next(true); } template const typename PathGenerator::sample_type& PathGenerator::next(bool antithetic) const { typedef typename GSG::sample_type sequence_type; const sequence_type& sequence_ = antithetic ? generator_.lastSequence() : generator_.nextSequence(); if (brownianBridge_) { bb_.transform(sequence_.value.begin(), sequence_.value.end(), temp_.begin()); } else { std::copy(sequence_.value.begin(), sequence_.value.end(), temp_.begin()); } next_.weight = sequence_.weight; Path& path = next_.value; path.front() = process_->x0(); for (Size i=1; ievolve(t, path[i-1], dt, antithetic ? -temp_[i-1] : temp_[i-1]); } return next_; } } #endif