2019-06-19 14:34:30 +02:00
|
|
|
|
/*
|
|
|
|
|
* Copyright © 2007 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
|
2021-06-09 17:33:48 +02:00
|
|
|
|
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
2019-06-19 14:34:30 +02:00
|
|
|
|
*/
|
2019-01-04 16:29:57 +01:00
|
|
|
|
|
|
|
|
|
#include "normal_conjugate.hh"
|
|
|
|
|
#include "kord_exception.hh"
|
|
|
|
|
|
2019-06-11 16:45:09 +02:00
|
|
|
|
// NormalConj diffuse prior constructor
|
2019-01-04 16:29:57 +01:00
|
|
|
|
NormalConj::NormalConj(int d)
|
|
|
|
|
: mu(d), kappa(0), nu(-1), lambda(d, d)
|
|
|
|
|
{
|
|
|
|
|
mu.zeros();
|
|
|
|
|
lambda.zeros();
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-11 16:45:09 +02:00
|
|
|
|
// NormalConj data update constructor
|
2019-01-04 16:29:57 +01:00
|
|
|
|
NormalConj::NormalConj(const ConstTwoDMatrix &ydata)
|
2019-04-16 12:40:50 +02:00
|
|
|
|
: mu(ydata.nrows()), kappa(ydata.ncols()), nu(ydata.ncols()-1),
|
|
|
|
|
lambda(ydata.nrows(), ydata.nrows())
|
2019-01-04 16:29:57 +01:00
|
|
|
|
{
|
|
|
|
|
mu.zeros();
|
2019-04-16 12:40:50 +02:00
|
|
|
|
for (int i = 0; i < ydata.ncols(); i++)
|
|
|
|
|
mu.add(1.0/ydata.ncols(), ydata.getCol(i));
|
2019-01-04 16:29:57 +01:00
|
|
|
|
|
|
|
|
|
lambda.zeros();
|
2019-04-16 12:40:50 +02:00
|
|
|
|
for (int i = 0; i < ydata.ncols(); i++)
|
2019-01-04 16:29:57 +01:00
|
|
|
|
{
|
Dynare++ / sylvester equation solver: refactor Vector and ConstVector classes
- these classes now encapsulate a std::shared_ptr<{const, }double>, so that
they do not perform memory management, and several {Const,}Vector instances
can transparently share the same underlying data
- make converting constructor from ConstVector to Vector explicit, since that
entails memory allocation (but the reverse conversion is almost costless, so
keep it implicit); do the same for GeneralMatrix/ConstGeneralMatrix,
TwoDMatrix/ConstTwoDMatrix
- remove the constructors that were extracting a row/column from a matrix, and
replace them by getRow() and getCol() methods on {Const,}GeneralMatrix
- rename and change the API of the complex version Vector::add(), so that it is
explicit that it deals with complex numbers
- add constructors that take a MATLAB mxArray
2019-01-22 16:07:44 +01:00
|
|
|
|
Vector diff{ydata.getCol(i)};
|
2019-01-04 16:29:57 +01:00
|
|
|
|
diff.add(-1, mu);
|
|
|
|
|
lambda.addOuter(diff);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-11 16:45:09 +02:00
|
|
|
|
// NormalConj::update() one observation code
|
2019-01-04 16:29:57 +01:00
|
|
|
|
/* The method performs the following:
|
2019-06-11 16:45:09 +02:00
|
|
|
|
|
|
|
|
|
κ₀ 1
|
|
|
|
|
μ₁ = ──── μ₀ + ──── y
|
|
|
|
|
κ₀+1 κ₀+1
|
|
|
|
|
|
|
|
|
|
κ₁ = κ₀ + 1
|
|
|
|
|
|
|
|
|
|
ν₁ = ν₀ + 1
|
|
|
|
|
|
|
|
|
|
κ₀
|
|
|
|
|
Λ₁ = Λ₀ + ──── (y − μ₀)(y − μ₀)ᵀ
|
|
|
|
|
κ₀+1
|
|
|
|
|
*/
|
2019-01-04 16:29:57 +01:00
|
|
|
|
void
|
|
|
|
|
NormalConj::update(const ConstVector &y)
|
|
|
|
|
{
|
|
|
|
|
KORD_RAISE_IF(y.length() != mu.length(),
|
|
|
|
|
"Wrong length of a vector in NormalConj::update");
|
|
|
|
|
|
|
|
|
|
mu.mult(kappa/(1.0+kappa));
|
|
|
|
|
mu.add(1.0/(1.0+kappa), y);
|
|
|
|
|
|
|
|
|
|
Vector diff(y);
|
|
|
|
|
diff.add(-1, mu);
|
|
|
|
|
lambda.addOuter(diff, kappa/(1.0+kappa));
|
|
|
|
|
|
|
|
|
|
kappa++;
|
|
|
|
|
nu++;
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-11 16:45:09 +02:00
|
|
|
|
// NormalConj::update() multiple observations code
|
2019-01-04 16:29:57 +01:00
|
|
|
|
/* The method evaluates the formula in the header file. */
|
|
|
|
|
void
|
|
|
|
|
NormalConj::update(const ConstTwoDMatrix &ydata)
|
|
|
|
|
{
|
|
|
|
|
NormalConj nc(ydata);
|
|
|
|
|
update(nc);
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-11 16:45:09 +02:00
|
|
|
|
// NormalConj::update() with NormalConj code
|
2019-01-04 16:29:57 +01:00
|
|
|
|
void
|
|
|
|
|
NormalConj::update(const NormalConj &nc)
|
|
|
|
|
{
|
2019-03-07 18:17:43 +01:00
|
|
|
|
double wold = static_cast<double>(kappa)/(kappa+nc.kappa);
|
2019-01-04 16:29:57 +01:00
|
|
|
|
double wnew = 1-wold;
|
|
|
|
|
|
|
|
|
|
mu.mult(wold);
|
|
|
|
|
mu.add(wnew, nc.mu);
|
|
|
|
|
|
|
|
|
|
Vector diff(nc.mu);
|
|
|
|
|
diff.add(-1, mu);
|
|
|
|
|
lambda.add(1.0, nc.lambda);
|
|
|
|
|
lambda.addOuter(diff);
|
|
|
|
|
|
|
|
|
|
kappa = kappa + nc.kappa;
|
|
|
|
|
nu = nu + nc.kappa;
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-11 16:45:09 +02:00
|
|
|
|
/* This returns 1/(ν−d−1)·Λ, which is the mean of the variance in the posterior
|
|
|
|
|
distribution. If the number of degrees of freedom is less than d, then NaNs
|
|
|
|
|
are returned. */
|
2019-01-04 16:29:57 +01:00
|
|
|
|
void
|
|
|
|
|
NormalConj::getVariance(TwoDMatrix &v) const
|
|
|
|
|
{
|
|
|
|
|
if (nu > getDim()+1)
|
|
|
|
|
{
|
2019-03-07 18:17:43 +01:00
|
|
|
|
v = const_cast<const TwoDMatrix &>(lambda);
|
2019-01-04 16:29:57 +01:00
|
|
|
|
v.mult(1.0/(nu-getDim()-1));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
v.nans();
|
|
|
|
|
}
|