21#ifndef quantlib_latent_model_hpp
22#define quantlib_latent_model_hpp
47 std::transform(
v.begin(),
v.end(),
v.begin(),
48 [=](
Real x) ->
Real { return x * d; });
69 const std::vector<Real>& arg)>&
f)
const = 0;
80 const ext::function<std::vector<Real> (
81 const std::vector<Real>& arg)>&
f)
const {
82 QL_FAIL(
"No vector integration provided");
101 #ifndef QL_PATCH_SOLARIS
109 #ifndef QL_PATCH_SOLARIS
120 return GaussianQuadMultidimIntegrator::integrate<Real>(
f);
123 const ext::function<std::vector<Real>(
const std::vector<Real>& arg)>&
f)
125 return GaussianQuadMultidimIntegrator::integrate<std::vector<Real>>(
f);
136 const std::vector<ext::shared_ptr<Integrator> >& integrators,
139 a_(integrators.size(),a),
b_(integrators.size(),
b) {}
145 const std::vector<Real>
a_,
b_;
277 template <
class copulaPolicyImpl>
290 return copula_.cumulativeY(val, iVariable);
298 #if defined(QL_EXTRA_SAFETY_CHECKS)
300 "Factor size must match that of model.");
306 return copula_.inverseCumulativeDensity(p, iFactor);
311 return copula_.inverseCumulativeY(p, iVariable);
316 return copula_.inverseCumulativeZ(p);
324 return copula_.allFactorCumulInverter(probs);
403 template <
class USNG,
426 typename USNG::sample_type sample =
458 #ifndef QL_PATCH_SOLARIS
467 std::vector<ext::shared_ptr<Integrator> > integrals;
468 for(
Size i=0; i<dimension; i++)
483 ext::make_shared<IntegrationBase<MultidimIntegral> >
484 (integrals, -35., 35.);
487 QL_FAIL(
"Unknown latent model integration type.");
513 const std::vector<std::vector<Real> >& factorsWeights,
514 const typename copulaType::initTraits& ini =
515 typename copulaType::initTraits());
526 const typename copulaType::initTraits& ini =
527 typename copulaType::initTraits());
541 const typename copulaType::initTraits& ini =
typename copulaType::initTraits());
556 const typename copulaType::initTraits& ini =
557 typename copulaType::initTraits());
569 Real init = (iVar1 == iVar2 ?
581 const ext::function<
Real(
const std::vector<Real>& v1)>&
f)
const {
585 [&](
const std::vector<Real>& x){
return copula_.density(x) *
f(x); });
592 const ext::function<std::vector<Real>(
593 const std::vector<Real>& v1)>&
f )
const {
596 [&](
const std::vector<Real>& x){
return M(
copula_.density(x),
f(x)); });
602 virtual const ext::shared_ptr<LMIntegration>&
integration()
const {
603 QL_FAIL(
"Integration non implemented in Latent model.");
643 template <
class Impl>
645 const std::vector<std::vector<Real> >& factorWeights,
646 const typename Impl::initTraits& ini)
647 : factorWeights_(factorWeights),
648 nFactors_(factorWeights[0].size()),
649 nVariables_(factorWeights.size()), copula_(factorWeights, ini)
658 "Name " << i <<
" provides a different number of factors");
662 template <
class Impl>
664 const std::vector<Real>& factorWeights,
665 const typename Impl::initTraits& ini)
667 nVariables_(factorWeights.size())
672 idiosyncFctrs_.push_back(std::sqrt(1. - factorWeight * factorWeight));
677 template <
class Impl>
679 const Real correlSqr,
681 const typename Impl::initTraits& ini)
682 : factorWeights_(nVariables,
std::vector<
Real>(1, correlSqr)),
683 idiosyncFctrs_(nVariables,
684 std::sqrt(1.-correlSqr*correlSqr)),
686 nVariables_(nVariables),
687 copula_(factorWeights_, ini)
690 template <
class Impl>
692 const Handle<Quote>& singleFactorCorrel,
694 const typename Impl::initTraits& ini)
695 : factorWeights_(nVariables,
std::vector<
Real>(1,
696 std::sqrt(singleFactorCorrel->value()))),
697 cachedMktFactor_(singleFactorCorrel),
698 idiosyncFctrs_(nVariables,
699 std::sqrt(1.-singleFactorCorrel->value())),
701 nVariables_(nVariables),
702 copula_(factorWeights_, ini)
709 template <
class Impl>
716 factorWeights_ = std::vector<std::vector<Real> >(nVariables_,
717 std::vector<Real>(1, std::sqrt(cachedMktFactor_->value())));
718 idiosyncFctrs_ = std::vector<Real>(nVariables_,
719 std::sqrt(1.-cachedMktFactor_->value()));
720 copula_ =
copulaType(factorWeights_, copula_.getInitTraits());
741 template<
class TC>
template<
class URNG,
bool dummy>
743 ::FactorSampler <RandomSequenceGenerator<BoxMullerGaussianRng<URNG> > ,
745 typedef URNG urng_type;
753 const sample_type& nextSequence()
const {
754 return boxMullRng_.nextSequence();
757 RandomSequenceGenerator<BoxMullerGaussianRng<urng_type> > boxMullRng_;
767 template<
class TC>
template<
class URNG,
bool dummy>
768 class LatentModel<TC>
769 ::FactorSampler<RandomSequenceGenerator<PolarStudentTRng<URNG> > ,
771 typedef URNG urng_type;
773 typedef Sample<std::vector<Real> > sample_type;
778 const std::vector<Real>& varF =
copula.varianceFactors();
780 trng_.push_back(PolarStudentTRng<urng_type>(2. / (1. - i * i), urng_));
782 const sample_type& nextSequence()
const {
784 for(; i<trng_.size(); i++)
785 sequence_.value[i] = trng_[i].next().value;
786 for(; i<sequence_.value.size(); i++)
787 sequence_.value[i] = trng_.back().next().value;
791 mutable sample_type sequence_;
793 mutable std::vector<PolarStudentTRng<urng_type> > trng_;
Box-Muller Gaussian random-number generator.
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(Real correlSqr, Size nVariables, const typename copulaType::initTraits &ini=typename 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.
LatentModel(const Handle< Quote > &singleFactorCorrel, Size nVariables, const typename copulaType::initTraits &ini=typename copulaType::initTraits())
Probability cumulativeY(Real val, Size iVariable) const
std::vector< Real > allFactorCumulInverter(const std::vector< Real > &probs) const
std::vector< Real > idiosyncFctrs_
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.
LatentModel(const std::vector< std::vector< Real > > &factorsWeights, const typename copulaType::initTraits &ini=typename copulaType::initTraits())
Real integratedExpectedValue(const ext::function< Real(const std::vector< Real > &v1)> &f) const
LatentModel(const std::vector< Real > &factorsWeight, const typename copulaType::initTraits &ini=typename 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.
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
#define QL_FAIL(message)
throw an error (possibly with file and line information)
ext::function< Real(Real)> b
Real Probability
probability
std::size_t Size
size of a container
Globally accessible relinkable pointer.
LatentModelIntegrationType
unsigned QL_BIG_INTEGER BigNatural
large positive integer
ext::shared_ptr< BlackVolTermStructure > v
Polar Student t random-number generator.
purely virtual base class for market observables
Random sequence generator based on a pseudo-random number generator.
std::vector< Real > operator()(Real d, std::vector< Real > v)
integral of a one-dimensional function using the trapezoid formula