I just realized I do not understand how parameters are treated in Stan.
I built a simple physics model for a thrown object, and estimate the angle thrown based on time and distance. It is straightforward, and it works fine. (See code at end.)
The problem is that I don’t want to estimate the individual angles - for now, I only want to estimate the variance. But if I move the Calc_Angle variable to be a local variable in the model block, the sampler evidently isn’t exploring the space of possible values for those anymore, so the model can’t find a fit for the variances, and therefore doesn’t find a log probability between -2,2, and gives up.
2 questions:
-
Am I understanding that correctly?
-
Is there any way to tell the model to sample a parameter, but not include it in the model that is output?
functions {
vector dist_calc(vector speed, vector angle, vector start_height, real g){
vector[size(to_array_1d(speed))] v_h;
v_h = speed .* sin(angle*pi()/180);
return speed .* cos((angle)*pi()/180) .* ((v_h + sqrt(v_h .* v_h + 2*g*start_height)) / (g));
}
vector angle_calc(vector speed, vector time, vector start_height, real g){
// (180/pi)* asin( ((1/2) * g * measured_time^2 - height_p[Thrower_i])/(measured_speed * measured_time))
return asin(((g/2*(time .* time)-start_height)) ./ (speed .* time))*(180/pi());
}
}
data {
//Data Element Parameters;
int<lower=1> N_i; //Number of input cases per person
int<lower=1> N_p; //Number of throwers
int<lower=1> Thrower_i[N_i*N_p]; //Which thrower threw case i
vector<lower=0>[N_i] measured_speed[N_p]; //Speed Measured for case i in M/s
vector<lower=0>[N_i] measured_time[N_p]; //Time Measured for case i from throw until landing
vector<lower=0>[N_i] measured_distance[N_p]; //Distance Measured for case i in meters
vector<lower=0>[N_p] height_p; // Person P's height.
real<lower=0> g; // Gravity - 9.8 m/s on earth.
}
parameters {
vector[N_i] Calc_Angle[N_p];
real<lower=0> angle_tau;
real<lower=0> overall_distance_tau;
}
model {
angle_tau ~ gamma(4,1);
overall_distance_tau ~ gamma(1,1);
{
for (p in 1:N_p){
Calc_Angle[p] ~ normal(angle_calc(measured_speed[p], measured_time[p], to_vector(rep_array(height_p[p],N_i)),g), angle_tau);
measured_distance[p] ~ normal(dist_calc(measured_speed[p], Calc_Angle[p], to_vector(rep_array(height_p[p],N_i)),g), overall_distance_tau);
}
}
}