Coverage Report

Created: 2026-01-25 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/quantlib/ql/experimental/math/gaussiancopulapolicy.hpp
Line
Count
Source
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*
4
 Copyright (C) 2014 Jose Aparicio
5
6
 This file is part of QuantLib, a free-software/open-source library
7
 for financial quantitative analysts and developers - http://quantlib.org/
8
9
 QuantLib is free software: you can redistribute it and/or modify it
10
 under the terms of the QuantLib license.  You should have received a
11
 copy of the license along with this program; if not, please email
12
 <quantlib-dev@lists.sf.net>. The license is also available online at
13
 <https://www.quantlib.org/license.shtml>.
14
15
 This program is distributed in the hope that it will be useful, but WITHOUT
16
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17
 FOR A PARTICULAR PURPOSE.  See the license for more details.
18
*/
19
20
#ifndef quantlib_gaussian_copula_policy_hpp
21
#define quantlib_gaussian_copula_policy_hpp
22
23
#include <ql/math/distributions/normaldistribution.hpp>
24
#include <vector>
25
#include <numeric>
26
#include <algorithm>
27
28
namespace QuantLib {
29
30
    /*! Gaussian Latent Model's copula policy. Its simplicity is a result of 
31
      the convolution stability of the Gaussian distribution.
32
    */
33
    /* This is the only case that would have allowed the policy to be static, 
34
    but other copulas will need parameters and initialization.*/
35
    struct GaussianCopulaPolicy {
36
37
        typedef int initTraits;
38
39
        explicit GaussianCopulaPolicy(
40
            const std::vector<std::vector<Real> >& factorWeights = 
41
                std::vector<std::vector<Real> >(), 
42
            const initTraits& dummy = int())
43
0
        : numFactors_(factorWeights.size() + factorWeights[0].size())
44
0
        {
45
            /* check factors in LM are normalized. */
46
0
            for (const auto& factorWeight : factorWeights) {
47
0
                Real factorsNorm = std::inner_product(factorWeight.begin(), factorWeight.end(),
48
0
                                                      factorWeight.begin(), Real(0.));
49
0
                QL_REQUIRE(factorsNorm < 1., 
50
0
                    "Non normal random factor combination.");
51
0
            }
52
            /* check factor matrix is squared .......... */
53
0
        }
54
55
        /*! Number of independent random factors. 
56
        This is the only methos that ould stop the class from being static, it
57
        is needed for the MC generator construction.
58
        */
59
0
        Size numFactors() const {
60
0
            return numFactors_;
61
0
        }
62
63
        //! returns a copy of the initialization arguments
64
0
        initTraits getInitTraits() const {
65
0
            return initTraits();
66
0
        }
67
68
        /*! Cumulative probability of a given latent variable 
69
            The iVariable parameter is the index of the requested variable.
70
        */
71
0
        Probability cumulativeY(Real val, Size iVariable) const {
72
0
            return cumulative_(val);
73
0
        }
74
        //! Cumulative probability of the idiosyncratic factors (all the same)
75
0
        Probability cumulativeZ(Real z) const {
76
0
            return cumulative_(z);
77
0
        }
78
        /*! Probability density of a given realization of values of the systemic
79
          factors (remember they are independent). In the normal case, since 
80
          they all follow the same law it is just a trivial product of the same 
81
          density. 
82
          Intended to be used in numerical integration of an arbitrary function 
83
          depending on those values.
84
        */
85
0
        Probability density(const std::vector<Real>& m) const {
86
0
            return std::accumulate(m.begin(), m.end(), Real(1.),
87
0
                                   [&](Real x, Real y) -> Real { return x*density_(y); });
88
0
        }
89
        /*! Returns the inverse of the cumulative distribution of the (modelled) 
90
          latent variable (as indexed by iVariable). The normal stability avoids
91
          the convolution of the factors' distributions
92
        */
93
0
        Real inverseCumulativeY(Probability p, Size iVariable) const {
94
0
            return InverseCumulativeNormal::standard_value(p);
95
0
        }
96
        /*! Returns the inverse of the cumulative distribution of the 
97
        idiosyncratic factor (identically distributed for all latent variables)
98
        */
99
0
        Real inverseCumulativeZ(Probability p) const {
100
0
            return InverseCumulativeNormal::standard_value(p);
101
0
        }
102
        /*! Returns the inverse of the cumulative distribution of the 
103
          systemic factor iFactor.
104
        */
105
0
        Real inverseCumulativeDensity(Probability p, Size iFactor) const {
106
0
            return InverseCumulativeNormal::standard_value(p);
107
0
        }
108
        //! 
109
        //to use this (by default) version, the generator must be a uniform one.
110
0
        std::vector<Real> allFactorCumulInverter(const std::vector<Real>& probs) const {
111
0
            std::vector<Real> result;
112
0
            result.resize(probs.size());
113
0
            std::transform(probs.begin(), probs.end(), result.begin(),
114
0
                           [&](Real p){ return InverseCumulativeNormal::standard_value(p); });
115
0
            return result;
116
0
        }
117
    private:
118
        mutable Size numFactors_;
119
        // no op =
120
        static const NormalDistribution density_;
121
        static const CumulativeNormalDistribution cumulative_;
122
    };
123
124
}
125
126
#endif