Coverage Report

Created: 2026-02-03 07:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/quantlib/ql/experimental/math/convolvedstudentt.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 convolved_student_t_hpp
21
#define convolved_student_t_hpp
22
23
#include <ql/types.hpp>
24
#include <vector>
25
#include <numeric>
26
#include <functional>
27
28
namespace QuantLib {
29
30
    /*! \brief Cumulative (generalized) BehrensFisher distribution.
31
32
    Exact analitical computation of the cumulative probability distribution of
33
    the linear combination of an arbitrary number (not just two) of T random
34
    variables of odd integer order. Adapted from the algorithm in:\par
35
        V. Witkovsky, Journal of Statistical Planning and Inference 94
36
        (2001) 1-13\par
37
    see also:\par
38
        On the distribution of a linear combination of t-distributed
39
        variables; Glenn Alan Walker, Ph.D.thesis University of Florida 1977\par
40
        'Convolutions of the T Distribution'; S. Nadarajah, D. K. Dey in
41
        Computers and Mathematics with Applications 49 (2005) 715-721\par
42
    The last reference provides direct expressions for some of the densities
43
    when the linear combination of only two Ts is just an addition. It can be
44
    used for testing the results here.\par
45
    Another available test on this algorithm stems from the realization that a
46
    linear convex (\f$ \sum a_i=1\f$) combination of Ts of order one is stable
47
    in the distribution sense (but this result is often of no practical use
48
    because of its non-finite variance).\par
49
    This implementation is for two or more T variables in the linear
50
    combination albeit these must be of odd order. The case of exactly two T of
51
    odd order is known to be a finite mixture of Ts but that result is not used
52
    here. On this line see 'Linearization coefficients of Bessel polynomials'
53
    C.Berg, C.Vignat; February 2008; arXiv:math/0506458
54
55
        \todo Implement the series expansion solution for the addition of
56
        two Ts of even order described in: 'On the density of the sum of two
57
        independent Student t-random vectors' C.Berg, C.Vignat; June 2009;
58
        eprint arXiv:0906.3037
59
    */
60
    class CumulativeBehrensFisher { // ODD orders only by now, rename?
61
    public:
62
        /*!
63
            @param degreesFreedom Degrees of freedom of the Ts convolved. The
64
                algorithm is limited to odd orders only.
65
            @param factors Factors in the linear combination of the Ts.
66
        */
67
        CumulativeBehrensFisher(
68
            const std::vector<Integer>& degreesFreedom = std::vector<Integer>(),
69
            const std::vector<Real>& factors = std::vector<Real>());
70
71
        //! Degrees of freedom of the Ts involved in the convolution.
72
0
        const std::vector<Integer>& degreeFreedom() const {
73
0
            return degreesFreedom_;
74
0
        }
75
        //! Factors in the linear combination.
76
0
        const std::vector<Real>& factors() const {
77
0
            return factors_;
78
0
        }
79
    private:
80
        /*! \brief Student t characteristic polynomials.
81
82
        Generates the polynomial coefficients defining the characteristic
83
        function of a T distribution \f$T_\nu\f$ of odd order; \f$\nu=2n+1\f$.
84
        In general the characteristic function is given by:
85
        \f[
86
        \phi_{\nu}(t) = \varphi_{n}(t) \exp{-\nu^{1/2}|t|} ;\,where\,\nu = 2n+1
87
        \f]
88
        where \f$ \varphi \f$ are polynomials that are computed recursively.
89
90
        The convolved characteristic function is the product of the two previous
91
        characteristic functions and the problem is then the convolution (a
92
        product) of two polynomials.
93
94
            @param n Natural number defining the order of the T for which
95
            the characteristic function is to be computed. The order of the
96
             T is then \f$ \nu=2n+1 \f$
97
        */
98
        // move outside of the class, as a separate problem?
99
        std::vector<Real> polynCharactT(Natural n) const;
100
101
        std::vector<Real> convolveVectorPolynomials(
102
            const std::vector<Real>& v1,
103
            const std::vector<Real>& v2) const ;
104
    public:
105
        /*! \brief Returns the cumulative probability of the resulting
106
        distribution.\par
107
            To obtain the cumulative probability the Gil-Pelaez theorem
108
              is applied:\par
109
            First compute the characteristic function of the linear combination
110
            variable by multiplying the individual characteristic functions.
111
            Then transform back integrating the characteristic function
112
            according to the GP theorem; this is done here analytically feeding
113
            in the expression of the total characteristic
114
            function this:
115
            \f[ \int_0^{\infty}x^n e^{-ax}sin(bx)dx =
116
                (-1)^n \Gamma(n+1) \frac{sin((n+1)arctg2(-b/a))}
117
                    {(\sqrt{a^2+b^2})^{n+1}}; for\,a>0,\,b>0
118
            \f]
119
            and for the first term I use:
120
            \f[
121
            \int_0^{\infty} \frac{e^{-ax}sin(bx)}{x} dx = arctg2(b/a)
122
            \f]
123
            The GP complex integration is simplified thanks to the symetry of
124
            the distribution.
125
        */
126
      Probability operator()(Real x) const;
127
128
      /*! \brief Returns the probability density of the resulting
129
      distribution.\par
130
          Similarly to the cumulative probability, Gil-Pelaez theorem is
131
          applied, the integration is similar.
132
133
          \todo Implement in a separate class? given the name of this class..
134
      */
135
      Probability density(Real x) const;
136
137
    private:
138
        mutable std::vector<Integer> degreesFreedom_;
139
        mutable std::vector<Real> factors_;
140
141
        mutable std::vector<std::vector<Real> > polynCharFnc_;
142
        mutable std::vector<Real> polyConvolved_;
143
144
        // cached factor in the exponential of the characteristic function
145
        mutable Real a_ = 0., a2_;
146
    };
147
148
149
150
    /*! \brief Inverse of the cumulative of the convolution of odd-T
151
    distributions
152
153
    Finds the inverse through a root solver. To find limits for the solver
154
    domain use is made of the property that the convolved distribution is
155
    bounded above by the normalized gaussian. If the coeffiecient in the linear
156
    combination add up to a number below one the T of order one can be used as
157
    a limit below but in general this is not necessarily the case and a constant
158
    is used.
159
    Also the fact that the combination is symmetric is used.
160
     */
161
    class InverseCumulativeBehrensFisher {
162
    public:
163
        /*!
164
            @param degreesFreedom Degrees of freedom of the Ts convolved. The
165
                algorithm is limited to odd orders only.
166
            @param factors Factors in the linear combination of the Ts.
167
            @param accuracy The accuracy of the root-solving process.
168
        */
169
        InverseCumulativeBehrensFisher(
170
            const std::vector<Integer>& degreesFreedom = std::vector<Integer>(),
171
            const std::vector<Real>& factors = std::vector<Real>(),
172
            Real accuracy = 1.e-6);
173
        //! Returns the cumulative inverse value.
174
        Real operator()(Probability q) const;
175
176
      private:
177
        mutable Real normSqr_, accuracy_;
178
        mutable CumulativeBehrensFisher distrib_;
179
    };
180
181
}
182
183
#endif