hoppMCMC 2.0.0__tar.gz → 2.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. {hoppmcmc-2.0.0 → hoppmcmc-2.2.0}/NEWS.txt +15 -57
  2. {hoppmcmc-2.0.0/src/hoppMCMC.egg-info → hoppmcmc-2.2.0}/PKG-INFO +1 -1
  3. {hoppmcmc-2.0.0 → hoppmcmc-2.2.0}/pyproject.toml +1 -1
  4. {hoppmcmc-2.0.0 → hoppmcmc-2.2.0}/setup.cfg +1 -1
  5. {hoppmcmc-2.0.0 → hoppmcmc-2.2.0}/src/hoppMCMC/__init__.py +1 -1
  6. hoppmcmc-2.2.0/src/hoppMCMC/examples/example4.py +135 -0
  7. hoppmcmc-2.2.0/src/hoppMCMC/examples/example5.py +203 -0
  8. {hoppmcmc-2.0.0 → hoppmcmc-2.2.0/src/hoppMCMC.egg-info}/PKG-INFO +1 -1
  9. {hoppmcmc-2.0.0 → hoppmcmc-2.2.0}/src/hoppMCMC.egg-info/SOURCES.txt +2 -0
  10. hoppmcmc-2.2.0/src/inferFun/__init__.py +1328 -0
  11. hoppmcmc-2.0.0/src/inferFun/__init__.py +0 -549
  12. {hoppmcmc-2.0.0 → hoppmcmc-2.2.0}/LICENSE +0 -0
  13. {hoppmcmc-2.0.0 → hoppmcmc-2.2.0}/MANIFEST.in +0 -0
  14. {hoppmcmc-2.0.0 → hoppmcmc-2.2.0}/README.txt +0 -0
  15. {hoppmcmc-2.0.0 → hoppmcmc-2.2.0}/setup.py +0 -0
  16. {hoppmcmc-2.0.0 → hoppmcmc-2.2.0}/src/hoppMCMC/doc/hoppMCMC_manual.pdf +0 -0
  17. {hoppmcmc-2.0.0 → hoppmcmc-2.2.0}/src/hoppMCMC/examples/example1.py +0 -0
  18. {hoppmcmc-2.0.0 → hoppmcmc-2.2.0}/src/hoppMCMC/examples/example2.py +0 -0
  19. {hoppmcmc-2.0.0 → hoppmcmc-2.2.0}/src/hoppMCMC/examples/example3.py +0 -0
  20. {hoppmcmc-2.0.0 → hoppmcmc-2.2.0}/src/hoppMCMC.egg-info/dependency_links.txt +0 -0
  21. {hoppmcmc-2.0.0 → hoppmcmc-2.2.0}/src/hoppMCMC.egg-info/not-zip-safe +0 -0
  22. {hoppmcmc-2.0.0 → hoppmcmc-2.2.0}/src/hoppMCMC.egg-info/requires.txt +0 -0
  23. {hoppmcmc-2.0.0 → hoppmcmc-2.2.0}/src/hoppMCMC.egg-info/top_level.txt +0 -0
  24. {hoppmcmc-2.0.0 → hoppmcmc-2.2.0}/src/myMPI/__init__.py +0 -0
@@ -1,74 +1,32 @@
1
1
  News
2
2
  ====
3
3
 
4
- 1.2.1
4
+ 2.2.0
5
5
  -----
6
6
 
7
- *UNRELEASED*
7
+ *Release date: 13-Jul-2026*
8
+
9
+ inferFun is now updated to include ABCModel and inferABCModels as the main ABC-SMC inference tools
8
10
 
11
+ 2.1.0
12
+ 1.2.1
9
13
  1.2
14
+ 1.1 *13-Sep-2018*
15
+ 1.0 *30-Jul-2018*
16
+ 0.6
17
+ 0.5 *14-Feb-2017*
18
+ 0.4 *14-Oct-2015*
19
+ 0.3 *09-Oct-2015*
20
+ 0.2 *28-Sep-2015*
21
+ 0.1 *28-Sep-2015*
10
22
  -----
11
23
 
12
- *UNRELEASED*
13
-
14
24
  * Prevented premature termination during kde.evaluate (needs a better solution)
