/
sdv_multi.cpp
72 lines (59 loc) · 1.6 KB
/
sdv_multi.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// Multivatiate SV model from Skaug and Yu 2013, Comp. Stat & data Analysis (to appear)
#include <TMB.hpp>
template<class Type>
Type objective_function<Type>::operator() ()
{
DATA_INTEGER(n);
DATA_INTEGER(p);
DATA_ARRAY(y);
PARAMETER_VECTOR(phi);
PARAMETER_VECTOR(log_sigma);
PARAMETER_VECTOR(mu_x);
PARAMETER_VECTOR(off_diag_x);
PARAMETER_ARRAY(h);
int i,j;
Type g=0;
vector<Type> sigma=exp(log_sigma);
// Likelihood contribution: stationary distribution for initial state
vector<Type> tmp(p);
for(j=0;j<p;j++)
tmp(j) = sigma(j)/sqrt(Type(1.0)-phi(j)*phi(j));
g -= sum(dnorm(vector<Type>(h.col(0)),Type(0),tmp,1));
// Likelihood contribution: State transitions
for(i=1;i<n;i++)
{
vector<Type> tmp2(p);
for(j=0;j<p;j++)
tmp2(j) = phi(j)*h(j,i-1);
g -= sum(dnorm(vector<Type>(h.col(i)),tmp2,sigma,1));
}
// Cholesky factor of Sigma
matrix<Type> L(p,p);
L.setIdentity();
int k=0;
for(i=1;i<p;i++)
{
Type Norm2=L(i,i);
for(j=0;j<=i-1;j++)
{
L(i,j) = off_diag_x(k++);
Norm2 += L(i,j)*L(i,j);
}
for(j=0;j<=i;j++)
L(i,j) /= sqrt(Norm2);
}
matrix<Type> Sigma = L * L.transpose();
using namespace density;
// Likelihood contribution: observations
for(i=0;i<n;i++)
{
vector<Type> sigma_y = exp(Type(0.5)*(mu_x + vector<Type>(h.col(i))));
// Scale up correlation matrix
matrix<Type> Sigma_y(p,p);
for(int i2=0;i2<p;i2++)
for(j=0;j<p;j++)
Sigma_y(i2,j) = Sigma(i2,j)*sigma_y(i2)*sigma_y(j);
g += MVNORM(Sigma_y, false /* no atomic */)(vector<Type>(y.col(i)));
}
return g;
}