library(rstan)
stan.code <- '
data {
int<lower=1> T; # Number of time points
real noise; # Noise to add to covariance
int<lower=1,upper=3> COVFN; # Choose covariance function
}
parameters {
vector[T] tau; # Pseudotime
}
transformed parameters {
cov_matrix[T] Sigma; # Covariance matrix over pseudotime
for (t1 in 1:T) {
for (t2 in 1:t1) {
real d;
d <- tau[t1] - tau[t2];
if (1 == COVFN) {
# Matern32 covariance
real x32;
x32 <- sqrt(3) * d;
Sigma[t1,t2] <- (1 + x32) * exp(-x32);
} else if (2 == COVFN) {
# Matern52 covariance
real x52;
x52 <- sqrt(5) * d;
Sigma[t1,t2] <- (1 + x52 + pow(x52, 2) / 3) * exp(-x52);
} else if (3 == COVFN) {
# Squared exponential covariance
Sigma[t1,t2] <- exp(- pow(d, 2) / 2);
}
if (t1 != t2) {
Sigma[t2,t1] <- Sigma[t1,t2];
} else {
Sigma[t1,t1] <- Sigma[t1,t1] + noise; # Add noise
}
}
}
}
model {
tau ~ normal(0, 1);
}
'
compiled <- stan(model_code=stan.code, chains=0)
stan.data <- list(T=100, noise=0.0, COVFN=3)
# Define a function to initialise the chains
init.chain <- function() { list(tau=rnorm(stan.data$T)) }
# Try one iteration to check everything is OK
fit <- stan(fit=compiled, data=stan.data, init=init.chain, iter=1, chains=1)
> sessionInfo()
R version 3.0.2 (2013-09-25)
Platform: x86_64-pc-linux-gnu (64-bit)
locale:
[1] LC_CTYPE=en_GB.UTF-8 LC_NUMERIC=C LC_TIME=en_GB.UTF-8 LC_COLLATE=en_GB.UTF-8
[5] LC_MONETARY=en_GB.UTF-8 LC_MESSAGES=en_GB.UTF-8 LC_PAPER=en_GB.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C LC_MEASUREMENT=en_GB.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] rstan_2.4.0 inline_0.3.13 Rcpp_0.11.3 vimcom_0.9-93 setwidth_1.0-3
loaded via a namespace (and not attached):
[1] codetools_0.2-9 stats4_3.0.2 tools_3.0.2
Has any one got any helpful ideas?
I've tried that trick but then it falls over using it in multi_normal_log so I'm not sure what to try next.
--
You received this message because you are subscribed to the Google Groups "Stan users mailing list" group.
To unsubscribe from this group and stop receiving emails from it, send an email to stan-users+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
> If you are sure that you are using a positive definite kernel (which Matern is) to construct the covariance matrix, then go ahead and declare it as a matrix[T,T] rather than a cov_matrix[T]. That will circumvent the check for positive definiteness, which is numerically unstable.
I've tried that trick but then it falls over using it in multi_normal_log so I'm not sure what to try next.
y ~ multi_normal_cholesky(mu, cholesky_decompose(Sigma));
Add a constant term to the diagonal — Matern is theoretically guaranteed to bepositive-definite but that doesn’t mean that it will be positive-definite in practice,especially when using floating-point arithmetic.
> fit <- stan(fit=compiled,
data=stan.data, init=init.chain, iter=1, chains=1)
SAMPLING FOR MODEL 'stan.code' NOW (CHAIN 1).
Error in eval(expr, envir, enclos) :
Rejecting user-specified initialization because of vanishing
density.
error occurred during calling the sampler; sampling not done
On 1 Nov 2014 14:24, "Ben Goodrich" <goodri...@gmail.com> wrote:
> What are your inits? It shouldn't be necessary to specify them, but if you are starting with an identity matrix or something and getting this message, then probably there is a problem with your Stan program.
Well the program is very simple, just what I sent in the first post with what you recommended added. The inits are just a random draw from a unit normal. I will post it when I get back to my machine.
John.
On Saturday, 1 November 2014 20:59:34 UTC, John Reid wrote:
On 1 Nov 2014 14:24, "Ben Goodrich" <> wrote:
> What are your inits? It shouldn't be necessary to
specify them, but if you are starting with an identity matrix or
something and getting this message, then probably there is a problem
with your Stan program.
Well the program is very simple, just what I sent in the
first post with what you recommended added. The inits are just a random
draw from a unit normal. I will post it when I get back to my machine.
John.
Here's the code. Playing around with stan.data
allows you to quickly see what is possible and what isn't:
library(rstan)
stan.code <- '
data {
int<lower=1> T; # Number of time points
real noise; # Noise to add to covariance
int<lower=1,upper=3> COVFN; # Choose covariance function
}
parameters {
vector[T] tau; # Pseudotime
vector[T] y; # Outcomes
}
transformed parameters {
matrix[T,T] Sigma; # Covariance matrix over pseudotime
for (t1 in 1:T) {
for (t2 in 1:t1) {
real d;
d <- tau[t1] - tau[t2];
if (1 == COVFN) {
# Matern32 covariance
real x32;
x32 <- sqrt(3) * d;
Sigma[t1,t2] <- (1 + x32) * exp(-x32);
} else if (2 == COVFN) {
# Matern52 covariance
real x52;
x52 <- sqrt(5) * d;
Sigma[t1,t2] <- (1 + x52 + pow(x52, 2) / 3) * exp(-x52);
} else if (3 == COVFN) {
# Squared exponential covariance
Sigma[t1,t2] <- exp(- pow(d, 2) / 2);
}
if (t1 != t2) {
Sigma[t2,t1] <- Sigma[t1,t2];
} else {
Sigma[t1,t1] <- Sigma[t1,t1] + noise; # Add noise
}
}
}
}
model {
tau ~ normal(0, 1);
# y ~ multi_normal(rep_vector(0, T), Sigma);
y ~ multi_normal_cholesky(rep_vector(0, T), cholesky_decompose(Sigma));
}
'
compiled <- stan(model_code=stan.code, chains=0)
stan.data <- list(T=100, noise=0.0, COVFN=3)
# Define a function to initialise the chains
init.chain <- function() { with(stan.data, list(tau=rnorm(T), y=rep(0,T))) }
# Try one iteration to check everything is OK
fit <- stan(fit=compiled, data=stan.data, init=init.chain, iter=1, chains=1)
sessionInfo()Those aren’t Matern covariance functions -- replace d with | d |.