1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 3 /* 4 Copyright (C) 2010 Hachemi Benyahia 5 Copyright (C) 2010 DeriveXperts SAS 6 7 This file is part of QuantLib, a free-software/open-source library 8 for financial quantitative analysts and developers - http://quantlib.org/ 9 10 QuantLib is free software: you can redistribute it and/or modify it 11 under the terms of the QuantLib license. You should have received a 12 copy of the license along with this program; if not, please email 13 <quantlib-dev@lists.sf.net>. The license is also available online at 14 <http://quantlib.org/license.shtml>. 15 16 This program is distributed in the hope that it will be useful, but WITHOUT 17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 18 FOR A PARTICULAR PURPOSE. See the license for more details. 19 */ 20 21 /*! \file farliegumbelmorgensterncopularng.hpp 22 \brief Farlie-Gumbel-Morgenstern copula random-number generator 23 */ 24 25 #ifndef quantlib_farlie_gumbel_morgenstern_copula_rng_hpp 26 #define quantlib_farlie_gumbel_morgenstern_copula_rng_hpp 27 28 #include <ql/methods/montecarlo/sample.hpp> 29 #include <ql/errors.hpp> 30 #include <vector> 31 32 namespace QuantLib { 33 34 //! Farlie-Gumbel-Morgenstern copula random-number generator 35 template <class RNG> 36 class FarlieGumbelMorgensternCopulaRng { 37 public: 38 typedef Sample<std::vector<Real> > sample_type; 39 typedef RNG urng_type; 40 explicit FarlieGumbelMorgensternCopulaRng(const RNG& uniformGenerator, 41 Real theta); 42 sample_type next() const; 43 private: 44 Real theta_; 45 RNG uniformGenerator_; 46 }; 47 48 template <class RNG> FarlieGumbelMorgensternCopulaRng(const RNG & ug,Real th)49 FarlieGumbelMorgensternCopulaRng<RNG>::FarlieGumbelMorgensternCopulaRng( 50 const RNG& ug, Real th) 51 : uniformGenerator_(ug), theta_(th) { 52 QL_REQUIRE(th >= -1.0 && th <= 1.00, 53 "theta (" << th << ") must be in [-1,1]"); 54 } 55 56 template <class RNG> 57 inline typename FarlieGumbelMorgensternCopulaRng<RNG>::sample_type next() const58 FarlieGumbelMorgensternCopulaRng<RNG>::next() const { 59 typename RNG::sample_type v1 = uniformGenerator_.next(); 60 typename RNG::sample_type v2 = uniformGenerator_.next(); 61 Real u1 = v1.value; 62 Real a = theta_*(2.0*u1-1.0); 63 Real b = pow(1.0-theta_*(2.0*u1-1.0),2.0)+4.0*theta_*v2.value*(2.0*u1-1.0); 64 Real u2 = (2.0*v2.value)/(sqrt(b)-a); 65 std::vector<Real> u; 66 u.push_back(u1); 67 u.push_back(u2); 68 return sample_type(u,v1.weight*v2.weight); 69 } 70 71 } 72 73 74 #endif 75