21#ifndef quantlib_latent_model_hpp
22#define quantlib_latent_model_hpp
24#include <ql/experimental/math/multidimquadrature.hpp>
25#include <ql/experimental/math/multidimintegrator.hpp>
26#include <ql/math/integrals/trapezoidintegral.hpp>
27#include <ql/math/randomnumbers/randomsequencegenerator.hpp>
28#include <ql/experimental/math/gaussiancopulapolicy.hpp>
29#include <ql/experimental/math/tcopulapolicy.hpp>
30#include <ql/math/randomnumbers/boxmullergaussianrng.hpp>
31#include <ql/experimental/math/polarstudenttrng.hpp>
32#include <ql/handle.hpp>
33#include <ql/quote.hpp>
53 std::transform(v.begin(), v.end(), v.begin(),
54 [=](
Real x) ->
Real { return x * d; });
75 const std::vector<Real>& arg)>& f)
const = 0;
86 const ext::function<std::vector<Real> (
87 const std::vector<Real>& arg)>& f)
const {
88 QL_FAIL(
"No vector integration provided");
107 #ifndef QL_PATCH_SOLARIS
115 #ifndef QL_PATCH_SOLARIS
126 return GaussianQuadMultidimIntegrator::integrate<Real>(f);
129 const ext::function<std::vector<Real>(
const std::vector<Real>& arg)>& f)
131 return GaussianQuadMultidimIntegrator::integrate<std::vector<Real>>(f);
142 const std::vector<ext::shared_ptr<Integrator> >& integrators,
145 a_(integrators.size(),a), b_(integrators.size(),b) {}
151 const std::vector<Real>
a_, b_;
283 template <
class copulaPolicyImpl>
296 return copula_.cumulativeY(val, iVariable);
304 #if defined(QL_EXTRA_SAFETY_CHECKS)
306 "Factor size must match that of model.");
312 return copula_.inverseCumulativeDensity(p, iFactor);
317 return copula_.inverseCumulativeY(p, iVariable);
322 return copula_.inverseCumulativeZ(p);
330 return copula_.allFactorCumulInverter(probs);
409 template <
class USNG,
432 typename USNG::sample_type sample =
457 #ifndef QL_PATCH_SOLARIS
464 #ifndef QL_PATCH_SOLARIS
473 std::vector<ext::shared_ptr<Integrator> > integrals;
474 for(
Size i=0; i<dimension; i++)
489 ext::make_shared<IntegrationBase<MultidimIntegral> >
490 (integrals, -35., 35.);
493 QL_FAIL(
"Unknown latent model integration type.");
519 const std::vector<std::vector<Real> >& factorsWeights,
520 const typename copulaType::initTraits& ini =
521 copulaType::initTraits());
532 const typename copulaType::initTraits& ini =
533 copulaType::initTraits());
547 const typename copulaType::initTraits& ini = copulaType::initTraits());
562 const typename copulaType::initTraits& ini =
563 copulaType::initTraits());
575 Real init = (iVar1 == iVar2 ?
587 const ext::function<
Real(
const std::vector<Real>& v1)>& f)
const {
591 [&](
const std::vector<Real>& x){
return copula_.density(x) * f(x); });
598 const ext::function<std::vector<Real>(
599 const std::vector<Real>& v1)>& f )
const {
602 [&](
const std::vector<Real>& x){
return M(
copula_.density(x), f(x)); });
608 virtual const ext::shared_ptr<LMIntegration>&
integration()
const {
609 QL_FAIL(
"Integration non implemented in Latent model.");
649 template <
class Impl>
651 const std::vector<std::vector<Real> >& factorWeights,
652 const typename Impl::initTraits& ini)
653 : factorWeights_(factorWeights),
654 nFactors_(factorWeights[0].size()),
655 nVariables_(factorWeights.size()), copula_(factorWeights, ini)
664 "Name " << i <<
" provides a different number of factors");
668 template <
class Impl>
670 const std::vector<Real>& factorWeights,
671 const typename Impl::initTraits& ini)
673 nVariables_(factorWeights.size())
678 idiosyncFctrs_.push_back(std::sqrt(1. - factorWeight * factorWeight));
683 template <
class Impl>
685 const Real correlSqr,
687 const typename Impl::initTraits& ini)
688 : factorWeights_(nVariables,
std::vector<
Real>(1, correlSqr)),
689 idiosyncFctrs_(nVariables,
690 std::sqrt(1.-correlSqr*correlSqr)),
692 nVariables_(nVariables),
693 copula_(factorWeights_, ini)
696 template <
class Impl>
698 const Handle<Quote>& singleFactorCorrel,
700 const typename Impl::initTraits& ini)
701 : factorWeights_(nVariables,
std::vector<
Real>(1,
702 std::sqrt(singleFactorCorrel->value()))),
703 cachedMktFactor_(singleFactorCorrel),
704 idiosyncFctrs_(nVariables,
705 std::sqrt(1.-singleFactorCorrel->value())),
707 nVariables_(nVariables),
708 copula_(factorWeights_, ini)
715 template <
class Impl>
722 factorWeights_ = std::vector<std::vector<Real> >(nVariables_,
723 std::vector<Real>(1, std::sqrt(cachedMktFactor_->value())));
724 idiosyncFctrs_ = std::vector<Real>(nVariables_,
725 std::sqrt(1.-cachedMktFactor_->value()));
726 copula_ =
copulaType(factorWeights_, copula_.getInitTraits());
747 template<
class TC>
template<
class URNG,
bool dummy>
749 ::FactorSampler <RandomSequenceGenerator<BoxMullerGaussianRng<URNG> > ,
751 typedef URNG urng_type;
759 const sample_type& nextSequence()
const {
760 return boxMullRng_.nextSequence();
763 RandomSequenceGenerator<BoxMullerGaussianRng<urng_type> > boxMullRng_;
773 template<
class TC>
template<
class URNG,
bool dummy>
774 class LatentModel<TC>
775 ::FactorSampler<RandomSequenceGenerator<PolarStudentTRng<URNG> > ,
777 typedef URNG urng_type;
779 typedef Sample<std::vector<Real> > sample_type;
784 const std::vector<Real>& varF =
copula.varianceFactors();
786 trng_.push_back(PolarStudentTRng<urng_type>(2. / (1. - i * i), urng_));
788 const sample_type& nextSequence()
const {
790 for(; i<trng_.size(); i++)
791 sequence_.value[i] = trng_[i].next().value;
792 for(; i<sequence_.value.size(); i++)
793 sequence_.value[i] = trng_.back().next().value;
797 mutable sample_type sequence_;
799 mutable std::vector<PolarStudentTRng<urng_type> > trng_;
Gaussian random number generator.
Integrates a vector or scalar function of vector domain.
Shared handle to an observable.
IntegrationBase(Size dimension, Size order)
~IntegrationBase() override=default
std::vector< Real > integrateV(const ext::function< std::vector< Real >(const std::vector< Real > &arg)> &f) const override
Real integrate(const ext::function< Real(const std::vector< Real > &arg)> &f) const override
const std::vector< Real > a_
~IntegrationBase() override=default
IntegrationBase(const std::vector< ext::shared_ptr< Integrator > > &integrators, Real a, Real b)
Real integrate(const ext::function< Real(const std::vector< Real > &arg)> &f) const override
IntegrationBase()=default
virtual std::vector< Real > integrateV(const ext::function< std::vector< Real >(const std::vector< Real > &arg)> &f) const
virtual ~LMIntegration()=default
virtual Real integrate(const ext::function< Real(const std::vector< Real > &arg)> &f) const =0
const sample_type & nextSequence() const
FactorSampler(const copulaType &copula, BigNatural seed=0)
const copulaType & copula_
Sample< std::vector< Real > > sample_type
IntegrationFactory()=default
static ext::shared_ptr< LMIntegration > createLMIntegration(Size dimension, LatentModelIntegrationType::LatentModelIntegrationType type=LatentModelIntegrationType::GaussianQuadrature)
Generic multifactor latent variable model.
Real latentVarValue(const std::vector< Real > &allFactors, Size iVar) const
Handle< Quote > cachedMktFactor_
LatentModel(const Handle< Quote > &singleFactorCorrel, Size nVariables, const typename copulaType::initTraits &ini=copulaType::initTraits())
Real latentVariableCorrel(Size iVar1, Size iVar2) const
Latent variable correlations:
Real inverseCumulativeY(Probability p, Size iVariable) const
std::vector< std::vector< Real > > factorWeights_
Size nVariables_
Number of latent model variables, idiosyncratic terms or model dim.
const std::vector< Real > & idiosyncFctrs() const
Provides values of the normalized idiosyncratic factors .
Real inverseCumulativeDensity(Probability p, Size iFactor) const
Inverse cumulative distribution of the systemic factor iFactor.
const copulaType & copula() const
Size numFactors() const
Number of systemic factors.
Probability density(const std::vector< Real > &m) const
Density function of M, the market/systemic factors.
Probability cumulativeY(Real val, Size iVariable) const
std::vector< Real > allFactorCumulInverter(const std::vector< Real > &probs) const
std::vector< Real > idiosyncFctrs_
LatentModel(Real correlSqr, Size nVariables, const typename copulaType::initTraits &ini=copulaType::initTraits())
LatentModel(const std::vector< Real > &factorsWeight, const typename copulaType::initTraits &ini=copulaType::initTraits())
copulaPolicyImpl copulaType
Probability cumulativeZ(Real z) const
Cumulative distribution of Z, the idiosyncratic/error factors.
const std::vector< std::vector< Real > > & factorWeights() const
Provides values of the factors .
Size numTotalFactors() const
Number of total free random factors; systemic and idiosyncratic.
Real inverseCumulativeZ(Probability p) const
virtual const ext::shared_ptr< LMIntegration > & integration() const
Size nFactors_
Number of systemic factors.
Real integratedExpectedValue(const ext::function< Real(const std::vector< Real > &v1)> &f) const
LatentModel(const std::vector< std::vector< Real > > &factorsWeights, const typename copulaType::initTraits &ini=copulaType::initTraits())
std::vector< Real > integratedExpectedValueV(const ext::function< std::vector< Real >(const std::vector< Real > &v1)> &f) const
Integrates a vector or scalar function of vector domain.
Real operator()(const ext::function< Real(const std::vector< Real > &)> &f, const std::vector< Real > &a, const std::vector< Real > &b) const
Object that notifies its changes to a set of observers.
Object that gets notified when a given observable changes.
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
Integral of a one-dimensional function.
Real Probability
probability
std::size_t Size
size of a container
LatentModelIntegrationType
unsigned QL_BIG_INTEGER BigNatural
large positive integer
QL_DEPRECATED typedef std::vector< Real > result_type
std::vector< Real > operator()(Real d, std::vector< Real > v)