dynare/mex/sources/libkorder/tl/normal_moments.hh

138 lines
6.5 KiB
C++
Raw Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
* Copyright © 2004 Ondra Kamenik
* Copyright © 2019 Dynare Team
*
* This file is part of Dynare.
*
* Dynare is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Dynare is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
*/
// Moments of normal distribution.
/* Here we calculate the higher order moments of normally distributed
random vector u with means equal to zero and given
variance-covariance matrix V, i.e. u↝𝒩(0,V). The moment
generating function for such distribution is f(t)=e^½tᵀVt. If
we derivate it w.r.t. t and unfold the higher dimensional tensors
row-wise, we obtain terms like:
∂f(t)/∂t = f(t)·Vt
∂²f(t)/∂t² = f(t)·(Vt⊗v)
∂³f(t)/∂t³ = f(t)·(Vt⊗Vt⊗Vt + P_?(v⊗Vt) + P_?(Vt⊗v) + v⊗Vt)
∂⁴f(t)/∂t⁴ = f(t)·(Vt⊗Vt⊗Vt⊗Vt + S_?(v⊗Vt⊗Vt) + S_?(Vt⊗v⊗Vt) + S_?(Vt⊗Vt⊗v) + S_?(v⊗v))
where v is vectorized V (v=vec(V)), and P_? is a suitable row permutation
(corresponds to permutation of multidimensional indices) which permutes the
tensor data, so that the index of a variable being derived would be the
last. This ensures that all (permuted) tensors can be summed yielding a
tensor whose indices have some order (in here we chose the order that more
recent derivating variables are to the right). Finally, S_? is a suitable sum
of various P_?.
We are interested in S_? multiplying the Kronecker powers ⊗ⁿv. The S_? is a
(possibly) multi-set of permutations of even order. Note that we know the
number of permutations in S_?. The above formulas for f(t) derivatives are
valid also for monomial u, and from literature we know that 2n-th moment is
(2n!)/(n!2ⁿ)·σ². So there are (2n!)/(n!2ⁿ) permutations in S_?.
In order to find the S_? permutation we need to define a couple of things.
First we define a sort of equivalence between the permutations applicable to
even number of indices. We write P₁P₂ whenever P₁⁻¹∘P₂ permutes only whole
pairs, or items within pairs, but not indices across the pairs. For instance
the permutations (0,1,2,3) and (3,2,0,1) are equivalent, but (0,2,1,3) is
not equivalent with the two. Clearly, the ≡ relationship is an equivalence.
This allows to define a relation ⊑ between the permutation multi-sets S,
which is basically the subset relation ⊆ but with respect to the equivalence
relation ≡, more formally:
S₁ ⊑ S₂ iff P ∈ S₁ ⇒ ∃Q ∈ S₂: PQ
This induces an equivalence S₁S₂.
Now let Fₙ denote a set of permutations on 2n indices which is maximal with
respect to ⊑, and minimal with respect to ≡ (in other words, it contains
everything up to the equivalence ≡). It is straightforward to calculate a
number of permutations in Fₙ. This is a total number of all permutations
of 2n divided by permutations of pairs divided by permutations within the
pairs. This is (2n!)/(n!2ⁿ).
We now prove that S_?Fₙ. Clearly S_?Fₙ, since Fₙ is maximal. In order
to prove that FₙS_?, let us assert that for any permutation P and for
any (semi-)positive definite matrix V we have
P·S_?(⊗ⁿv)=S_?(⊗ⁿv). Below we show that there is a positive
definite matrix V of some dimension that for any two permutation
multi-sets S₁, S₂, we have
S₁ ≢ S₂ ⇒ S₁(⊗ⁿv) ≠ S₂(⊗ⁿv)
So it follows that for any permutation P, we have P·S_?S_?. For a purpose
of contradiction let PFₙ be a permutation which is not equivalent to any
permutation from S_?. Since S_? is non-empty, let us pick P₀S_?. Now
assert that P₀⁻¹S_?P⁻¹S_? since the first contains an identity and the
second does not contain a permutation equivalent to identity. Thus we have
(P∘P₀⁻¹)S_?S_? which gives the contradiction and we have proved that
FₙS_?. Thus FₙS_?. Moreover, we know that S_? and Fₙ have the same
number of permutations, hence the minimality of S_? with respect to ≡.
Now it suffices to prove that there exists a positive definite V such that
for any two permutation multi-sets S₁ and S₂ holds S₁S₂  S₁(⊗ⁿv)S₂⊗ⁿv.
If V is a n×n matrix, then S₁S₂ implies that there is
identically nonzero polynomial of elements from V of order n over
integers. If V=AᵀA then there is identically non-zero polynomial of
elements from A of order 2n. This means, that we have to find n(n+1)/2
tuple x of real numbers such that all identically non-zero polynomials p
of order 2n over integers yield p(x)≠0.
The x is constructed as follows: x_i = π^log(rᵢ), where rᵢ is i-th prime.
Let us consider the monom x₁^j₁·…·xₖ^jₖ. When the monom is evaluated, we get
π^{log(r₁^j₁)+…+log(rₖ^jₖ)}= π^log(r₁^j₁+…+rₖ^jₖ)
Now it is easy to see that if an integer combination of such terms is zero,
then the combination must be either trivial or sum to 0 and all monoms
must be equal. Both cases imply a polynomial identically equal to zero. So,
any non-trivial integer polynomial evaluated at x must be non-zero.
So, having this result in hand, now it is straightforward to calculate
higher moments of normal distribution. Here we define a container, which
does the job. In its constructor, we simply calculate Kronecker powers of v
and apply Fₙ to ⊗ⁿv. Fₙ is, in fact, a set of all equivalences in sense of
class Equivalence over 2n elements, having n classes each of them having
exactly 2 elements.
*/
#ifndef NORMAL_MOMENTS_HH
#define NORMAL_MOMENTS_HH
#include "t_container.hh"
class UNormalMoments : public TensorContainer<URSingleTensor>
{
public:
UNormalMoments(int maxdim, const TwoDMatrix& v);
private:
void generateMoments(int maxdim, const TwoDMatrix& v);
static bool selectEquiv(const Equivalence& e);
};
class FNormalMoments : public TensorContainer<FRSingleTensor>
{
public:
FNormalMoments(const UNormalMoments& moms);
};
#endif