prophet_logistic_growth.stan 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. data {
  2. int T; // Sample size
  3. int<lower=1> K; // Number of seasonal vectors
  4. vector[T] t; // Day
  5. vector[T] cap; // Capacities
  6. vector[T] y; // Time-series
  7. int S; // Number of split points
  8. matrix[T, S] A; // Split indicators
  9. int s_indx[S]; // Index of split points
  10. matrix[T,K] X; // season vectors
  11. real<lower=0> sigma; // scale on seasonality prior
  12. real<lower=0> tau; // scale on changepoints prior
  13. }
  14. transformed data {
  15. int s_ext[S + 1]; // Segment endpoints
  16. for (j in 1:S) {
  17. s_ext[j] = s_indx[j];
  18. }
  19. s_ext[S + 1] = T + 1; // Used for the m_adj loop below.
  20. }
  21. parameters {
  22. real k; // Base growth rate
  23. real m; // offset
  24. vector[S] delta; // Rate adjustments
  25. real<lower=0> sigma_obs; // Observation noise (incl. seasonal variation)
  26. vector[K] beta; // seasonal vector
  27. }
  28. transformed parameters {
  29. vector[S] gamma; // adjusted offsets, for piecewise continuity
  30. vector[S + 1] k_s; // actual rate in each segment
  31. real m_pr;
  32. // Compute the rate in each segment
  33. k_s[1] = k;
  34. for (i in 1:S) {
  35. k_s[i + 1] = k_s[i] + delta[i];
  36. }
  37. // Piecewise offsets
  38. m_pr = m; // The offset in the previous segment
  39. for (i in 1:S) {
  40. gamma[i] = (t[s_indx[i]] - m_pr) * (1 - k_s[i] / k_s[i + 1]);
  41. m_pr = m_pr + gamma[i]; // update for the next segment
  42. }
  43. }
  44. model {
  45. //priors
  46. k ~ normal(0, 5);
  47. m ~ normal(0, 5);
  48. delta ~ double_exponential(0, tau);
  49. sigma_obs ~ normal(0, 0.1);
  50. beta ~ normal(0, sigma);
  51. // Likelihood
  52. y ~ normal(cap ./ (1 + exp(-(k + A * delta) .* (t - (m + A * gamma)))) + X * beta, sigma_obs);
  53. }