-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathgpbf2.stan
73 lines (72 loc) · 2.4 KB
/
gpbf2.stan
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
73
functions {
#include gpbasisfun_functions.stan
}
data {
int<lower=1> N; // number of observations
vector[N] x; // univariate covariate
vector[N] y; // target variable
real<lower=0> c_f1; // factor c to determine the boundary value L
int<lower=1> M_f1; // number of basis functions for smooth function
int<lower=1> J_f2; // number of cos and sin functions for periodic
}
transformed data {
// Normalize data
real xmean = mean(x);
real ymean = mean(y);
real xsd = sd(x);
real ysd = sd(y);
vector[N] xn = (x - xmean)/xsd;
vector[N] yn = (y - ymean)/ysd;
// Basis functions for f1
real L_f1 = c_f1*max(xn);
matrix[N,M_f1] PHI_f1 = PHI(N, M_f1, L_f1, xn);
// Basis functions for f2
real period_year = 365.25/xsd;
matrix[N,2*J_f2] PHI_f2 = PHI_periodic(N, J_f2, 2*pi()/period_year, xn);
// Concatenated basis functions
matrix[N,M_f1+2*J_f2] PHI_f = append_col(PHI_f1, PHI_f2);
}
parameters {
vector[M_f1] beta_f1; // the basis functions coefficients for f1
vector[2*J_f2] beta_f2; // the basis functions coefficients for f2
real<lower=0> lengthscale_f1; //
real<lower=0> lengthscale_f2; //
real<lower=0> sigma_f1; // scale of f1
real<lower=0> sigma_f2; // scale of f2
real<lower=0> sigma; // residual scale
}
model {
// spectral densities for f1 and f2
vector[M_f1] diagSPD_f1 = diagSPD_EQ(sigma_f1, lengthscale_f1, L_f1, M_f1);
vector[2*J_f2] diagSPD_f2 = diagSPD_periodic(sigma_f2, lengthscale_f2, J_f2);
// priors
beta_f1 ~ normal(0, 1);
beta_f2 ~ normal(0, 1);
lengthscale_f1 ~ lognormal(log(700/xsd), 1);
lengthscale_f2 ~ normal(0, .1);
sigma_f1 ~ normal(0, 1);
sigma_f2 ~ normal(0, 1);
sigma ~ normal(0, .5);
// model
yn ~ normal_id_glm(PHI_f,
0.0,
append_row(diagSPD_f1 .* beta_f1, diagSPD_f2 .* beta_f2),
sigma);
}
generated quantities {
vector[N] f1;
vector[N] f2;
vector[N] f;
vector[N] log_lik;
{
// spectral densities for f1
vector[M_f1] diagSPD_f1 = diagSPD_EQ(sigma_f1, lengthscale_f1, L_f1, M_f1);
vector[2*J_f2] diagSPD_f2 = diagSPD_periodic(sigma_f2, lengthscale_f2, J_f2);
// functions scaled back to original scale
f1 = (0.0 + PHI_f1 * (diagSPD_f1 .* beta_f1))*ysd;
f2 = (PHI_f2 * (diagSPD_f2 .* beta_f2))*ysd;
f = f1 + f2 + ymean;
// log_liks for loo
for (n in 1:N) log_lik[n] = normal_lpdf(y[n] | f[n], sigma*ysd);
}
}