abcpp 1.0.0__cp313-cp313-win_amd64.whl

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.
abcpp/__init__.py ADDED
@@ -0,0 +1,4 @@
1
+ from .abc import abc
2
+ from .summary import summary
3
+
4
+ __all__ = ["abc", "summary"]
Binary file
abcpp/abc.py ADDED
@@ -0,0 +1,120 @@
1
+ import copy
2
+
3
+ import numpy
4
+
5
+ from . import _core
6
+
7
+
8
+ DEFAULT_CONTROL = {
9
+ "method": "rejection",
10
+ "tol": 0.01,
11
+ "kernel": "epanechnikov",
12
+ "hcorr": True,
13
+ "transf": "none",
14
+ "logit_bounds": None,
15
+ "subset": None,
16
+ "prior_weights": None,
17
+ "seed": 1004,
18
+ "reduction": "none",
19
+ "n_comp": 0,
20
+ "nnet": {
21
+ "numnet": 10,
22
+ "sizenet": 5,
23
+ "lambda": [0.0001, 0.001, 0.01],
24
+ "maxit": 500,
25
+ "rang": 0.7,
26
+ "abstol": 1e-4,
27
+ "reltol": 1e-8,
28
+ "verbose": False,
29
+ "skip": False,
30
+ },
31
+ }
32
+
33
+
34
+ def _nested_merge(defaults, overrides):
35
+ merged = copy.deepcopy(defaults)
36
+ for key, value in overrides.items():
37
+ if (
38
+ isinstance(value, dict)
39
+ and isinstance(merged.get(key), dict)
40
+ ):
41
+ merged[key] = _nested_merge(merged[key], value)
42
+ else:
43
+ merged[key] = value
44
+ return merged
45
+
46
+
47
+ def _prepare_control(control):
48
+ if control is None:
49
+ control = {}
50
+ if not isinstance(control, dict):
51
+ raise TypeError("control must be a dict or None")
52
+ merged = _nested_merge(DEFAULT_CONTROL, control)
53
+ if isinstance(merged["transf"], str):
54
+ merged["transf"] = [merged["transf"]]
55
+ if merged["logit_bounds"] is None:
56
+ merged["logit_bounds"] = numpy.zeros((1, 2), dtype=float)
57
+ if merged["subset"] is None:
58
+ merged["subset"] = numpy.asarray([], dtype=bool)
59
+ if merged["prior_weights"] is None:
60
+ merged["prior_weights"] = numpy.asarray([], dtype=float)
61
+ else:
62
+ merged["prior_weights"] = numpy.asarray(
63
+ merged["prior_weights"],
64
+ dtype=float,
65
+ )
66
+ return merged
67
+
68
+
69
+ def _is_matrix_like(value):
70
+ try:
71
+ return numpy.asarray(value).ndim == 2
72
+ except ValueError:
73
+ return False
74
+
75
+
76
+ def abc(target, params, sumstats, control=None):
77
+ """Run Approximate Bayesian Computation with the C++ backend."""
78
+ control = _prepare_control(control)
79
+ target_array = numpy.asarray(target, dtype=float)
80
+ param_array = numpy.asarray(params, dtype=float)
81
+ sumstat_is_mapping = isinstance(sumstats, dict)
82
+ sumstat_items = list(sumstats.values()) if sumstat_is_mapping else sumstats
83
+ sumstat_is_matrix_collection = (
84
+ isinstance(sumstat_items, (list, tuple))
85
+ and len(sumstat_items) > 0
86
+ and all(_is_matrix_like(item) for item in sumstat_items)
87
+ )
88
+ if sumstat_is_matrix_collection:
89
+ sumstat_value = [
90
+ numpy.asarray(item, dtype=float)
91
+ for item in sumstat_items
92
+ ]
93
+ else:
94
+ sumstat_value = numpy.asarray(sumstats, dtype=float)
95
+
96
+ if target_array.ndim == 1:
97
+ target_array = target_array.reshape((1, -1))
98
+ if param_array.ndim == 1:
99
+ param_array = param_array.reshape((-1, 1))
100
+ if not sumstat_is_matrix_collection and sumstat_value.ndim == 1:
101
+ sumstat_value = sumstat_value.reshape((-1, 1))
102
+ if (
103
+ not sumstat_is_matrix_collection
104
+ and param_array.ndim == 2
105
+ and sumstat_value.ndim == 2
106
+ and param_array.shape[0] == 1
107
+ and param_array.shape[1] == sumstat_value.shape[0]
108
+ and sumstat_value.shape[0] != 1
109
+ ):
110
+ param_array = param_array.T
111
+
112
+ if sumstat_is_matrix_collection:
113
+ return _core.abc_matrix_list(
114
+ target_array,
115
+ param_array,
116
+ [numpy.asarray(item, dtype=float) for item in sumstat_value],
117
+ control,
118
+ )
119
+
120
+ return _core.abc(target_array, param_array, sumstat_value, control)
abcpp/summary.py ADDED
@@ -0,0 +1,6 @@
1
+ from . import _core
2
+
3
+
4
+ def summary(result, unadj=False, intvl=0.95):
5
+ """Summarize posterior draws returned by :func:`abcpp.abc`."""
6
+ return _core.summary(result, unadj=bool(unadj), intvl=float(intvl))