diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0feecbe..d63a5d1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,7 +8,7 @@ on: workflow_dispatch: {} env: - CACHE_VERSION: 1 + CACHE_VERSION: 2 # only run one copy per PR concurrency: diff --git a/TODO.md b/TODO.md index 506e3a5..977d222 100644 --- a/TODO.md +++ b/TODO.md @@ -4,7 +4,7 @@ - [x] Add nicer ability to build models from source in the languages - [x] download source if needed, similar to bridgestan - [x] Version checking -- [ ] Fixed param sampler for 0 dimension parameters? +- [-] ~Fixed param sampler for 0 dimension parameters?~ - [ ] Add wrapper around generate quantities method? - [x] Add wraper around laplace sampling? - [x] Pathfinder: expose the no lp/no PSIS version diff --git a/clients/R/R/tinystan.R b/clients/R/R/tinystan.R index eb398bf..4d12699 100644 --- a/clients/R/R/tinystan.R +++ b/clients/R/R/tinystan.R @@ -167,9 +167,6 @@ sampler.tinystan_model = function(model, data = "", num_chains = 4, inits = NULL with_model(model, data, seed, { free_params <- get_free_params(model, model_ptr) - if (free_params == 0) { - stop("Model has no parameters to sample") - } params <- c(HMC_SAMPLER_VARIABLES, get_parameter_names(model, model_ptr)) num_params <- length(params) diff --git a/clients/R/tests/testthat/test_sample.R b/clients/R/tests/testthat/test_sample.R index 7af9b98..ab06cf5 100644 --- a/clients/R/tests/testthat/test_sample.R +++ b/clients/R/tests/testthat/test_sample.R @@ -200,7 +200,7 @@ test_that("bad num_warmup handled properly", { test_that("model with no params fails", { - expect_error(sampler(empty_model), "Model has no parameters") + expect_no_error(sampler(empty_model)) }) diff --git a/clients/julia/src/model.jl b/clients/julia/src/model.jl index 41324c7..84bc8a6 100644 --- a/clients/julia/src/model.jl +++ b/clients/julia/src/model.jl @@ -250,9 +250,6 @@ function sample( with_model(model, data, seed) do model_ptr free_params = num_free_params(model, model_ptr) - if free_params == 0 - error("Model has no parameters to sample") - end param_names = cat(HMC_SAMPLER_VARIABLES, get_names(model, model_ptr), dims = 1) num_params = length(param_names) diff --git a/clients/julia/test/test_sample.jl b/clients/julia/test/test_sample.jl index cda3838..cbf8677 100644 --- a/clients/julia/test/test_sample.jl +++ b/clients/julia/test/test_sample.jl @@ -333,7 +333,9 @@ end @testset "Model without parameters" begin - @test_throws "Model has no parameters to sample" sample(empty_model) + (names, draws, metric) = sample(empty_model; save_metric=true) + @test length(names) == 7 # HMC parameters only + @test prod(size(metric)) == 0 end @testset "Bad num_warmup" begin diff --git a/clients/python/tests/test_sample.py b/clients/python/tests/test_sample.py index 754440a..7b992d4 100644 --- a/clients/python/tests/test_sample.py +++ b/clients/python/tests/test_sample.py @@ -310,9 +310,9 @@ def test_bad_num_warmup(bernoulli_model): def test_model_no_params(empty_model): - with pytest.raises(ValueError, match="Model has no parameters to sample"): - empty_model.sample() - + fit = empty_model.sample(save_metric=True) + assert len(fit.parameters) == 7 # just HMC parameters + assert fit.metric.size == 0 @pytest.mark.parametrize( "arg, value, match", diff --git a/clients/python/tinystan/model.py b/clients/python/tinystan/model.py index cd157f8..3e7ab87 100644 --- a/clients/python/tinystan/model.py +++ b/clients/python/tinystan/model.py @@ -557,8 +557,6 @@ def sample( with self._get_model(data, seed) as model: model_params = self._num_free_params(model) - if model_params == 0: - raise ValueError("Model has no parameters to sample.") param_names = HMC_SAMPLER_VARIABLES + self._get_parameter_names(model) diff --git a/clients/typescript/src/model.ts b/clients/typescript/src/model.ts index 2a2332a..706c4b5 100644 --- a/clients/typescript/src/model.ts +++ b/clients/typescript/src/model.ts @@ -166,9 +166,6 @@ export default class StanModel { const n_params = paramNames.length; const free_params = this.m._tinystan_model_num_free_params(model); - if (free_params === 0) { - throw new Error("Model has no parameters to sample."); - } // TODO: allow init_inv_metric to be specified const init_inv_metric_ptr = NULL; diff --git a/clients/typescript/test/model.test.ts b/clients/typescript/test/model.test.ts index fe57e17..bb2bd5a 100644 --- a/clients/typescript/test/model.test.ts +++ b/clients/typescript/test/model.test.ts @@ -33,9 +33,11 @@ describe("test tinystan code with a mocked WASM module", () => { const { mockedModule, model } = await getMockedModel({ numFreeParams: 0, }); - expect(() => model.sample({})).toThrow(/no parameters/); + const {metric} = model.sample({save_metric:true}); - expect(mockedModule._tinystan_sample).toHaveBeenCalledTimes(0); + expect(metric?.[0]?.length).toEqual(0); + + expect(mockedModule._tinystan_sample).toHaveBeenCalledTimes(1); }); test("failure in model construction throws", async () => { diff --git a/stan b/stan index 3cf3d9e..658755b 160000 --- a/stan +++ b/stan @@ -1 +1 @@ -Subproject commit 3cf3d9ea15705519966ff27f8ceeeaaaa877011f +Subproject commit 658755b43bf1a34bb54149863b889f2f484faa12