Skip to content

Commit fdbe189

Browse files
committed
planetary motion case study.
1 parent bf2c0d5 commit fdbe189

File tree

8 files changed

+1174
-0
lines changed

8 files changed

+1174
-0
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
k <- 0.0370383855031032
2+
p0 <-
3+
c(-0.265409729119215, 0.995573007641702)
4+
q0 <-
5+
c(1.04456730637102, 0.221941902167825)
6+
star <-
7+
c(-0.0377712773150063, -0.0703029465489535)
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
2+
functions {
3+
real[] ode (real t,
4+
real[] y,
5+
real[] theta,
6+
real[] x_r, int[] x_i) {
7+
vector[2] q = to_vector({y[1], y[2]});
8+
real r_cube = pow(dot_self(q), 1.5);
9+
vector[2] p = to_vector({y[3], y[4]});
10+
real m = x_r[1];
11+
real k = theta[1];
12+
13+
vector[4] dydt;
14+
dydt[1:2] = p ./ m;
15+
dydt[3:4] = - k * q ./ r_cube;
16+
17+
return to_array_1d(dydt);
18+
}
19+
}
20+
21+
data {
22+
int n;
23+
real q_obs[n, 2];
24+
}
25+
26+
transformed data {
27+
real t0 = 0;
28+
int n_coord = 2;
29+
real q0[n_coord] = {1.0, 0.0};
30+
real p0[n_coord] = {0.0, 1.0};
31+
real y0[n_coord * 2] = append_array(q0, p0);
32+
33+
real m = 1.0;
34+
35+
real t[n];
36+
for (i in 1:n) t[i] = i * 1.0 / 10;
37+
38+
int x_i[0];
39+
40+
real<lower = 0> sigma_x = 0.01;
41+
real<lower = 0> sigma_y = 0.01;
42+
43+
// ODE tuning parameters
44+
real rel_tol = 1e-6; // 1e-12;
45+
real abs_tol = 1e-6; // 1e-12;
46+
int max_steps = 1000; // 1e6
47+
48+
}
49+
50+
parameters {
51+
real<lower = 0> k;
52+
// real<lower = 0> sigma_x;
53+
// real<lower = 0> sigma_y;
54+
}
55+
56+
transformed parameters {
57+
real y[n, n_coord * 2]
58+
= integrate_ode_bdf(ode, y0, t0, t, {k}, {m}, x_i,
59+
rel_tol, abs_tol, max_steps);
60+
}
61+
62+
model {
63+
// sigma_x ~ normal(0, 1);
64+
// sigma_y ~ normal(0, 1);
65+
k ~ normal(0, 1);
66+
// k ~ normal(1, 0.1);
67+
68+
q_obs[, 1] ~ normal(y[, 1], sigma_x);
69+
q_obs[, 2] ~ normal(y[, 2], sigma_y);
70+
}
71+
72+
generated quantities {
73+
// real q_pred[n, 2];
74+
real qx_pred[n];
75+
real qy_pred[n];
76+
77+
qx_pred = normal_rng(y[, 1], sigma_x);
78+
qy_pred = normal_rng(y[, 2], sigma_y);
79+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
2+
// It's assumed that the planet orbits a star at position (0, 0),
3+
// and that the mass of the planet is negligable next to that of
4+
// the star (meaning the star doesn't move).
5+
6+
functions {
7+
real[] ode (real t,
8+
real[] y,
9+
real[] theta,
10+
real[] x_r, int[] x_i) {
11+
vector[2] q = to_vector({y[1], y[2]});
12+
real r_cube = pow(dot_self(q), 1.5);
13+
vector[2] p = to_vector({y[3], y[4]});
14+
real m = x_r[1];
15+
real k = x_r[2];
16+
17+
vector[4] dydt;
18+
dydt[1:2] = p ./ m;
19+
dydt[3:4] = - k * q ./ r_cube;
20+
21+
return to_array_1d(dydt);
22+
}
23+
}
24+
25+
data {
26+
int n;
27+
real<lower = 0> sigma_x;
28+
real<lower = 0> sigma_y;
29+
}
30+
31+
transformed data {
32+
// intial state at t = 0
33+
real t0 = 0;
34+
int n_coord = 2;
35+
real q0[n_coord] = {1.0, 0.0};
36+
real p0[n_coord] = {0.0, 1.0};
37+
real y0[n_coord * 2] = append_array(q0, p0);
38+
39+
// model parameters
40+
real m = 1.0;
41+
real k = 1.0;
42+
43+
// exact motion
44+
real t[n];
45+
for (i in 1:n) t[i] = (i * 1.0) / 10;
46+
real x_r[2] = {m, k};
47+
48+
real theta[0];
49+
int x_i[0];
50+
51+
real y[n, n_coord * 2]
52+
= integrate_ode_rk45(ode, y0, t0, t, theta, x_r, x_i);
53+
}
54+
55+
parameters {
56+
real phi;
57+
}
58+
59+
model {
60+
phi ~ normal(0, 1);
61+
}
62+
63+
generated quantities {
64+
real q_obs[n, 2];
65+
66+
q_obs[, 1] = normal_rng(y[, 1], sigma_x);
67+
q_obs[, 2] = normal_rng(y[, 2], sigma_y);
68+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
2+
// fixes a calculation error in planetary_motion_star.stan.
3+
4+
functions {
5+
real[] ode (real t,
6+
real[] y,
7+
real[] theta,
8+
real[] x_r, int[] x_i) {
9+
vector[2] q = to_vector({y[1], y[2]});
10+
vector[2] s = to_vector({theta[2], theta[3]});
11+
12+
real r_cube = pow(dot_self(q - s), 1.5);
13+
vector[2] p = to_vector({y[3], y[4]});
14+
real m = x_r[1];
15+
real k = theta[1];
16+
17+
vector[4] dydt;
18+
dydt[1:2] = p ./ m;
19+
dydt[3:4] = - k * (q - s) ./ r_cube;
20+
21+
return to_array_1d(dydt);
22+
}
23+
}
24+
25+
data {
26+
int n;
27+
real q_obs[n, 2];
28+
real time[n];
29+
30+
real<lower = 0> sigma;
31+
}
32+
33+
transformed data {
34+
real t0 = 0;
35+
int n_coord = 2;
36+
// real q0[n_coord] = {1.0, 0.0};
37+
// real p0[n_coord] = {0.0, 1.0};
38+
// real y0[n_coord * 2] = append_array(q0, p0);
39+
40+
real m = 1.0;
41+
42+
// real t[n];
43+
// for (i in 1:n) t[i] = i * 1.0 / 10;
44+
45+
int x_i[0];
46+
47+
real<lower = 0> sigma_x = sigma;
48+
real<lower = 0> sigma_y = sigma;
49+
50+
// ODE tuning parameters
51+
real rel_tol = 1e-6;
52+
real abs_tol = 1e-6;
53+
int max_steps = 1000;
54+
55+
}
56+
57+
parameters {
58+
real<lower = 0> k;
59+
real q0[n_coord];
60+
real p0[n_coord];
61+
real star[n_coord];
62+
}
63+
64+
transformed parameters {
65+
real y0[n_coord * 2] = append_array(q0, p0);
66+
real theta[n_coord + 1] = append_array({k}, star);
67+
68+
real y[n, n_coord * 2]
69+
= integrate_ode_rk45(ode, y0, t0, time, theta, {m}, x_i,
70+
rel_tol, abs_tol, max_steps);
71+
}
72+
73+
model {
74+
k ~ normal(1, 0.001); // prior derive based on solar system
75+
// (still pretty uninformative)
76+
77+
p0[1] ~ normal(0, 1);
78+
p0[2] ~ lognormal(0, 1); // impose p0 to be positive.
79+
q0 ~ normal(0, 1);
80+
star ~ normal(0, 0.5);
81+
// star ~ normal(0, 1);
82+
83+
q_obs[, 1] ~ normal(y[, 1], sigma_x);
84+
q_obs[, 2] ~ normal(y[, 2], sigma_y);
85+
}
86+
87+
generated quantities {
88+
// real q_pred[n, 2];
89+
real qx_pred[n];
90+
real qy_pred[n];
91+
92+
qx_pred = normal_rng(y[, 1], sigma_x);
93+
qy_pred = normal_rng(y[, 2], sigma_y);
94+
}
842 KB
Binary file not shown.

0 commit comments

Comments
 (0)