1 /*
2  * Copyright © 2004 Ondra Kamenik
3  * Copyright © 2019 Dynare Team
4  *
5  * This file is part of Dynare.
6  *
7  * Dynare is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * Dynare is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 // Moments of normal distribution.
22 
23 /* Here we calculate the higher order moments of normally distributed
24    random vector u with means equal to zero and given
25    variance-covariance matrix V, i.e. u↝��(0,V). The moment
26    generating function for such distribution is f(t)=e^½tᵀVt. If
27    we derivate it w.r.t. t and unfold the higher dimensional tensors
28    row-wise, we obtain terms like:
29 
30     ∂f(t)/∂t = f(t)·Vt
31     ∂²f(t)/∂t² = f(t)·(Vt⊗v)
32     ∂³f(t)/∂t³ = f(t)·(Vt⊗Vt⊗Vt + P_?(v⊗Vt) + P_?(Vt⊗v) + v⊗Vt)
33     ∂⁴f(t)/∂t⁴ = f(t)·(Vt⊗Vt⊗Vt⊗Vt + S_?(v⊗Vt⊗Vt) + S_?(Vt⊗v⊗Vt) + S_?(Vt⊗Vt⊗v) + S_?(v⊗v))
34 
35    where v is vectorized V (v=vec(V)), and P_? is a suitable row permutation
36    (corresponds to permutation of multidimensional indices) which permutes the
37    tensor data, so that the index of a variable being derived would be the
38    last. This ensures that all (permuted) tensors can be summed yielding a
39    tensor whose indices have some order (in here we chose the order that more
40    recent derivating variables are to the right). Finally, S_? is a suitable sum
41    of various P_?.
42 
43    We are interested in S_? multiplying the Kronecker powers ⊗ⁿv. The S_? is a
44    (possibly) multi-set of permutations of even order. Note that we know the
45    number of permutations in S_?. The above formulas for f(t) derivatives are
46    valid also for monomial u, and from literature we know that 2n-th moment is
47    (2n!)/(n!2ⁿ)·σ². So there are (2n!)/(n!2ⁿ) permutations in S_?.
48 
49    In order to find the S_? permutation we need to define a couple of things.
50    First we define a sort of equivalence between the permutations applicable to
51    even number of indices. We write P₁ ≡ P₂ whenever P₁⁻¹∘P₂ permutes only whole
52    pairs, or items within pairs, but not indices across the pairs. For instance
53    the permutations (0,1,2,3) and (3,2,0,1) are equivalent, but (0,2,1,3) is
54    not equivalent with the two. Clearly, the ≡ relationship is an equivalence.
55 
56    This allows to define a relation ⊑ between the permutation multi-sets S,
57    which is basically the subset relation ⊆ but with respect to the equivalence
58    relation ≡, more formally:
59 
60     S₁ ⊑ S₂  iff  P ∈ S₁ ⇒ ∃Q ∈ S₂ : P ≡ Q
61 
62    This induces an equivalence S₁ ≡ S₂.
63 
64    Now let Fₙ denote a set of permutations on 2n indices which is maximal with
65    respect to ⊑, and minimal with respect to ≡ (in other words, it contains
66    everything up to the equivalence ≡). It is straightforward to calculate a
67    number of permutations in Fₙ. This is a total number of all permutations
68    of 2n divided by permutations of pairs divided by permutations within the
69    pairs. This is (2n!)/(n!2ⁿ).
70 
71    We now prove that S_? ≡ Fₙ. Clearly S_? ⊑ Fₙ, since Fₙ is maximal. In order
72    to prove that Fₙ ⊑ S_?, let us assert that for any permutation P and for
73    any (semi-)positive definite matrix V we have
74    P·S_?(⊗ⁿv)=S_?(⊗ⁿv). Below we show that there is a positive
75    definite matrix V of some dimension that for any two permutation
76    multi-sets S₁, S₂, we have
77 
78     S₁ ≢ S₂  ⇒  S₁(⊗ⁿv) ≠ S₂(⊗ⁿv)
79 
80    So it follows that for any permutation P, we have P·S_? ≡ S_?. For a purpose
81    of contradiction let P ∈ Fₙ be a permutation which is not equivalent to any
82    permutation from S_?. Since S_? is non-empty, let us pick P₀ ∈ S_?. Now
83    assert that P₀⁻¹S_? ≢ P⁻¹S_? since the first contains an identity and the
84    second does not contain a permutation equivalent to identity. Thus we have
85    (P∘P₀⁻¹)S_? ≢ S_? which gives the contradiction and we have proved that
86    Fₙ ⊑ S_?. Thus Fₙ ≡ S_?. Moreover, we know that S_? and Fₙ have the same
87    number of permutations, hence the minimality of S_? with respect to ≡.
88 
89    Now it suffices to prove that there exists a positive definite V such that
90    for any two permutation multi-sets S₁ and S₂ holds S₁ ≢ S₂ ⇒ S₁(⊗ⁿv) ≠ S₂⊗ⁿv.
91    If V is a n×n matrix, then S₁ ≢ S₂ implies that there is
92    identically nonzero polynomial of elements from V of order n over
93    integers. If V=AᵀA then there is identically non-zero polynomial of
94    elements from A of order 2n. This means, that we have to find n(n+1)/2
95    tuple x of real numbers such that all identically non-zero polynomials p
96    of order 2n over integers yield p(x)≠0.
97 
98    The x is constructed as follows: x_i = π^log(rᵢ), where rᵢ is i-th prime.
99    Let us consider the monom x₁^j₁·…·xₖ^jₖ. When the monom is evaluated, we get
100 
101     π^{log(r₁^j₁)+…+log(rₖ^jₖ)}= π^log(r₁^j₁+…+rₖ^jₖ)
102 
103    Now it is easy to see that if an integer combination of such terms is zero,
104    then the combination must be either trivial or sum to 0 and all monoms
105    must be equal. Both cases imply a polynomial identically equal to zero. So,
106    any non-trivial integer polynomial evaluated at x must be non-zero.
107 
108    So, having this result in hand, now it is straightforward to calculate
109    higher moments of normal distribution. Here we define a container, which
110    does the job. In its constructor, we simply calculate Kronecker powers of v
111    and apply Fₙ to ⊗ⁿv. Fₙ is, in fact, a set of all equivalences in sense of
112    class Equivalence over 2n elements, having n classes each of them having
113    exactly 2 elements.
114 */
115 
116 #ifndef NORMAL_MOMENTS_H
117 #define NORMAL_MOMENTS_H
118 
119 #include "t_container.hh"
120 
121 class UNormalMoments : public TensorContainer<URSingleTensor>
122 {
123 public:
124   UNormalMoments(int maxdim, const TwoDMatrix &v);
125 private:
126   void generateMoments(int maxdim, const TwoDMatrix &v);
127   static bool selectEquiv(const Equivalence &e);
128 };
129 
130 class FNormalMoments : public TensorContainer<FRSingleTensor>
131 {
132 public:
133   FNormalMoments(const UNormalMoments &moms);
134 };
135 
136 #endif
137