/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2003 Ferdinando Ametrano Copyright (C) 2000, 2001, 2002, 2003 RiskMap srl Copyright (C) 2003, 2004, 2005 StatPro Italia srl Copyright (C) 2005 Klaus Spanderen 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 multipathgenerator.hpp \brief Generates a multi path from a random-array generator */ #ifndef quantlib_multi_path_generator_hpp #define quantlib_multi_path_generator_hpp #include #include #include namespace QuantLib { //! Generates a multipath from a random number generator. /*! RSG is a sample generator which returns a random sequence. It must have the minimal interface: \code RSG { Sample next(); }; \endcode \ingroup mcarlo \test the generated paths are checked against cached results */ template class MultiPathGenerator { public: typedef Sample sample_type; MultiPathGenerator(const boost::shared_ptr&, const TimeGrid&, GSG generator, bool brownianBridge = false); const sample_type& next() const; const sample_type& antithetic() const; private: const sample_type& next(bool antithetic) const; bool brownianBridge_; boost::shared_ptr process_; GSG generator_; mutable sample_type next_; }; // template definitions template MultiPathGenerator::MultiPathGenerator( const boost::shared_ptr& process, const TimeGrid& times, GSG generator, bool brownianBridge) : brownianBridge_(brownianBridge), process_(process), generator_(generator), next_(MultiPath(process->size(), times), 1.0) { QL_REQUIRE(generator_.dimension() == process->factors()*(times.size()-1), "dimension (" << generator_.dimension() << ") is not equal to (" << process->factors() << " * " << times.size()-1 << ") the number of factors " << "times the number of time steps"); QL_REQUIRE(times.size() > 1, "no times given"); } template inline const typename MultiPathGenerator::sample_type& MultiPathGenerator::next() const { return next(false); } template inline const typename MultiPathGenerator::sample_type& MultiPathGenerator::antithetic() const { return next(true); } template const typename MultiPathGenerator::sample_type& MultiPathGenerator::next(bool antithetic) const { if (brownianBridge_) { QL_FAIL("Brownian bridge not supported"); } else { typedef typename GSG::sample_type sequence_type; const sequence_type& sequence_ = antithetic ? generator_.lastSequence() : generator_.nextSequence(); Size m = process_->size(); Size n = process_->factors(); MultiPath& path = next_.value; Array asset = process_->initialValues(); for (Size j=0; j()); else std::copy(sequence_.value.begin()+offset, sequence_.value.begin()+offset+n, temp.begin()); asset = process_->evolve(t, asset, dt, temp); for (Size j=0; j