15
-
16
- 1.1
17
- -----
18
-
19
- *Release date: 13-Sep-2018*
20
-
21
25
  * Fixed a bug in reading output (Python 3)
22
-
23
- 1.0
24
- -----
25
-
26
- *Release date: 30-Jul-2018*
27
-
28
26
  * Compatible with Python 3
29
-
30
- 0.6
31
- -----
32
-
33
- *UNRELEASED*
34
-
35
27
  * Print out the covariates in addition to the parameters
36
-
37
- 0.5
38
- -----
39
-
40
- *Release date: 14-Feb-2017*
41
-
42
28
  * Minor improvement on pulsevarUpdate
43
-
44
- 0.4
45
- -----
46
-
47
- *Release date: 14-Oct-2015*
48
-
49
29
  * Fixed an issue with default parameters
50
-
51
- 0.3
52
- -----
53
-
54
- *Release date: 09-Oct-2015*
55
-
56
30
  * This version includes an improvement in compareAUCs
57
-
58
-
59
- 0.2
60
- -----
61
-
62
- *Release date: 28-Sep-2015*
63
-
64
31
  * This version includes a documentation and examples
65
-
66
-
67
- 0.1
68
- -----
69
-
70
- *Release date: 28-Sep-2015*
71
-
72
- * Initial commit
73
-
74
-
32
+ * Initial commit
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hoppMCMC
3
- Version: 2.0.0
3
+ Version: 2.2.0
4
4
  Summary: An adaptive basin-hopping Markov-chain Monte Carlo algorithm for Bayesian optimisation
5
5
  Author: Kamil Erguler
6
6
  Author-email: Kamil Erguler <kerguler@gmail.com>
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "hoppMCMC"
7
- version = "2.0.0"
7
+ version = "2.2.0"
8
8
  description = "An adaptive basin-hopping Markov-chain Monte Carlo algorithm for Bayesian optimisation"
9
9
  authors = [{ name = "Kamil Erguler", email = "kerguler@gmail.com" }]
10
10
  license = { text = "GPLv3" }
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = hoppMCMC
3
- version = 2.0.0
3
+ version = 2.2.0
4
4
  description = Adaptive basin-hopping MCMC and ABC inference with MPI support
5
5
  author = Kamil Erguler
6
6
  author_email = k.erguler@cyi.ac.cy
@@ -6,7 +6,7 @@ This is the python (v2.7) implementation of the hoppMCMC algorithm aiming to ide
6
6
 
