Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot provide an empty int-valued list #319

Open
riddell-stan opened this issue Apr 24, 2020 · 5 comments
Open

Cannot provide an empty int-valued list #319

riddell-stan opened this issue Apr 24, 2020 · 5 comments

Comments

@riddell-stan
Copy link
Contributor

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.

@riddell-stan riddell-stan added this to the 2.x milestone Apr 24, 2020
@ahartikainen
Copy link
Contributor

Stanc3 should have this option, because pystan 2 has the same problem.

@riddell-stan
Copy link
Contributor Author

I think cmdstan might have solved this. If this is true, we could copy their solution.

@stale
Copy link

stale bot commented Nov 9, 2020

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.

@stale stale bot added the wontfix label Nov 9, 2020
@stale stale bot closed this as completed Nov 17, 2020
@ahartikainen ahartikainen reopened this Jun 14, 2021
@stale stale bot removed the wontfix label Jun 14, 2021
@ahartikainen
Copy link
Contributor

ahartikainen commented Jun 14, 2021

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

@riddell-stan riddell-stan pinned this issue Jun 24, 2021
@riddell-stan riddell-stan self-assigned this Oct 6, 2021
@stale stale bot added the wontfix label Apr 16, 2022
@stan-dev stan-dev deleted a comment from stale bot Apr 27, 2022
@stale stale bot removed the wontfix label Apr 27, 2022
@stale stale bot added the wontfix label Jul 31, 2022
@stale stale bot removed the wontfix label Oct 8, 2022
@stale stale bot added the wontfix label Jan 8, 2023
@stan-dev stan-dev deleted a comment from stale bot Jan 8, 2023
@stan-dev stan-dev deleted a comment from stale bot Jan 8, 2023
@stale stale bot removed the wontfix label Jan 8, 2023
@stale
Copy link

stale bot commented Jun 18, 2023

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.

@stale stale bot added the wontfix label Jun 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants