SSブログ

Stanで常微分方程式 [統計]

Stan 2.5では常微分方程式が扱えるようになったということなので、マニュアルを参考にためしてみました。

生態学でつかわれるロジスティック式を解かせてみました。式は以下のようなもの:
logistic.png
Nは個体数、rは内的増加率、Kは環境収容力(最大個体数)です。

Stanのコードは以下のように。

functions {
  real[] logistic(real t,
                  real[] y,
                  real[] theta,
                  real[] x_r,
                  int[] x_i) {
    real dNdt[1];
    real r;
    real K;
    real N;
    r <- theta[1];
    K <- theta[2];
    N <- y[1];
    dNdt[1] <- r * N * (K - N) / K;
    return dNdt;
  }
}
data {
  int<lower=1> T;
  real N0;
  real t0;
  real ts[T];
  real theta[2];	// r <- theta[1]; K <- theta[2];
}
transformed data {
  real x_r[0];
  int x_i[0];
}
model {
}
generated quantities {
  real y0[1];
  real y_hat[T, 1];
  y0[1] <- N0;
  y_hat <- integrate_ode(logistic, y0, t0, ts, theta, x_r, x_i);
}

最初に微分方程式を関数として定義しています。マニュアルによれば、この関数にあたえる引数は順番に、時間(real)、状態(real[])、パラメーター(real[])、実データ(real[])、整数データ(int[])で、返り値は各時間における状態(real[])ということです。ここでは時間と、実データ・整数データは実際には使っていません。

modelブロックは空で、generated quantitiesブロックで微分方程式を解いています。integrate_ode()にあたえる引数は順番に、微分方程式を記述した関数、初期状態(real[])、初期時間(intまたはreal[])、解を得る時間(real[])、パラメーター(real[])、実データ(real[])、整数データ(int[])となっています。例によって型は厳密です。

Rコードは以下のように。サンプリングはないので、chains = 1, iter = 1としています。

library(rstan)

N0 <- 1         # Initial population size
r <- 0.1        # Internal growth rate
K <- 30         # Carrying capacity
t0 <- 0         # Initial time
te <- 100       # Endpoint
intvl <- 0.2		# Interval
t <- seq(t0, te, by = intvl)

fit <- stan(file = "logistic.stan",
            data = list(T = length(t) - 1,
                        N0 = N0,
                        t0 = t0,
                        ts = t[-1],
                        theta = c(r, K)),
            chains = 1, iter = 1,
            algorithm = "Fixed_param")
# print(fit)

library(ggplot2)
N <- get_posterior_mean(fit)
N <- N[-length(N)]
p <- ggplot(data.frame(t, N))
p + geom_line(aes(x = t, y = N))

結果

Rplot.png


タグ:STAn RStan
nice!(2)  コメント(0)  トラックバック(1) 
共通テーマ:日記・雑感

nice! 2

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

Facebook コメント

トラックバック 1