From b89afbff5785494eb59a1d532aa5543854574cce Mon Sep 17 00:00:00 2001 From: "t.hajimohammadloo" Date: Fri, 19 Apr 2024 14:50:36 +0200 Subject: [PATCH 01/19] adding the thinning parmaeter for thinning the mcmc resutls --- src/openmcmc/mcmc.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/openmcmc/mcmc.py b/src/openmcmc/mcmc.py index d77cc57..2db7d7b 100644 --- a/src/openmcmc/mcmc.py +++ b/src/openmcmc/mcmc.py @@ -32,7 +32,8 @@ class MCMC: specified will be sampler from prior distributions samplers (list): list of the samplers to be used for each parameter to be estimated. n_burn (int): number of initial burn in these iterations are not stored. - n_iter (int): number of iterations which are stored in store. + n_thin (int): number of iterations to thin by. + n_iter (int): number of iterations which are stored in store. For every iteration, n_thin iterations are run. store (dict): dictionary storing MCMC output as np.array for each inference parameter. """ @@ -42,6 +43,7 @@ class MCMC: model: Model n_burn: int = 5000 n_iter: int = 5000 + n_thin: int = 1 store: dict = field(default_factory=dict, init=False) def __post_init__(self): @@ -91,8 +93,9 @@ def run_mcmc(self): """ for i_it in tqdm(range(-self.n_burn, self.n_iter)): - for sampler in self.samplers: - self.state = sampler.sample(self.state) + for _ in range(self.n_thin): + for sampler in self.samplers: + self.state = sampler.sample(self.state) if i_it < 0: continue From fca8594ca30133d1cba671dd49aa43101eb3d68f Mon Sep 17 00:00:00 2001 From: "david.randell" Date: Tue, 30 Apr 2024 15:12:29 +0200 Subject: [PATCH 02/19] updated unit test to include thinning --- tests/test_mcmc.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/tests/test_mcmc.py b/tests/test_mcmc.py index 357db55..18330cc 100644 --- a/tests/test_mcmc.py +++ b/tests/test_mcmc.py @@ -63,16 +63,19 @@ def fix_state(request): @pytest.fixture( - params=[(0, 4000), (2000, 4000), (0, 6000), (2000, 6000)], - ids=["n_burn=0,n_iter=4000", "n_burn=non-zero,n_iter=4000", "n_burn=0,n_iter=6000", "n_burn=non-zero,n_iter=6000"], + params=[(0, 4000, 1), (2000, 4000, 5), (0, 6000, 10), (2000, 6000, 1)], + ids=["n_burn=0,n_iter=4000, n_thin=1", + "n_burn=non-zero,n_iter=4000,n_thin=5", + "n_burn=0,n_iter=6000, n_thin=10", + "n_burn=non-zero,n_iter=6000,n_thin=1"], name="nburn_niter", ) -def fix_nburn_niter(request): +def fix_nburn_niter_nthin(request): """Define the initial state for the MCMC.""" - [n_burn, n_iter] = request.param - nburn_niter = {"nburn": n_burn, "niter": n_iter} + [n_burn, n_iter, n_thin] = request.param + fix_nburn_niter_nthin = {"nburn": n_burn, "niter": n_iter, "nthin": n_thin} - return nburn_niter + return fix_nburn_niter_nthin def test_run_mcmc(state: dict, sampler: list, model: Model, nburn_niter: dict, monkeypatch): @@ -105,10 +108,13 @@ def mock_log_p(self, current_state): monkeypatch.setattr(NormalGamma, "store", mock_store) monkeypatch.setattr(Model, "log_p", mock_log_p) - M = MCMC(state, sampler, model, n_burn=nburn_niter["nburn"], n_iter=nburn_niter["niter"]) + M = MCMC(state, sampler, model, + n_burn=nburn_niter["nburn"], + n_iter=nburn_niter["niter"], + n_thin=nburn_niter["nthin"]) M.store["count"] = 0 M.run_mcmc() - assert M.state["count"] == (M.n_iter + M.n_burn) * len(sampler) + assert M.state["count"] == (M.n_iter + M.n_burn) * len(sampler) * M.n_thin assert M.store["count"] == M.n_iter * len(sampler) From 9e8b9ad43027ed892cbaf2e93c4e878202077155 Mon Sep 17 00:00:00 2001 From: TannazHajiMohammadloo Date: Tue, 30 Apr 2024 13:29:32 +0000 Subject: [PATCH 03/19] renaming the fixture function for iteration. burn and thinning --- tests/test_mcmc.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/test_mcmc.py b/tests/test_mcmc.py index 18330cc..d50a51c 100644 --- a/tests/test_mcmc.py +++ b/tests/test_mcmc.py @@ -68,24 +68,24 @@ def fix_state(request): "n_burn=non-zero,n_iter=4000,n_thin=5", "n_burn=0,n_iter=6000, n_thin=10", "n_burn=non-zero,n_iter=6000,n_thin=1"], - name="nburn_niter", + name="mcmc_settings", ) -def fix_nburn_niter_nthin(request): +def fix_mcmc_settings(request): """Define the initial state for the MCMC.""" [n_burn, n_iter, n_thin] = request.param - fix_nburn_niter_nthin = {"nburn": n_burn, "niter": n_iter, "nthin": n_thin} + fix_mcmc_settings = {"nburn": n_burn, "niter": n_iter, "nthin": n_thin} - return fix_nburn_niter_nthin + return fix_mcmc_settings -def test_run_mcmc(state: dict, sampler: list, model: Model, nburn_niter: dict, monkeypatch): +def test_run_mcmc(state: dict, sampler: list, model: Model, mcmc_settings: dict, monkeypatch): """Test run_mcmc function Checks size is correct for the output parameters of the function (state and store) based on the number of iterations (n_iter) and number of burn (n_burn), i.e., Args: state: dictionary model: Model input - nburn_niter: dictionary of mcmc settings + mcmc_settings: dictionary of mcmc settings monkeypatch object for avoiding computationally expensive mcmc sampler. """ @@ -109,34 +109,34 @@ def mock_log_p(self, current_state): monkeypatch.setattr(Model, "log_p", mock_log_p) M = MCMC(state, sampler, model, - n_burn=nburn_niter["nburn"], - n_iter=nburn_niter["niter"], - n_thin=nburn_niter["nthin"]) + n_burn=mcmc_settings["nburn"], + n_iter=mcmc_settings["niter"], + n_thin=mcmc_settings["nthin"]) M.store["count"] = 0 M.run_mcmc() assert M.state["count"] == (M.n_iter + M.n_burn) * len(sampler) * M.n_thin assert M.store["count"] == M.n_iter * len(sampler) -def test_post_init(state: dict, sampler: list, model: Model, nburn_niter: dict): +def test_post_init(state: dict, sampler: list, model: Model, mcmc_settings: dict): """This function test __pos__init function to check returned store and state parameters are np.array of the dimension n * 1 Args: state: dictionary - nburn_niter: integer + mcmc_settings: integer model: """ - M = MCMC(state, sampler, model, n_iter=nburn_niter["niter"]) + M = MCMC(state, sampler, model, n_iter=mcmc_settings["niter"]) assert isinstance(M.state["count"], np.ndarray) assert M.state["count"].ndim == 2 assert isinstance(M.state["beta"], np.ndarray) assert M.state["beta"].ndim == 2 - assert (len(M.store) - 1) * (M.store["beta"]).shape[1] == len(sampler) * nburn_niter["niter"] - assert M.store["log_post"].size == nburn_niter["niter"] + assert (len(M.store) - 1) * (M.store["beta"]).shape[1] == len(sampler) * mcmc_settings["niter"] + assert M.store["log_post"].size == mcmc_settings["niter"] if len(sampler) > 1: assert isinstance(M.state["tau"], np.ndarray) From 33d1a9edef3d7317435c16be6c028e8f8cf54309 Mon Sep 17 00:00:00 2001 From: code_reformat <> Date: Tue, 30 Apr 2024 13:41:26 +0000 Subject: [PATCH 04/19] Automatic reformat of code Signed-off-by: code_reformat <> --- tests/test_mcmc.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/tests/test_mcmc.py b/tests/test_mcmc.py index d50a51c..b980ff0 100644 --- a/tests/test_mcmc.py +++ b/tests/test_mcmc.py @@ -64,10 +64,12 @@ def fix_state(request): @pytest.fixture( params=[(0, 4000, 1), (2000, 4000, 5), (0, 6000, 10), (2000, 6000, 1)], - ids=["n_burn=0,n_iter=4000, n_thin=1", - "n_burn=non-zero,n_iter=4000,n_thin=5", - "n_burn=0,n_iter=6000, n_thin=10", - "n_burn=non-zero,n_iter=6000,n_thin=1"], + ids=[ + "n_burn=0,n_iter=4000, n_thin=1", + "n_burn=non-zero,n_iter=4000,n_thin=5", + "n_burn=0,n_iter=6000, n_thin=10", + "n_burn=non-zero,n_iter=6000,n_thin=1", + ], name="mcmc_settings", ) def fix_mcmc_settings(request): @@ -108,10 +110,14 @@ def mock_log_p(self, current_state): monkeypatch.setattr(NormalGamma, "store", mock_store) monkeypatch.setattr(Model, "log_p", mock_log_p) - M = MCMC(state, sampler, model, - n_burn=mcmc_settings["nburn"], - n_iter=mcmc_settings["niter"], - n_thin=mcmc_settings["nthin"]) + M = MCMC( + state, + sampler, + model, + n_burn=mcmc_settings["nburn"], + n_iter=mcmc_settings["niter"], + n_thin=mcmc_settings["nthin"], + ) M.store["count"] = 0 M.run_mcmc() assert M.state["count"] == (M.n_iter + M.n_burn) * len(sampler) * M.n_thin From 9bc4635a6f9df2a5e5b9f38961e96641beafba6a Mon Sep 17 00:00:00 2001 From: "t.hajimohammadloo" Date: Fri, 19 Apr 2024 14:50:36 +0200 Subject: [PATCH 05/19] adding the thinning parmaeter for thinning the mcmc resutls Signed-off-by: t.hajimohammadloo --- src/openmcmc/mcmc.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/openmcmc/mcmc.py b/src/openmcmc/mcmc.py index d77cc57..2db7d7b 100644 --- a/src/openmcmc/mcmc.py +++ b/src/openmcmc/mcmc.py @@ -32,7 +32,8 @@ class MCMC: specified will be sampler from prior distributions samplers (list): list of the samplers to be used for each parameter to be estimated. n_burn (int): number of initial burn in these iterations are not stored. - n_iter (int): number of iterations which are stored in store. + n_thin (int): number of iterations to thin by. + n_iter (int): number of iterations which are stored in store. For every iteration, n_thin iterations are run. store (dict): dictionary storing MCMC output as np.array for each inference parameter. """ @@ -42,6 +43,7 @@ class MCMC: model: Model n_burn: int = 5000 n_iter: int = 5000 + n_thin: int = 1 store: dict = field(default_factory=dict, init=False) def __post_init__(self): @@ -91,8 +93,9 @@ def run_mcmc(self): """ for i_it in tqdm(range(-self.n_burn, self.n_iter)): - for sampler in self.samplers: - self.state = sampler.sample(self.state) + for _ in range(self.n_thin): + for sampler in self.samplers: + self.state = sampler.sample(self.state) if i_it < 0: continue From b4ba6065c3591fce7b9254021965c41b233518a3 Mon Sep 17 00:00:00 2001 From: "david.randell" Date: Tue, 30 Apr 2024 15:12:29 +0200 Subject: [PATCH 06/19] updated unit test to include thinning Signed-off-by: t.hajimohammadloo --- tests/test_mcmc.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/tests/test_mcmc.py b/tests/test_mcmc.py index 357db55..18330cc 100644 --- a/tests/test_mcmc.py +++ b/tests/test_mcmc.py @@ -63,16 +63,19 @@ def fix_state(request): @pytest.fixture( - params=[(0, 4000), (2000, 4000), (0, 6000), (2000, 6000)], - ids=["n_burn=0,n_iter=4000", "n_burn=non-zero,n_iter=4000", "n_burn=0,n_iter=6000", "n_burn=non-zero,n_iter=6000"], + params=[(0, 4000, 1), (2000, 4000, 5), (0, 6000, 10), (2000, 6000, 1)], + ids=["n_burn=0,n_iter=4000, n_thin=1", + "n_burn=non-zero,n_iter=4000,n_thin=5", + "n_burn=0,n_iter=6000, n_thin=10", + "n_burn=non-zero,n_iter=6000,n_thin=1"], name="nburn_niter", ) -def fix_nburn_niter(request): +def fix_nburn_niter_nthin(request): """Define the initial state for the MCMC.""" - [n_burn, n_iter] = request.param - nburn_niter = {"nburn": n_burn, "niter": n_iter} + [n_burn, n_iter, n_thin] = request.param + fix_nburn_niter_nthin = {"nburn": n_burn, "niter": n_iter, "nthin": n_thin} - return nburn_niter + return fix_nburn_niter_nthin def test_run_mcmc(state: dict, sampler: list, model: Model, nburn_niter: dict, monkeypatch): @@ -105,10 +108,13 @@ def mock_log_p(self, current_state): monkeypatch.setattr(NormalGamma, "store", mock_store) monkeypatch.setattr(Model, "log_p", mock_log_p) - M = MCMC(state, sampler, model, n_burn=nburn_niter["nburn"], n_iter=nburn_niter["niter"]) + M = MCMC(state, sampler, model, + n_burn=nburn_niter["nburn"], + n_iter=nburn_niter["niter"], + n_thin=nburn_niter["nthin"]) M.store["count"] = 0 M.run_mcmc() - assert M.state["count"] == (M.n_iter + M.n_burn) * len(sampler) + assert M.state["count"] == (M.n_iter + M.n_burn) * len(sampler) * M.n_thin assert M.store["count"] == M.n_iter * len(sampler) From 682a0d0b7c210c1f43738161f429cce5b25e6d62 Mon Sep 17 00:00:00 2001 From: TannazHajiMohammadloo Date: Tue, 30 Apr 2024 13:29:32 +0000 Subject: [PATCH 07/19] renaming the fixture function for iteration. burn and thinning Signed-off-by: t.hajimohammadloo --- tests/test_mcmc.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/test_mcmc.py b/tests/test_mcmc.py index 18330cc..d50a51c 100644 --- a/tests/test_mcmc.py +++ b/tests/test_mcmc.py @@ -68,24 +68,24 @@ def fix_state(request): "n_burn=non-zero,n_iter=4000,n_thin=5", "n_burn=0,n_iter=6000, n_thin=10", "n_burn=non-zero,n_iter=6000,n_thin=1"], - name="nburn_niter", + name="mcmc_settings", ) -def fix_nburn_niter_nthin(request): +def fix_mcmc_settings(request): """Define the initial state for the MCMC.""" [n_burn, n_iter, n_thin] = request.param - fix_nburn_niter_nthin = {"nburn": n_burn, "niter": n_iter, "nthin": n_thin} + fix_mcmc_settings = {"nburn": n_burn, "niter": n_iter, "nthin": n_thin} - return fix_nburn_niter_nthin + return fix_mcmc_settings -def test_run_mcmc(state: dict, sampler: list, model: Model, nburn_niter: dict, monkeypatch): +def test_run_mcmc(state: dict, sampler: list, model: Model, mcmc_settings: dict, monkeypatch): """Test run_mcmc function Checks size is correct for the output parameters of the function (state and store) based on the number of iterations (n_iter) and number of burn (n_burn), i.e., Args: state: dictionary model: Model input - nburn_niter: dictionary of mcmc settings + mcmc_settings: dictionary of mcmc settings monkeypatch object for avoiding computationally expensive mcmc sampler. """ @@ -109,34 +109,34 @@ def mock_log_p(self, current_state): monkeypatch.setattr(Model, "log_p", mock_log_p) M = MCMC(state, sampler, model, - n_burn=nburn_niter["nburn"], - n_iter=nburn_niter["niter"], - n_thin=nburn_niter["nthin"]) + n_burn=mcmc_settings["nburn"], + n_iter=mcmc_settings["niter"], + n_thin=mcmc_settings["nthin"]) M.store["count"] = 0 M.run_mcmc() assert M.state["count"] == (M.n_iter + M.n_burn) * len(sampler) * M.n_thin assert M.store["count"] == M.n_iter * len(sampler) -def test_post_init(state: dict, sampler: list, model: Model, nburn_niter: dict): +def test_post_init(state: dict, sampler: list, model: Model, mcmc_settings: dict): """This function test __pos__init function to check returned store and state parameters are np.array of the dimension n * 1 Args: state: dictionary - nburn_niter: integer + mcmc_settings: integer model: """ - M = MCMC(state, sampler, model, n_iter=nburn_niter["niter"]) + M = MCMC(state, sampler, model, n_iter=mcmc_settings["niter"]) assert isinstance(M.state["count"], np.ndarray) assert M.state["count"].ndim == 2 assert isinstance(M.state["beta"], np.ndarray) assert M.state["beta"].ndim == 2 - assert (len(M.store) - 1) * (M.store["beta"]).shape[1] == len(sampler) * nburn_niter["niter"] - assert M.store["log_post"].size == nburn_niter["niter"] + assert (len(M.store) - 1) * (M.store["beta"]).shape[1] == len(sampler) * mcmc_settings["niter"] + assert M.store["log_post"].size == mcmc_settings["niter"] if len(sampler) > 1: assert isinstance(M.state["tau"], np.ndarray) From 353dfbfe9d83939f8e8d3aa78b876bec93ff457e Mon Sep 17 00:00:00 2001 From: code_reformat <> Date: Tue, 30 Apr 2024 13:41:26 +0000 Subject: [PATCH 08/19] Automatic reformat of code Signed-off-by: code_reformat <> Signed-off-by: t.hajimohammadloo --- tests/test_mcmc.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/tests/test_mcmc.py b/tests/test_mcmc.py index d50a51c..b980ff0 100644 --- a/tests/test_mcmc.py +++ b/tests/test_mcmc.py @@ -64,10 +64,12 @@ def fix_state(request): @pytest.fixture( params=[(0, 4000, 1), (2000, 4000, 5), (0, 6000, 10), (2000, 6000, 1)], - ids=["n_burn=0,n_iter=4000, n_thin=1", - "n_burn=non-zero,n_iter=4000,n_thin=5", - "n_burn=0,n_iter=6000, n_thin=10", - "n_burn=non-zero,n_iter=6000,n_thin=1"], + ids=[ + "n_burn=0,n_iter=4000, n_thin=1", + "n_burn=non-zero,n_iter=4000,n_thin=5", + "n_burn=0,n_iter=6000, n_thin=10", + "n_burn=non-zero,n_iter=6000,n_thin=1", + ], name="mcmc_settings", ) def fix_mcmc_settings(request): @@ -108,10 +110,14 @@ def mock_log_p(self, current_state): monkeypatch.setattr(NormalGamma, "store", mock_store) monkeypatch.setattr(Model, "log_p", mock_log_p) - M = MCMC(state, sampler, model, - n_burn=mcmc_settings["nburn"], - n_iter=mcmc_settings["niter"], - n_thin=mcmc_settings["nthin"]) + M = MCMC( + state, + sampler, + model, + n_burn=mcmc_settings["nburn"], + n_iter=mcmc_settings["niter"], + n_thin=mcmc_settings["nthin"], + ) M.store["count"] = 0 M.run_mcmc() assert M.state["count"] == (M.n_iter + M.n_burn) * len(sampler) * M.n_thin From 020afb54c3df2cd0213e3599fd14d25d367b1f95 Mon Sep 17 00:00:00 2001 From: "t.hajimohammadloo" Date: Fri, 19 Apr 2024 14:50:36 +0200 Subject: [PATCH 09/19] adding the thinning parmaeter for thinning the mcmc resutls --- src/openmcmc/mcmc.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/openmcmc/mcmc.py b/src/openmcmc/mcmc.py index d77cc57..2db7d7b 100644 --- a/src/openmcmc/mcmc.py +++ b/src/openmcmc/mcmc.py @@ -32,7 +32,8 @@ class MCMC: specified will be sampler from prior distributions samplers (list): list of the samplers to be used for each parameter to be estimated. n_burn (int): number of initial burn in these iterations are not stored. - n_iter (int): number of iterations which are stored in store. + n_thin (int): number of iterations to thin by. + n_iter (int): number of iterations which are stored in store. For every iteration, n_thin iterations are run. store (dict): dictionary storing MCMC output as np.array for each inference parameter. """ @@ -42,6 +43,7 @@ class MCMC: model: Model n_burn: int = 5000 n_iter: int = 5000 + n_thin: int = 1 store: dict = field(default_factory=dict, init=False) def __post_init__(self): @@ -91,8 +93,9 @@ def run_mcmc(self): """ for i_it in tqdm(range(-self.n_burn, self.n_iter)): - for sampler in self.samplers: - self.state = sampler.sample(self.state) + for _ in range(self.n_thin): + for sampler in self.samplers: + self.state = sampler.sample(self.state) if i_it < 0: continue From d41b98a4d07089f7a52209d91dd53b1e3dd7edf9 Mon Sep 17 00:00:00 2001 From: "david.randell" Date: Tue, 30 Apr 2024 15:12:29 +0200 Subject: [PATCH 10/19] updated unit test to include thinning Signed-off-by: david.randell --- tests/test_mcmc.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/tests/test_mcmc.py b/tests/test_mcmc.py index 357db55..18330cc 100644 --- a/tests/test_mcmc.py +++ b/tests/test_mcmc.py @@ -63,16 +63,19 @@ def fix_state(request): @pytest.fixture( - params=[(0, 4000), (2000, 4000), (0, 6000), (2000, 6000)], - ids=["n_burn=0,n_iter=4000", "n_burn=non-zero,n_iter=4000", "n_burn=0,n_iter=6000", "n_burn=non-zero,n_iter=6000"], + params=[(0, 4000, 1), (2000, 4000, 5), (0, 6000, 10), (2000, 6000, 1)], + ids=["n_burn=0,n_iter=4000, n_thin=1", + "n_burn=non-zero,n_iter=4000,n_thin=5", + "n_burn=0,n_iter=6000, n_thin=10", + "n_burn=non-zero,n_iter=6000,n_thin=1"], name="nburn_niter", ) -def fix_nburn_niter(request): +def fix_nburn_niter_nthin(request): """Define the initial state for the MCMC.""" - [n_burn, n_iter] = request.param - nburn_niter = {"nburn": n_burn, "niter": n_iter} + [n_burn, n_iter, n_thin] = request.param + fix_nburn_niter_nthin = {"nburn": n_burn, "niter": n_iter, "nthin": n_thin} - return nburn_niter + return fix_nburn_niter_nthin def test_run_mcmc(state: dict, sampler: list, model: Model, nburn_niter: dict, monkeypatch): @@ -105,10 +108,13 @@ def mock_log_p(self, current_state): monkeypatch.setattr(NormalGamma, "store", mock_store) monkeypatch.setattr(Model, "log_p", mock_log_p) - M = MCMC(state, sampler, model, n_burn=nburn_niter["nburn"], n_iter=nburn_niter["niter"]) + M = MCMC(state, sampler, model, + n_burn=nburn_niter["nburn"], + n_iter=nburn_niter["niter"], + n_thin=nburn_niter["nthin"]) M.store["count"] = 0 M.run_mcmc() - assert M.state["count"] == (M.n_iter + M.n_burn) * len(sampler) + assert M.state["count"] == (M.n_iter + M.n_burn) * len(sampler) * M.n_thin assert M.store["count"] == M.n_iter * len(sampler) From 03169783622a169b1cb4ec7a37fdf8ed54ee8ebe Mon Sep 17 00:00:00 2001 From: TannazHajiMohammadloo Date: Tue, 30 Apr 2024 13:29:32 +0000 Subject: [PATCH 11/19] renaming the fixture function for iteration. burn and thinning Signed-off-by: david.randell --- tests/test_mcmc.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/test_mcmc.py b/tests/test_mcmc.py index 18330cc..d50a51c 100644 --- a/tests/test_mcmc.py +++ b/tests/test_mcmc.py @@ -68,24 +68,24 @@ def fix_state(request): "n_burn=non-zero,n_iter=4000,n_thin=5", "n_burn=0,n_iter=6000, n_thin=10", "n_burn=non-zero,n_iter=6000,n_thin=1"], - name="nburn_niter", + name="mcmc_settings", ) -def fix_nburn_niter_nthin(request): +def fix_mcmc_settings(request): """Define the initial state for the MCMC.""" [n_burn, n_iter, n_thin] = request.param - fix_nburn_niter_nthin = {"nburn": n_burn, "niter": n_iter, "nthin": n_thin} + fix_mcmc_settings = {"nburn": n_burn, "niter": n_iter, "nthin": n_thin} - return fix_nburn_niter_nthin + return fix_mcmc_settings -def test_run_mcmc(state: dict, sampler: list, model: Model, nburn_niter: dict, monkeypatch): +def test_run_mcmc(state: dict, sampler: list, model: Model, mcmc_settings: dict, monkeypatch): """Test run_mcmc function Checks size is correct for the output parameters of the function (state and store) based on the number of iterations (n_iter) and number of burn (n_burn), i.e., Args: state: dictionary model: Model input - nburn_niter: dictionary of mcmc settings + mcmc_settings: dictionary of mcmc settings monkeypatch object for avoiding computationally expensive mcmc sampler. """ @@ -109,34 +109,34 @@ def mock_log_p(self, current_state): monkeypatch.setattr(Model, "log_p", mock_log_p) M = MCMC(state, sampler, model, - n_burn=nburn_niter["nburn"], - n_iter=nburn_niter["niter"], - n_thin=nburn_niter["nthin"]) + n_burn=mcmc_settings["nburn"], + n_iter=mcmc_settings["niter"], + n_thin=mcmc_settings["nthin"]) M.store["count"] = 0 M.run_mcmc() assert M.state["count"] == (M.n_iter + M.n_burn) * len(sampler) * M.n_thin assert M.store["count"] == M.n_iter * len(sampler) -def test_post_init(state: dict, sampler: list, model: Model, nburn_niter: dict): +def test_post_init(state: dict, sampler: list, model: Model, mcmc_settings: dict): """This function test __pos__init function to check returned store and state parameters are np.array of the dimension n * 1 Args: state: dictionary - nburn_niter: integer + mcmc_settings: integer model: """ - M = MCMC(state, sampler, model, n_iter=nburn_niter["niter"]) + M = MCMC(state, sampler, model, n_iter=mcmc_settings["niter"]) assert isinstance(M.state["count"], np.ndarray) assert M.state["count"].ndim == 2 assert isinstance(M.state["beta"], np.ndarray) assert M.state["beta"].ndim == 2 - assert (len(M.store) - 1) * (M.store["beta"]).shape[1] == len(sampler) * nburn_niter["niter"] - assert M.store["log_post"].size == nburn_niter["niter"] + assert (len(M.store) - 1) * (M.store["beta"]).shape[1] == len(sampler) * mcmc_settings["niter"] + assert M.store["log_post"].size == mcmc_settings["niter"] if len(sampler) > 1: assert isinstance(M.state["tau"], np.ndarray) From 8be1ecb519cb142d22e36f151c287b3fe51e4f80 Mon Sep 17 00:00:00 2001 From: code_reformat <> Date: Tue, 30 Apr 2024 13:41:26 +0000 Subject: [PATCH 12/19] Automatic reformat of code Signed-off-by: code_reformat <> Signed-off-by: david.randell --- tests/test_mcmc.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/tests/test_mcmc.py b/tests/test_mcmc.py index d50a51c..b980ff0 100644 --- a/tests/test_mcmc.py +++ b/tests/test_mcmc.py @@ -64,10 +64,12 @@ def fix_state(request): @pytest.fixture( params=[(0, 4000, 1), (2000, 4000, 5), (0, 6000, 10), (2000, 6000, 1)], - ids=["n_burn=0,n_iter=4000, n_thin=1", - "n_burn=non-zero,n_iter=4000,n_thin=5", - "n_burn=0,n_iter=6000, n_thin=10", - "n_burn=non-zero,n_iter=6000,n_thin=1"], + ids=[ + "n_burn=0,n_iter=4000, n_thin=1", + "n_burn=non-zero,n_iter=4000,n_thin=5", + "n_burn=0,n_iter=6000, n_thin=10", + "n_burn=non-zero,n_iter=6000,n_thin=1", + ], name="mcmc_settings", ) def fix_mcmc_settings(request): @@ -108,10 +110,14 @@ def mock_log_p(self, current_state): monkeypatch.setattr(NormalGamma, "store", mock_store) monkeypatch.setattr(Model, "log_p", mock_log_p) - M = MCMC(state, sampler, model, - n_burn=mcmc_settings["nburn"], - n_iter=mcmc_settings["niter"], - n_thin=mcmc_settings["nthin"]) + M = MCMC( + state, + sampler, + model, + n_burn=mcmc_settings["nburn"], + n_iter=mcmc_settings["niter"], + n_thin=mcmc_settings["nthin"], + ) M.store["count"] = 0 M.run_mcmc() assert M.state["count"] == (M.n_iter + M.n_burn) * len(sampler) * M.n_thin From c42f73818644ec4e34a3f93cb35682dd1f7aed69 Mon Sep 17 00:00:00 2001 From: bvandekerkhof Date: Thu, 23 May 2024 16:08:28 +0200 Subject: [PATCH 13/19] Update GH tokens Signed-off-by: bvandekerkhof Signed-off-by: david.randell --- .github/workflows/code_formatting.yml | 2 +- .github/workflows/manual_release.yml | 4 ++-- .github/workflows/release_tagging.yml | 4 ++-- .github/workflows/sonarcloud_analysis.yml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/code_formatting.yml b/.github/workflows/code_formatting.yml index d9a1349..16c1ba8 100644 --- a/.github/workflows/code_formatting.yml +++ b/.github/workflows/code_formatting.yml @@ -35,7 +35,7 @@ jobs: - name: Run isort and black when required and commit back if: ${{ failure() || steps.checks.outcome == 'failure'}} env: - GITHUB_ACCESS_TOKEN: ${{ secrets.OPENMCMC_TOKEN }} + GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | isort . black . diff --git a/.github/workflows/manual_release.yml b/.github/workflows/manual_release.yml index 24cb866..9a28245 100644 --- a/.github/workflows/manual_release.yml +++ b/.github/workflows/manual_release.yml @@ -27,7 +27,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Get version env: - GITHUB_ACCESS_TOKEN: ${{ secrets.OPENMCMC_TOKEN }} + GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }} id: version run: | version=$(python .github/get_version.py) @@ -36,4 +36,4 @@ jobs: - name: Create Release run: gh release create ${{ env.BUMPED_VERSION }} --generate-notes env: - GITHUB_TOKEN: ${{ secrets.OPENMCMC_TOKEN }} \ No newline at end of file + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/release_tagging.yml b/.github/workflows/release_tagging.yml index a8ca695..7425671 100644 --- a/.github/workflows/release_tagging.yml +++ b/.github/workflows/release_tagging.yml @@ -27,7 +27,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Get version env: - GITHUB_ACCESS_TOKEN: ${{ secrets.OPENMCMC_TOKEN }} + GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }} id: version run: | version=$(python .github/get_version.py) @@ -36,4 +36,4 @@ jobs: - name: Create Release run: gh release create ${{ env.BUMPED_VERSION }} --generate-notes env: - GITHUB_TOKEN: ${{ secrets.OPENMCMC_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/sonarcloud_analysis.yml b/.github/workflows/sonarcloud_analysis.yml index 048e1dc..cce6049 100644 --- a/.github/workflows/sonarcloud_analysis.yml +++ b/.github/workflows/sonarcloud_analysis.yml @@ -31,7 +31,7 @@ jobs: - name: SonarCloud Scan uses: SonarSource/sonarcloud-github-action@master env: - GITHUB_TOKEN: ${{ secrets.OPENMCMC_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - name: Upload SonarCloud Scan Report uses: actions/upload-artifact@master From 37d2b882c5368626dfa4dbba6384a7face8bd17f Mon Sep 17 00:00:00 2001 From: "david.randell" Date: Wed, 19 Jun 2024 09:42:44 +0200 Subject: [PATCH 14/19] updated unit test to include thinning Signed-off-by: t.hajimohammadloo Signed-off-by: david.randell --- tests/test_mcmc.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/test_mcmc.py b/tests/test_mcmc.py index b980ff0..878c9d7 100644 --- a/tests/test_mcmc.py +++ b/tests/test_mcmc.py @@ -110,6 +110,7 @@ def mock_log_p(self, current_state): monkeypatch.setattr(NormalGamma, "store", mock_store) monkeypatch.setattr(Model, "log_p", mock_log_p) +<<<<<<< HEAD M = MCMC( state, sampler, @@ -118,6 +119,12 @@ def mock_log_p(self, current_state): n_iter=mcmc_settings["niter"], n_thin=mcmc_settings["nthin"], ) +======= + M = MCMC(state, sampler, model, + n_burn=nburn_niter["nburn"], + n_iter=nburn_niter["niter"], + n_thin=nburn_niter["nthin"]) +>>>>>>> b4ba606 (updated unit test to include thinning) M.store["count"] = 0 M.run_mcmc() assert M.state["count"] == (M.n_iter + M.n_burn) * len(sampler) * M.n_thin From 6d69147f46b439431352687c45da214bb5969022 Mon Sep 17 00:00:00 2001 From: "david.randell" Date: Wed, 19 Jun 2024 09:43:54 +0200 Subject: [PATCH 15/19] renaming the fixture function for iteration. burn and thinning Signed-off-by: t.hajimohammadloo Signed-off-by: david.randell --- tests/test_mcmc.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/test_mcmc.py b/tests/test_mcmc.py index 878c9d7..5141eef 100644 --- a/tests/test_mcmc.py +++ b/tests/test_mcmc.py @@ -64,12 +64,10 @@ def fix_state(request): @pytest.fixture( params=[(0, 4000, 1), (2000, 4000, 5), (0, 6000, 10), (2000, 6000, 1)], - ids=[ - "n_burn=0,n_iter=4000, n_thin=1", - "n_burn=non-zero,n_iter=4000,n_thin=5", - "n_burn=0,n_iter=6000, n_thin=10", - "n_burn=non-zero,n_iter=6000,n_thin=1", - ], + ids=["n_burn=0,n_iter=4000, n_thin=1", + "n_burn=non-zero,n_iter=4000,n_thin=5", + "n_burn=0,n_iter=6000, n_thin=10", + "n_burn=non-zero,n_iter=6000,n_thin=1"], name="mcmc_settings", ) def fix_mcmc_settings(request): @@ -121,10 +119,16 @@ def mock_log_p(self, current_state): ) ======= M = MCMC(state, sampler, model, +<<<<<<< HEAD n_burn=nburn_niter["nburn"], n_iter=nburn_niter["niter"], n_thin=nburn_niter["nthin"]) >>>>>>> b4ba606 (updated unit test to include thinning) +======= + n_burn=mcmc_settings["nburn"], + n_iter=mcmc_settings["niter"], + n_thin=mcmc_settings["nthin"]) +>>>>>>> 682a0d0 (renaming the fixture function for iteration. burn and thinning) M.store["count"] = 0 M.run_mcmc() assert M.state["count"] == (M.n_iter + M.n_burn) * len(sampler) * M.n_thin From bc6aa1b45b6bc478c5805539b0b2659e5eb1b9e0 Mon Sep 17 00:00:00 2001 From: "david.randell" Date: Wed, 19 Jun 2024 09:45:23 +0200 Subject: [PATCH 16/19] Automatic reformat of code Signed-off-by: code_reformat <> Signed-off-by: t.hajimohammadloo Signed-off-by: david.randell --- tests/test_mcmc.py | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/tests/test_mcmc.py b/tests/test_mcmc.py index 5141eef..b980ff0 100644 --- a/tests/test_mcmc.py +++ b/tests/test_mcmc.py @@ -64,10 +64,12 @@ def fix_state(request): @pytest.fixture( params=[(0, 4000, 1), (2000, 4000, 5), (0, 6000, 10), (2000, 6000, 1)], - ids=["n_burn=0,n_iter=4000, n_thin=1", - "n_burn=non-zero,n_iter=4000,n_thin=5", - "n_burn=0,n_iter=6000, n_thin=10", - "n_burn=non-zero,n_iter=6000,n_thin=1"], + ids=[ + "n_burn=0,n_iter=4000, n_thin=1", + "n_burn=non-zero,n_iter=4000,n_thin=5", + "n_burn=0,n_iter=6000, n_thin=10", + "n_burn=non-zero,n_iter=6000,n_thin=1", + ], name="mcmc_settings", ) def fix_mcmc_settings(request): @@ -108,7 +110,6 @@ def mock_log_p(self, current_state): monkeypatch.setattr(NormalGamma, "store", mock_store) monkeypatch.setattr(Model, "log_p", mock_log_p) -<<<<<<< HEAD M = MCMC( state, sampler, @@ -117,18 +118,6 @@ def mock_log_p(self, current_state): n_iter=mcmc_settings["niter"], n_thin=mcmc_settings["nthin"], ) -======= - M = MCMC(state, sampler, model, -<<<<<<< HEAD - n_burn=nburn_niter["nburn"], - n_iter=nburn_niter["niter"], - n_thin=nburn_niter["nthin"]) ->>>>>>> b4ba606 (updated unit test to include thinning) -======= - n_burn=mcmc_settings["nburn"], - n_iter=mcmc_settings["niter"], - n_thin=mcmc_settings["nthin"]) ->>>>>>> 682a0d0 (renaming the fixture function for iteration. burn and thinning) M.store["count"] = 0 M.run_mcmc() assert M.state["count"] == (M.n_iter + M.n_burn) * len(sampler) * M.n_thin From 0c246cc376754b26afc06f0488c028b831270aa9 Mon Sep 17 00:00:00 2001 From: "Matthew.Jones" Date: Wed, 19 Jun 2024 10:08:42 +0200 Subject: [PATCH 17/19] Updated docstrings in mcmc.py. --- src/openmcmc/mcmc.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/openmcmc/mcmc.py b/src/openmcmc/mcmc.py index 2db7d7b..2a2c534 100644 --- a/src/openmcmc/mcmc.py +++ b/src/openmcmc/mcmc.py @@ -21,19 +21,19 @@ class MCMC: """Class for running Markov Chain Monte Carlo on a Model object to do parameter inference. Args: - state (dict): initial state of sampler any parameters not - specified will be sampler from prior distributions - samplers (list): list of the samplers to be used for each parameter to be estimated - n_burn (int, optional): number of initial burn in these iterations are not stored, default 5000 + state (dict): initial state of sampler. Any parameters not specified will be sampled from prior distributions. + samplers (list): list of the samplers to be used for each parameter to be estimated. + n_burn (int, optional): number of initial burn in these iterations are not stored, default 5000. n_iter (int, optional): number of iterations which are stored in store, default 5000 + n_thin (int, optional): number of iterations to thin by, default 1. Attributes: state (dict): initial state of sampler any parameters not specified will be sampler from prior distributions samplers (list): list of the samplers to be used for each parameter to be estimated. n_burn (int): number of initial burn in these iterations are not stored. + n_iter (int): number of iterations which are stored in store. n_thin (int): number of iterations to thin by. - n_iter (int): number of iterations which are stored in store. For every iteration, n_thin iterations are run. store (dict): dictionary storing MCMC output as np.array for each inference parameter. """ @@ -47,7 +47,8 @@ class MCMC: store: dict = field(default_factory=dict, init=False) def __post_init__(self): - """Convert any state values to at least 2D np.arrays and sample any missing states from the prior distributions, and set up storage arrays for the sampled values. + """Convert any state values to at least 2D np.arrays and sample any missing states from the prior distributions, + and set up storage arrays for the sampled values. Ensures that all elements of the initial state are in an appropriate format for running the sampler: @@ -85,7 +86,9 @@ def __post_init__(self): self.store["log_post"] = np.full(shape=(self.n_iter, 1), fill_value=np.nan) def run_mcmc(self): - """Runs MCMC routine for model specification loops for n_iter+ n_burn iterations sampling the state for each parameter and updating the parameter state. + """Runs MCMC routine for the given model specification. + + Numbers the iteratins of the sampler from -self.n_burn to self.n_iter, sotring every self.n_thin samples. Runs a first loop over samplers, and generates a sample for all corresponding variables in the state. Then stores the value of each of the sampled parameters in the self.store dictionary, as well as the data fitted From a5dcc62beacc54facc18df07a12fb28830b22243 Mon Sep 17 00:00:00 2001 From: "Matthew.Jones" Date: Wed, 19 Jun 2024 10:30:53 +0200 Subject: [PATCH 18/19] Minor update to pass pydocstyle check. --- src/openmcmc/mcmc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openmcmc/mcmc.py b/src/openmcmc/mcmc.py index 2a2c534..a7898b6 100644 --- a/src/openmcmc/mcmc.py +++ b/src/openmcmc/mcmc.py @@ -47,7 +47,7 @@ class MCMC: store: dict = field(default_factory=dict, init=False) def __post_init__(self): - """Convert any state values to at least 2D np.arrays and sample any missing states from the prior distributions, + """Convert any state values to at least 2D np.arrays and sample any missing states from the prior distributions and set up storage arrays for the sampled values. Ensures that all elements of the initial state are in an appropriate format for running From fe1a2be30e351c361e4f458dd8dfd562f822e78c Mon Sep 17 00:00:00 2001 From: "Matthew.Jones" Date: Wed, 19 Jun 2024 10:48:07 +0200 Subject: [PATCH 19/19] Re-formatted summary line to pass pydocstyle check. --- src/openmcmc/mcmc.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/openmcmc/mcmc.py b/src/openmcmc/mcmc.py index a7898b6..445ee2b 100644 --- a/src/openmcmc/mcmc.py +++ b/src/openmcmc/mcmc.py @@ -47,8 +47,7 @@ class MCMC: store: dict = field(default_factory=dict, init=False) def __post_init__(self): - """Convert any state values to at least 2D np.arrays and sample any missing states from the prior distributions - and set up storage arrays for the sampled values. + """Convert any state values to at least 2D np.arrays and sample any missing states from the prior distributions and set up storage arrays for the sampled values. Ensures that all elements of the initial state are in an appropriate format for running the sampler: