Cannot provide an empty int-valued list
Models which use data which contains an empty int-valued list cannot be used.
This does not have a trivial solution since we use JSON for serializing data and JSON cannot distinguish between an empty list of floats and an empty list of ints.
A completely satisfactory solution will probably involve asking Stan or stanc3 to tell us the type of data variables.
Stanc3 should have this option, because pystan 2 has the same problem.
I think cmdstan might have solved this. If this is true, we could copy their solution.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Now with Stan 2.27 stanc3 has --info which returns a dictionary with needed information.
stanc --info path/to/stan_file.stan
(Here is an example with bernoulli example in CmdStan examples.)
{ "inputs": { "N": { "type": "int", "dimensions": 0},
"y": { "type": "int", "dimensions": 1} },
"parameters": { "theta": { "type": "real", "dimensions": 0} },
"transformed parameters": { },
"generated quantities": { },
"functions": [ ],
"distributions": [ "bernoulli_lupmf",
"beta_lupdf" ] }
And in httpstan solution (copy from httpstan/compile) with example from 8-schools (pystan docs)
import httpstan
import stan
import importlib.resources
import tempfile
from pathlib import Path
from typing import List, Union, Tuple
import os
import subprocess
import json
program_code = """
data {
int<lower=0> J; // number of schools
real y[J]; // estimated treatment effects
real<lower=0> sigma[J]; // standard error of effect estimates
}
parameters {
real mu; // population treatment effect
real<lower=0> tau; // standard deviation in treatment effects
vector[J] eta; // unscaled deviation from mu by school
}
transformed parameters {
vector[J] theta = mu + tau * eta; // school treatment effects
}
model {
target += normal_lpdf(eta | 0, 1); // prior log-density
target += normal_lpdf(y | theta, sigma); // log-likelihood
}
"""
schools_data = {"J": 8,
"y": [28, 8, -3, 7, -1, 1, 18, 12],
"sigma": [15, 10, 16, 11, 9, 11, 10, 18]}
posterior = stan.build(program_code, data=schools_data)
def model_info(program_code: str, stan_model_name: str) -> Tuple[str, str]:
with importlib.resources.path(httpstan.__package__, "stanc") as stanc_binary:
with tempfile.TemporaryDirectory(prefix="httpstan_") as tmpdir:
filepath = Path(tmpdir) / f"{stan_model_name}.stan"
with filepath.open("w") as fh:
fh.write(program_code)
run_args: List[Union[os.PathLike, str]] = [
stanc_binary,
"--info",
str(filepath),
]
completed_process = subprocess.run(run_args, capture_output=True, timeout=1)
stderr = completed_process.stderr.decode().strip()
if completed_process.returncode != 0:
raise ValueError(stderr)
return completed_process.stdout.decode().strip(), stderr
model_name = httpstan.models.calculate_model_name(program_code)
stan_model_name = f"model_{model_name.split('/')[1]}"
stdout, stderr = model_info(program_code, stan_model_name)
model_input_info = json.loads(stdout)
model_input_info
{'inputs': {'J': {'type': 'int', 'dimensions': 0},
'y': {'type': 'real', 'dimensions': 1},
'sigma': {'type': 'real', 'dimensions': 1}},
'parameters': {'mu': {'type': 'real', 'dimensions': 0},
'tau': {'type': 'real', 'dimensions': 0},
'eta': {'type': 'real', 'dimensions': 1}},
'transformed parameters': {'theta': {'type': 'real', 'dimensions': 1}},
'generated quantities': {},
'functions': [],
'distributions': ['normal_lpdf']}
edit. Fix code
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.