7
7
  """
8
8
 
9
- __version__ = '2.0.0'
9
+ __version__ = '2.2.0'
10
10
 
11
11
  import os
12
12
  import sys
@@ -0,0 +1,135 @@
1
+ import numpy
2
+ import pandas
3
+ import seaborn
4
+
5
+ from matplotlib import pyplot as plt
6
+
7
+ import myMPI
8
+ from inferFun import ABCModel, inferABCModels
9
+
10
+ # ---------------------------------------------------------------------
11
+ # Synthetic observation data
12
+ # ---------------------------------------------------------------------
13
+
14
+ temperatures = numpy.array([15, 18, 21, 24, 27, 30, 33, 36, 39], dtype=float)
15
+ observed_rates = numpy.array([0.07508502, 0.15548009, 0.25742823, 0.31720884, 0.39438616, 0.43292063, 0.41474694, 0.33905526, 0. ])
16
+
17
+ def briere_rate(temp, c, tmin, tmax):
18
+ """
19
+ Brière temperature response.
20
+
21
+ The response is zero below tmin and above tmax.
22
+ Between tmin and tmax, it rises and then falls near tmax.
23
+ """
24
+ temp = numpy.asarray(temp, dtype=float)
25
+ rate = c * temp * (temp - tmin) * numpy.sqrt(numpy.maximum(tmax - temp, 0.0))
26
+ rate[(temp <= tmin) | (temp >= tmax)] = 0.0
27
+ return rate
28
+
29
+ # ---------------------------------------------------------------------
30
+ # Distance function
31
+ # ---------------------------------------------------------------------
32
+
33
+ def normalised_rmse(predicted, observed):
34
+ """
35
+ Normalised root mean squared error.
36
+
37
+ The normalisation keeps the ABC threshold easier to interpret across
38
+ examples.
39
+ """
40
+ predicted = numpy.asarray(predicted, dtype=float)
41
+ observed = numpy.asarray(observed, dtype=float)
42
+ scale = numpy.std(observed)
43
+ if scale == 0:
44
+ scale = 1.0
45
+ return numpy.sqrt(numpy.mean((predicted - observed) ** 2)) / scale
46
+
47
+ def score_briere(par, verbose=False):
48
+ c, tmin, tmax = par
49
+ # Invalid thermal limits are rejected by returning an infinite score.
50
+ if tmin >= tmax:
51
+ return numpy.inf
52
+ predicted = briere_rate(temperatures, c=c, tmin=tmin, tmax=tmax)
53
+ return normalised_rmse(predicted, observed_rates)
54
+
55
+ # ---------------------------------------------------------------------
56
+ # Brière model definition
57
+ # ---------------------------------------------------------------------
58
+
59
+ model_briere = ABCModel(
60
+ name="briere",
61
+ pargen=lambda: numpy.array([2.5e-4, 10.0, 38.0]),
62
+ score=score_briere,
63
+ lower=numpy.array([1e-6, 0.0, 30.0]),
64
+ upper = numpy.array([1e-3, 20.0, 45.0]),
65
+ prior=0.5,
66
+ inferpar=[0, 1, 2],
67
+ kernel=numpy.array([1e-8, 0.5, 0.5])
68
+ )
69
+
70
+ # ---------------------------------------------------------------------
71
+ # Run single-model ABC
72
+ # ---------------------------------------------------------------------
73
+
74
+ abc = inferABCModels(
75
+ models=[model_briere],
76
+ epsseq=[0.5],
77
+ size=100,
78
+ niter=20,
79
+ adapt=2,
80
+ retain=True,
81
+ verbose=True
82
+ )
83
+
84
+ # ---------------------------------------------------------------------
85
+ # Summarise model posterior probabilities
86
+ # ---------------------------------------------------------------------
87
+
88
+ if myMPI.MPI_RANK == myMPI.MPI_MASTER:
89
+ plt.plot(abc.results[:,abc.infocol['iter']],
90
+ abc.results[:,abc.infocol['param0']],
91
+ '.')
92
+ plt.show()
93
+
94
+ if myMPI.MPI_RANK == myMPI.MPI_MASTER:
95
+ # Use abc.result, unless your class stores it as abc.results
96
+ mat = abc.result
97
+ param_start = abc.infocol["param0"]
98
+ params = mat[:, param_start:]
99
+ # Remove padded NaN columns, useful if inferABCModels stores variable-length parameters
100
+ valid_cols = ~numpy.all(numpy.isnan(params), axis=0)
101
+ params = params[:, valid_cols]
102
+ df = pandas.DataFrame(
103
+ params,
104
+ columns=[f"par{i+1}" for i in range(params.shape[1])]
105
+ )
106
+ df["score"] = mat[:, abc.infocol["score"]]
107
+ #
108
+ g = seaborn.pairplot(
109
+ df,
110
+ vars=[c for c in df.columns if c.startswith("par")],
111
+ corner=True,
112
+ diag_kind="kde",
113
+ plot_kws={
114
+ "s": 35,
115
+ "alpha": 0.65,
116
+ "edgecolor": "none"
117
+ },
118
+ diag_kws={
119
+ "fill": True,
120
+ "alpha": 0.45
121
+ }
122
+ )
123
+ g.figure.suptitle("ABC posterior parameter samples", y=1.02)
124
+ g.figure.set_size_inches(8, 8)
125
+ plt.tight_layout()
126
+ plt.show()
127
+
128
+ if myMPI.MPI_RANK == myMPI.MPI_MASTER:
129
+ model_probs = abc.model_posterior()
130
+ print("\nPosterior model probabilities")
131
+ print(model_probs)
132
+ # Optional: inspect the final particle population.
133
+ particles = abc.result
134
+ print("\nFinal particle matrix shape:")
135
+ print(particles.shape)
@@ -0,0 +1,203 @@
1
+ import numpy
2
+ import pandas
3
+ import seaborn
4
+
5
+ from matplotlib import pyplot as plt
6
+
7
+ import myMPI
8
+ from inferFun import ABCModel, inferABCModels
9
+
10
+ # ---------------------------------------------------------------------
11
+ # Synthetic observation data
12
+ # ---------------------------------------------------------------------
13
+
14
+ temperatures = numpy.array([15, 18, 21, 24, 27, 30, 33, 36, 39], dtype=float)
15
+ observed_rates = numpy.array([0.07508502, 0.15548009, 0.25742823, 0.31720884, 0.39438616, 0.43292063, 0.41474694, 0.33905526, 0. ])
16
+
17
+ def briere_rate(temp, c, tmin, tmax):
18
+ """
19
+ Brière temperature response.
20
+
21
+ The response is zero below tmin and above tmax.
22
+ Between tmin and tmax, it rises and then falls near tmax.
23
+ """
24
+ temp = numpy.asarray(temp, dtype=float)
25
+ rate = c * temp * (temp - tmin) * numpy.sqrt(numpy.maximum(tmax - temp, 0.0))
26
+ rate[(temp <= tmin) | (temp >= tmax)] = 0.0
27
+ return rate
28
+
29
+ def exponential_rate(temp, a, b):
30
+ """
31
+ Exponential temperature response.
32
+
33
+ This model can increase with temperature but cannot represent a
34
+ high-temperature decline.
35
+ """
36
+ temp = numpy.asarray(temp, dtype=float)
37
+ return a * numpy.exp(b * temp)
38
+
39
+ # ---------------------------------------------------------------------
40
+ # Shared distance function helper
41
+ # ---------------------------------------------------------------------
42
+
43
+ def normalised_rmse(predicted, observed):
44
+ """
45
+ Normalised root mean squared error.
46
+
47
+ The normalisation keeps the ABC threshold easier to interpret across
48
+ examples.
49
+ """
50
+ predicted = numpy.asarray(predicted, dtype=float)
51
+ observed = numpy.asarray(observed, dtype=float)
52
+ scale = numpy.std(observed)
53
+ if scale == 0:
54
+ scale = 1.0
55
+ return numpy.sqrt(numpy.mean((predicted - observed) ** 2)) / scale
56
+
57
+ # ---------------------------------------------------------------------
58
+ # Exponential model definition
59
+ # ---------------------------------------------------------------------
60
+
61
+ lower_exp = numpy.array([1e-5, 0.001])
62
+ upper_exp = numpy.array([0.05, 0.25])
63
+
64
+ def pargen_exponential():
65
+ return numpy.random.uniform(lower_exp, upper_exp)
66
+
67
+ def score_exponential(par, verbose=False):
68
+ a, b = par
69
+ predicted = exponential_rate(
70
+ temperatures,
71
+ a=a,
72
+ b=b
73
+ )
74
+ return normalised_rmse(predicted, observed_rates)
75
+
76
+ model_exponential = ABCModel(
77
+ name="exponential",
78
+ pargen=pargen_exponential,
79
+ score=score_exponential,
80
+ lower=lower_exp,
81
+ upper=upper_exp,
82
+ prior=0.5,
83
+ inferpar=[0, 1],
84
+ kernel=numpy.array([1e-4, 1e-4])
85
+ )
86
+
87
+ # ---------------------------------------------------------------------
88
+ # Brière model definition
89
+ # ---------------------------------------------------------------------
90
+
91
+ lower_briere = numpy.array([1e-6, 0.0, 30.0])
92
+ upper_briere = numpy.array([1e-3, 20.0, 45.0])
93
+
94
+ def pargen_briere():
95
+ return numpy.random.uniform(lower_briere, upper_briere)
96
+
97
+ def score_briere(par, verbose=False):
98
+ c, tmin, tmax = par
99
+ # Invalid thermal limits are rejected by returning an infinite score.
100
+ if tmin >= tmax:
101
+ return numpy.inf
102
+ predicted = briere_rate(
103
+ temperatures,
104
+ c=c,
105
+ tmin=tmin,
106
+ tmax=tmax
107
+ )
108
+ return normalised_rmse(predicted, observed_rates)
109
+
110
+ model_briere = ABCModel(
111
+ name="briere",
112
+ pargen=pargen_briere,
113
+ score=score_briere,
114
+ lower=lower_briere,
115
+ upper=upper_briere,
116
+ prior=0.5,
117
+ inferpar=[0, 1, 2],
118
+ kernel=numpy.array([1e-8, 0.5, 0.5])
119
+ )
120
+
121
+ # ---------------------------------------------------------------------
122
+ # Run multi-model ABC
123
+ # ---------------------------------------------------------------------
124
+
125
+ abc = inferABCModels(
126
+ models=[
127
+ model_exponential,
128
+ model_briere
129
+ ],
130
+ epsseq=[
131
+ 1.5,
132
+ 1.0,
133
+ 0.5
134
+ ],
135
+ size=100,
136
+ niter=10,
137
+ adapt=2,
138
+ retain=True,
139
+ verbose=True
140
+ )
141
+
142
+ # ---------------------------------------------------------------------
143
+ # Summarise model posterior probabilities
144
+ # ---------------------------------------------------------------------
145
+
146
+ if myMPI.MPI_RANK == myMPI.MPI_MASTER:
147
+ model_probs = abc.model_posterior()
148
+ print("\nPosterior model probabilities")
149
+ print(model_probs)
150
+ # Optional: inspect the final particle population.
151
+ particles = abc.result
152
+ print("\nFinal particle matrix shape:")
153
+ print(particles.shape)
154
+
155
+ if myMPI.MPI_RANK == myMPI.MPI_MASTER:
156
+ mats = [abc.results[:abc.size,:], abc.result]
157
+ p0 = abc.infocol["param0"]
158
+ #
159
+ for ipop,mat in enumerate(mats):
160
+ plt.figure(figsize=(7, 5))
161
+ # Observations
162
+ plt.scatter(
163
+ temperatures,
164
+ observed_rates,
165
+ s=50,
166
+ color="black",
167
+ label="observed",
168
+ zorder=10
169
+ )
170
+ # Exponential posterior population
171
+ model_id = abc.model_names.index("exponential")
172
+ sub = mat[mat[:, abc.infocol["model"]] == model_id]
173
+ for row in sub:
174
+ par = row[p0:p0 + abc.parsizes[model_id]]
175
+ y = exponential_rate(temperatures, par[0], par[1])
176
+ plt.plot(
177
+ temperatures,
178
+ y,
179
+ color="tab:blue",
180
+ alpha=0.5
181
+ )
182
+ # Brière posterior population
183
+ model_id = abc.model_names.index("briere")
184
+ sub = mat[mat[:, abc.infocol["model"]] == model_id]
185
+ for row in sub:
186
+ par = row[p0:p0 + abc.parsizes[model_id]]
187
+ y = briere_rate(temperatures, par[0], par[1], par[2])
188
+ plt.plot(
189
+ temperatures,
190
+ y,
191
+ color="tab:orange",
192
+ alpha=0.5
193
+ )
194
+ #
195
+ # Dummy lines for legend
196
+ plt.plot([], [], color="tab:blue", label="exponential")
197
+ plt.plot([], [], color="tab:orange", label="Brière")
198
+ plt.xlabel("Temperature")
199
+ plt.ylabel("Rate")
200
+ plt.title(f"{["First","Final"][ipop]} ABC posterior population")
201
+ plt.legend()
202
+ plt.tight_layout()
203
+ plt.show()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hoppMCMC
3
- Version: 2.0.0
3
+ Version: 2.2.0
4
4
  Summary: An adaptive basin-hopping Markov-chain Monte Carlo algorithm for Bayesian optimisation
5
5
  Author: Kamil Erguler
6
6
  Author-email: Kamil Erguler <kerguler@gmail.com>
@@ -16,5 +16,7 @@ src/hoppMCMC/doc/hoppMCMC_manual.pdf
16
16
  src/hoppMCMC/examples/example1.py
17
17
  src/hoppMCMC/examples/example2.py
18
18
  src/hoppMCMC/examples/example3.py
19
+ src/hoppMCMC/examples/example4.py
20
+ src/hoppMCMC/examples/example5.py
19
21
  src/inferFun/__init__.py
20
22
  src/myMPI/__init__.py