pinf 0.1.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.
- pinf-0.1.0/LICENSE +21 -0
- pinf-0.1.0/PKG-INFO +418 -0
- pinf-0.1.0/README.md +373 -0
- pinf-0.1.0/pyproject.toml +74 -0
- pinf-0.1.0/setup.cfg +4 -0
- pinf-0.1.0/src/pinf/__init__.py +5 -0
- pinf-0.1.0/src/pinf/execution_engine.py +780 -0
- pinf-0.1.0/src/pinf/gui/__init__.py +1 -0
- pinf-0.1.0/src/pinf/gui/app.py +946 -0
- pinf-0.1.0/src/pinf/gui/helpers.py +488 -0
- pinf-0.1.0/src/pinf/gui/launcher.py +37 -0
- pinf-0.1.0/src/pinf/gui/seeded_data/pi_simulation_bounds_s2_m1.csv +6 -0
- pinf-0.1.0/src/pinf/gui/seeded_data/pi_simulation_bounds_s2_m2.csv +7 -0
- pinf-0.1.0/src/pinf/gui/seeded_data/pi_simulation_stats_s2_m1.csv +6 -0
- pinf-0.1.0/src/pinf/gui/seeded_data/pi_simulation_stats_s2_m2.csv +7 -0
- pinf-0.1.0/src/pinf/gui/seeded_data/pi_subset_s2.csv +8 -0
- pinf-0.1.0/src/pinf/gui/seeded_data/pi_subset_s2_m2.csv +8 -0
- pinf-0.1.0/src/pinf/gui/seeded_data/x0_feasible_region_s2.xlsx +0 -0
- pinf-0.1.0/src/pinf/gui/seeded_data/x0_feasible_region_s2_m2.xlsx +0 -0
- pinf-0.1.0/src/pinf/model_construction.py +269 -0
- pinf-0.1.0/src/pinf/rules/__init__.py +1 -0
- pinf-0.1.0/src/pinf/rules/acceptability.py +177 -0
- pinf-0.1.0/src/pinf/rules/auxiliary_constraints.py +78 -0
- pinf-0.1.0/src/pinf/rules/confidence_regions.py +290 -0
- pinf-0.1.0/src/pinf/rules/functional_structure.py +157 -0
- pinf-0.1.0/src/pinf/utils/__init__.py +1 -0
- pinf-0.1.0/src/pinf/utils/cutoff_calculation.py +75 -0
- pinf-0.1.0/src/pinf/utils/functional_properties_validation.py +45 -0
- pinf-0.1.0/src/pinf/utils/model_construction_inputs.py +181 -0
- pinf-0.1.0/src/pinf/utils/solver_config.py +105 -0
- pinf-0.1.0/src/pinf.egg-info/PKG-INFO +418 -0
- pinf-0.1.0/src/pinf.egg-info/SOURCES.txt +46 -0
- pinf-0.1.0/src/pinf.egg-info/dependency_links.txt +1 -0
- pinf-0.1.0/src/pinf.egg-info/entry_points.txt +2 -0
- pinf-0.1.0/src/pinf.egg-info/requires.txt +22 -0
- pinf-0.1.0/src/pinf.egg-info/top_level.txt +1 -0
- pinf-0.1.0/tests/test_acceptability_screening.py +108 -0
- pinf-0.1.0/tests/test_cutoff_calculation.py +26 -0
- pinf-0.1.0/tests/test_execution_engine.py +38 -0
- pinf-0.1.0/tests/test_functional_structure.py +123 -0
- pinf-0.1.0/tests/test_gui_helpers.py +97 -0
- pinf-0.1.0/tests/test_gui_launcher.py +45 -0
- pinf-0.1.0/tests/test_input_validation.py +122 -0
- pinf-0.1.0/tests/test_intervals.py +116 -0
- pinf-0.1.0/tests/test_model_construction.py +100 -0
- pinf-0.1.0/tests/test_package.py +7 -0
- pinf-0.1.0/tests/test_pixelization.py +101 -0
- pinf-0.1.0/tests/test_solver_config.py +102 -0
pinf-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jinbo Zhao and David J. Eckman
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
pinf-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pinf
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Plausible inference for simulation experiments: screening, plausible intervals and pixelization, built on Pyomo.
|
|
5
|
+
Author: Jinbo Zhao, David J. Eckman
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Jinbo-Zhao/pinf
|
|
8
|
+
Project-URL: Documentation, https://pinf.readthedocs.io/en/latest/
|
|
9
|
+
Project-URL: Repository, https://github.com/Jinbo-Zhao/pinf
|
|
10
|
+
Project-URL: Issues, https://github.com/Jinbo-Zhao/pinf/issues
|
|
11
|
+
Keywords: optimization,pyomo,plausible inference,simulation,statistical inference
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: numpy>=1.22
|
|
26
|
+
Requires-Dist: pandas>=1.5
|
|
27
|
+
Requires-Dist: pyomo>=6.10.1
|
|
28
|
+
Requires-Dist: gurobipy>=10.0
|
|
29
|
+
Requires-Dist: pyscipopt>=5.0
|
|
30
|
+
Requires-Dist: scipy>=1.9
|
|
31
|
+
Provides-Extra: gui
|
|
32
|
+
Requires-Dist: matplotlib>=3.6; extra == "gui"
|
|
33
|
+
Requires-Dist: streamlit>=1.28; extra == "gui"
|
|
34
|
+
Requires-Dist: openpyxl>=3.1; extra == "gui"
|
|
35
|
+
Provides-Extra: dev
|
|
36
|
+
Requires-Dist: pinf[gui]; extra == "dev"
|
|
37
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
38
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
39
|
+
Provides-Extra: docs
|
|
40
|
+
Requires-Dist: sphinx>=7.2; extra == "docs"
|
|
41
|
+
Requires-Dist: sphinx-rtd-theme>=2.0; extra == "docs"
|
|
42
|
+
Requires-Dist: sphinx-autoapi>=3.0; extra == "docs"
|
|
43
|
+
Requires-Dist: myst-nb>=1.0; extra == "docs"
|
|
44
|
+
Dynamic: license-file
|
|
45
|
+
|
|
46
|
+
# Plausible Inference
|
|
47
|
+
|
|
48
|
+
[](https://pinf.readthedocs.io/en/latest/)
|
|
49
|
+
|
|
50
|
+
📖 **Documentation:** <https://pinf.readthedocs.io>
|
|
51
|
+
|
|
52
|
+
<!-- start: intro -->
|
|
53
|
+
This repository contains code for **plausible inference** methods (Zhao et al. 2025) for analyzing the outputs of simulation experiments. The methods involve optimization subroutines built on [Pyomo](https://www.pyomo.org/).
|
|
54
|
+
|
|
55
|
+
Given a set of simulated solutions, estimates of their objective values—provided as summary statistics (e.g., sample means and sample variances) or confidence regions—and assumptions about the structure of the underlying objective function (e.g., convexity, Lipschitz continuity), this package performs inference tasks including:
|
|
56
|
+
|
|
57
|
+
- **Screening:** Perform statistical inference or hypothesis testing on the acceptability (e.g., optimality) of a candidate solution `x_0`.
|
|
58
|
+
- **Plausible intervals:** Construct confidence intervals or regions for the objective value(s) at a given solution `x_0`, or confidence bands for the objective function over the feasible region.
|
|
59
|
+
- **Pixelization:** Construct confidence regions for the set of acceptable solutions in decision (input) space, or for its image in objective (output) space.
|
|
60
|
+
<!-- end: intro -->
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Installation
|
|
65
|
+
<!-- start: installation -->
|
|
66
|
+
|
|
67
|
+
Requires Python ≥ 3.10.
|
|
68
|
+
|
|
69
|
+
### Using the package
|
|
70
|
+
|
|
71
|
+
Install the package from PyPI:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
pip install pinf
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
This also installs the Python interfaces of the Gurobi and SCIP solvers (see
|
|
78
|
+
the Solvers section). The package is imported as `pinf`.
|
|
79
|
+
|
|
80
|
+
To also install the Streamlit GUI (launched with `pinf-gui`, see the Streamlit
|
|
81
|
+
GUI section):
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
pip install "pinf[gui]"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Working from a clone
|
|
88
|
+
|
|
89
|
+
The tests, the demo notebooks and the documentation sources live in this
|
|
90
|
+
repository but are not part of the published package. To use them, clone the
|
|
91
|
+
repository and install it in editable mode from the repository root, inside the
|
|
92
|
+
Python environment you will use (for example after `conda activate <env>`):
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
git clone https://github.com/Jinbo-Zhao/pinf.git
|
|
96
|
+
cd pinf
|
|
97
|
+
pip install -e ".[gui]" # Streamlit GUI (pinf-gui) and the demo notebooks
|
|
98
|
+
pip install -e ".[dev]" # tests and linting (pytest, ruff); includes gui
|
|
99
|
+
pip install -e ".[docs]" # build the documentation locally
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Available extras
|
|
103
|
+
|
|
104
|
+
| Extra | Adds | Needed for |
|
|
105
|
+
|---|---|---|
|
|
106
|
+
| *(none)* `pip install pinf` | NumPy, pandas, SciPy, Pyomo, gurobipy, PySCIPOpt | Building and solving models |
|
|
107
|
+
| `gui` | Streamlit, Matplotlib, openpyxl | The Streamlit GUI (`pinf-gui`) and the demo notebooks |
|
|
108
|
+
| `dev` | pytest, ruff, and the `gui` extra | Tests and linting (from a clone) |
|
|
109
|
+
| `docs` | Sphinx, MyST, Read the Docs theme, sphinx-autoapi | Building the documentation (from a clone) |
|
|
110
|
+
|
|
111
|
+
Every extra already includes the core package. Combine extras in one command,
|
|
112
|
+
for example `pip install -e ".[gui,dev]"`.
|
|
113
|
+
<!-- end: installation -->
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Main Elements
|
|
118
|
+
<!-- start: concepts -->
|
|
119
|
+
|
|
120
|
+
| Concept | Meaning |
|
|
121
|
+
|---|---|
|
|
122
|
+
| **Experimental set** | `exp_set`, shape `(k, s)`: `k` simulated solutions in `s`-dim decision space. |
|
|
123
|
+
| **Plausible objective values** | `m[i, d]`: an intermediate modeling quantity representing objective `d` at solution `i`. Index `0` corresponds to the candidate solution `x_0`; indices `1..k` correspond to the simulated solutions. |
|
|
124
|
+
| **Functional properties** | Structural assumptions on the objective: `convexity`, `concavity`, `Lipschitz_continuity`, `directional_Lipschitz_continuity` (one set per objective). |
|
|
125
|
+
| **Acceptability** | What makes `x_0` "acceptable" (see below). Smaller values are assumed to be preferred for every objective. Defined in terms of `m[0, :]`. |
|
|
126
|
+
| **Confidence region** | A region that constrains the objective values at the simulated solutions, specified directly through bounds on each objective or constraints. |
|
|
127
|
+
| **Discrepancy type** | Specifies how to construct a confidence region from summary statistics. Only one of a discrepancy type or an explicitly specified confidence region is required. |
|
|
128
|
+
|
|
129
|
+
### Inference Types
|
|
130
|
+
|
|
131
|
+
All inference types use statistics computed from the simulation outputs at the simulated solutions, or a confidence region for their objective values.
|
|
132
|
+
|
|
133
|
+
- **`screening`**: Test whether a given solution `x_0` is one of the acceptable solutions.
|
|
134
|
+
- **`upper_plausible_interval`**: Construct an upper confidence bound on a selected objective value at a given solution `x_0`.
|
|
135
|
+
- **`lower_plausible_interval`**: Construct a lower confidence bound on a selected objective value at a given solution `x_0`.
|
|
136
|
+
- **`input_pixelization`**: Test whether a given region in solution (input) space intersects an implicitly defined confidence region for acceptable solutions.
|
|
137
|
+
- **`output_pixelization`**: Test whether a given region in objective (output) space intersects an implicitly defined confidence region for the image of acceptable solutions under the objective function.
|
|
138
|
+
|
|
139
|
+
Inference procedures based on the same simulation statistics or confidence region provide a **uniform confidence guarantee**: with probability at least `1 - alpha`, none of the resulting conclusions makes a Type I error. Here, `1 - alpha` is the confidence level of the provided confidence region, or the confidence level specified when selecting a discrepancy type.
|
|
140
|
+
|
|
141
|
+
Plausible intervals are computed one objective at a time: pass `interval_objective_index` (1-based, default `1`) to `model_construction` to choose which objective is bounded.
|
|
142
|
+
|
|
143
|
+
### Acceptabilities
|
|
144
|
+
|
|
145
|
+
Smaller values are assumed to be preferred for every objective. Objectives for which larger values are preferred can be multiplied by `-1` to follow this convention.
|
|
146
|
+
|
|
147
|
+
| Name | Definition | Parameters |
|
|
148
|
+
|---|---|---|
|
|
149
|
+
| `single-objective-optimality` | The solution achieves the smallest objective value over the feasible region. | — |
|
|
150
|
+
| `delta-optimality` | The solution's objective value is within `delta` of the smallest objective value over the feasible region. | `{'delta': ≥0}` |
|
|
151
|
+
| `feasibility` | The solution's objective value is at or below a specified `threshold`. | `{'threshold': c}` (scalar, or one value per objective) |
|
|
152
|
+
| `closeness-to-target` | The solution's objective value differs from a specified `threshold` by at most `delta`. | `{'threshold': c, 'delta': ≥0}` (each a scalar, or one value per objective) |
|
|
153
|
+
| `Pareto-optimality` | No other feasible solution is at least as good in every objective and strictly better in at least one objective. | — |
|
|
154
|
+
|
|
155
|
+
`single-objective-optimality` and `delta-optimality` apply to a single objective, and `Pareto-optimality` applies to multiple objectives. `feasibility` and `closeness-to-target` apply to any number of objectives, imposing the condition on each objective separately. Parameters are passed via `acceptability_parameters`.
|
|
156
|
+
|
|
157
|
+
### Discrepancy Types
|
|
158
|
+
|
|
159
|
+
A discrepancy is a distance measure that quantifies the disagreement between objective values and simulation observations.
|
|
160
|
+
|
|
161
|
+
For each objective `d`, let
|
|
162
|
+
|
|
163
|
+
$$
|
|
164
|
+
z_{i,d} = \frac{m[i,d] - \bar{Y}_{i,d}}{S_{i,d}/\sqrt{n_{i,d}}},
|
|
165
|
+
$$
|
|
166
|
+
|
|
167
|
+
where $\bar{Y}_{i,d}$, $S_{i,d}^2$, and $n_{i,d}$ are the sample mean, sample variance, and sample size at simulated solution `i`.
|
|
168
|
+
|
|
169
|
+
- **`norm_1`**: Sum the absolute standardized differences:
|
|
170
|
+
|
|
171
|
+
$$
|
|
172
|
+
D_d = \sum_{i=1}^{k} |z_{i,d}|.
|
|
173
|
+
$$
|
|
174
|
+
|
|
175
|
+
- **`norm_2`**: Sum the squared standardized differences:
|
|
176
|
+
|
|
177
|
+
$$
|
|
178
|
+
D_d = \sum_{i=1}^{k} z_{i,d}^{2}.
|
|
179
|
+
$$
|
|
180
|
+
|
|
181
|
+
- **`norm_infinite`**: Take the largest absolute standardized difference:
|
|
182
|
+
|
|
183
|
+
$$
|
|
184
|
+
D_d = \max_{i=1,\ldots,k} |z_{i,d}|.
|
|
185
|
+
$$
|
|
186
|
+
|
|
187
|
+
- **`CRN`**: Use a covariance-adjusted squared distance to account for correlations between simulation outputs at different solutions, such as those induced by common random numbers:
|
|
188
|
+
|
|
189
|
+
$$
|
|
190
|
+
D_d = n_d(\mathbf{m}_d-\bar{\mathbf{Y}}_d)^\top
|
|
191
|
+
\widehat{\Sigma}_d^{-1}
|
|
192
|
+
(\mathbf{m}_d-\bar{\mathbf{Y}}_d).
|
|
193
|
+
$$
|
|
194
|
+
|
|
195
|
+
Here, $\mathbf{m}_d=(m[1,d],\ldots,m[k,d])^\top$, $\bar{\mathbf{Y}}_d$ is the vector of sample means, $\widehat{\Sigma}_d$ is the sample covariance matrix of simulation outputs, and $n_d$ is the common sample size across simulated solutions.
|
|
196
|
+
|
|
197
|
+
- **`confidence_region`**: Directly use a precomputed confidence region specified through `lower_confidence_bounds` and `upper_confidence_bounds`.
|
|
198
|
+
|
|
199
|
+
The three norm-based types assume independent sampling across simulated solutions and use `sample_mean`, `sample_var`, and `sample_size`. For `CRN`, `sample_var` provides a sample covariance matrix across simulated solutions for each objective.
|
|
200
|
+
|
|
201
|
+
For statistics-based types, the package constructs a confidence region by bounding each discrepancy using a cutoff determined by `confidence_level`, with a Bonferroni correction across objectives. For each objective `d`, the resulting region for $(m[1,d], \ldots, m[k,d])$ is a polyhedron for `norm_infinite` (a hyperrectangle) and `norm_1` (a cross-polytope), an axis-aligned ellipsoid for `norm_2`, and an ellipsoid whose axes follow $\widehat{\Sigma}_d$ for `CRN`; with multiple objectives, the overall region is the Cartesian product of these per-objective regions. For `confidence_region`, the region is the hyperrectangle given by the bounds, which should jointly cover the objective values across all simulated solutions and objectives at the intended confidence level.
|
|
202
|
+
<!-- end: concepts -->
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Quick Start
|
|
207
|
+
<!-- start: quickstart -->
|
|
208
|
+
|
|
209
|
+
**Before you run it:** install the package:
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
pip install pinf
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
```python
|
|
216
|
+
import numpy as np
|
|
217
|
+
from pinf.model_construction import model_construction
|
|
218
|
+
from pinf.utils.solver_config import get_plausibility_solver
|
|
219
|
+
from pinf.execution_engine import ExecutionConfig, run_execution_engine
|
|
220
|
+
|
|
221
|
+
# Two simulated solutions in 2-D, single objective, with explicit confidence bounds.
|
|
222
|
+
exp_set = np.array([[0.0, 0.0], [1.0, 1.0]])
|
|
223
|
+
lower = np.array([[1.0], [2.0]])
|
|
224
|
+
upper = np.array([[2.0], [3.0]])
|
|
225
|
+
|
|
226
|
+
# Build a screening model: is x_0 a near-optimal (within 0.5) point for some convex
|
|
227
|
+
# objective consistent with the data?
|
|
228
|
+
model = model_construction(
|
|
229
|
+
exp_set,
|
|
230
|
+
num_objectives=1,
|
|
231
|
+
inference_type="screening",
|
|
232
|
+
functional_properties_list=[["convexity"]],
|
|
233
|
+
acceptability="delta-optimality",
|
|
234
|
+
acceptability_parameters={"delta": 0.5},
|
|
235
|
+
discrepancy_type="confidence_region",
|
|
236
|
+
upper_confidence_bounds=upper,
|
|
237
|
+
lower_confidence_bounds=lower,
|
|
238
|
+
feasibility_check_solver=None, # skip the structural feasibility pre-check
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
solver = get_plausibility_solver("gurobi")
|
|
242
|
+
candidates = np.array([[5.0, 5.0]]) # one candidate x_0, shape (n, s)
|
|
243
|
+
results = run_execution_engine(ExecutionConfig(inference_type="screening"), model, solver, candidates)
|
|
244
|
+
print(results) # DataFrame: idx, solve_status='completed', result='returned'/'screened_out'
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Using statistics instead of explicit bounds:
|
|
248
|
+
|
|
249
|
+
```python
|
|
250
|
+
model = model_construction(
|
|
251
|
+
exp_set,
|
|
252
|
+
num_objectives=1,
|
|
253
|
+
inference_type="screening",
|
|
254
|
+
functional_properties_list=[["convexity"]],
|
|
255
|
+
acceptability="single-objective-optimality",
|
|
256
|
+
discrepancy_type="norm_infinite",
|
|
257
|
+
sample_mean=np.array([[1.0], [2.0]]),
|
|
258
|
+
sample_var=np.array([[0.5], [0.5]]), # must be finite and > 0
|
|
259
|
+
sample_size=100.0,
|
|
260
|
+
confidence_level=0.95, # must be in (0, 1)
|
|
261
|
+
feasibility_check_solver=None,
|
|
262
|
+
)
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
Once you have a model, use `run_execution_engine` to solve the inference over your
|
|
266
|
+
candidate points. It returns one `pandas.DataFrame` with a row per point:
|
|
267
|
+
|
|
268
|
+
```python
|
|
269
|
+
from pinf.execution_engine import ExecutionConfig, run_execution_engine
|
|
270
|
+
|
|
271
|
+
results = run_execution_engine(
|
|
272
|
+
ExecutionConfig(inference_type="screening"),
|
|
273
|
+
model,
|
|
274
|
+
solver,
|
|
275
|
+
candidates,
|
|
276
|
+
)
|
|
277
|
+
```
|
|
278
|
+
<!-- end: quickstart -->
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## Solvers
|
|
283
|
+
<!-- start: solvers -->
|
|
284
|
+
|
|
285
|
+
Plausible inference must distinguish **infeasible** from **unbounded**, which solver
|
|
286
|
+
presolve can otherwise hide (`INF_OR_UNBD`). Always create the solver via
|
|
287
|
+
`get_plausibility_solver(name)`, which sets the right options:
|
|
288
|
+
|
|
289
|
+
- **Gurobi** — `DualReductions = 0`
|
|
290
|
+
- **SCIP** — `misc/allowstrongdualreds = False`, `misc/allowweakdualreds = False`
|
|
291
|
+
|
|
292
|
+
Models built with `norm_2` or `CRN` contain quadratic constraints; both solvers
|
|
293
|
+
handle them.
|
|
294
|
+
|
|
295
|
+
### Gurobi
|
|
296
|
+
|
|
297
|
+
Solver names: `gurobi`, `gurobi_direct`.
|
|
298
|
+
|
|
299
|
+
```bash
|
|
300
|
+
pip install pinf # includes gurobipy
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
The pip-installed `gurobipy` includes a size-limited license that is enough for
|
|
304
|
+
small examples. Larger models need a full Gurobi license (free for academic use);
|
|
305
|
+
see the [Gurobi license documentation](https://support.gurobi.com/hc/en-us/articles/12684663118993-How-do-I-obtain-a-Gurobi-license).
|
|
306
|
+
|
|
307
|
+
### SCIP
|
|
308
|
+
|
|
309
|
+
SCIP is open source but can be reached through two Pyomo interfaces, which are
|
|
310
|
+
installed differently:
|
|
311
|
+
|
|
312
|
+
| Solver name | What it uses | How to install |
|
|
313
|
+
|---|---|---|
|
|
314
|
+
| `scip_direct` | PySCIPOpt (Python bindings that bundle the SCIP library) | included in `pip install pinf` |
|
|
315
|
+
| `scip` | the `scip` command-line executable | `conda install -c conda-forge scip`, or download an installer from [scipopt.org](https://www.scipopt.org/) |
|
|
316
|
+
|
|
317
|
+
`pip install pyscipopt` does **not** provide the `scip` executable, so with a
|
|
318
|
+
pip-only setup use `scip_direct`. To use `scip`, check that the executable is on
|
|
319
|
+
`PATH` with `scip --version`. `scip_direct` requires Pyomo 6.10.1 or
|
|
320
|
+
later, which `pip install pinf` installs.
|
|
321
|
+
|
|
322
|
+
### Checking a solver
|
|
323
|
+
|
|
324
|
+
```python
|
|
325
|
+
from pinf.utils.solver_config import get_plausibility_solver
|
|
326
|
+
|
|
327
|
+
solver = get_plausibility_solver("scip_direct") # or "gurobi", "scip", ...
|
|
328
|
+
print(solver.available(exception_flag=False)) # True when Pyomo can use it
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### Structural feasibility check
|
|
332
|
+
|
|
333
|
+
`model_construction` first checks that the functional-property and
|
|
334
|
+
confidence-region constraints are feasible. Choose the solver with
|
|
335
|
+
`feasibility_check_solver` (`gurobi`, `gurobi_direct`, `scip` or `scip_direct`;
|
|
336
|
+
default `scip_direct`), or pass `None` to skip the check.
|
|
337
|
+
<!-- end: solvers -->
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
## Streamlit GUI
|
|
342
|
+
<!-- start: gui -->
|
|
343
|
+
|
|
344
|
+
The GUI ships with the package. Install it with the GUI extra:
|
|
345
|
+
|
|
346
|
+
```bash
|
|
347
|
+
pip install "pinf[gui]"
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
Then start it from the directory where you want results to be saved:
|
|
351
|
+
|
|
352
|
+
```bash
|
|
353
|
+
pinf-gui
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
Streamlit prints a local URL (usually <http://localhost:8501>) and opens it in
|
|
357
|
+
your browser. Stop the app with Ctrl+C in the terminal. Results are written to
|
|
358
|
+
`inference_results/` under the launch directory. Options after `pinf-gui` are
|
|
359
|
+
passed to `streamlit run`, for example `pinf-gui --server.port 8600`.
|
|
360
|
+
|
|
361
|
+
The GUI guides the user through problem setup, acceptability + threshold inputs, simulation
|
|
362
|
+
upload (statistics or bounds templates), procedure-specific inputs (candidate points or
|
|
363
|
+
pixel grids), and runs the inference with downloadable results.
|
|
364
|
+
<!-- end: gui -->
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
## Project Layout
|
|
369
|
+
|
|
370
|
+
```
|
|
371
|
+
src/pinf/
|
|
372
|
+
├── model_construction.py # build the Pyomo model (entry point)
|
|
373
|
+
├── execution_engine.py # batch-solve the optimization problems (run_execution_engine)
|
|
374
|
+
├── rules/
|
|
375
|
+
│ ├── functional_structure.py # convexity / concavity / linearity / Lipschitz
|
|
376
|
+
│ ├── acceptability.py # acceptability constraints
|
|
377
|
+
│ ├── confidence_regions.py # discrepancy measures + cutoffs
|
|
378
|
+
│ └── auxiliary_constraints.py # abs/max linearization helpers
|
|
379
|
+
├── utils/
|
|
380
|
+
│ ├── cutoff_calculation.py # Monte-Carlo / closed-form discrepancy cutoffs
|
|
381
|
+
│ ├── model_construction_inputs.py # input validation
|
|
382
|
+
│ ├── functional_properties_validation.py # property-parameter validation
|
|
383
|
+
│ └── solver_config.py # solver factory + time limits
|
|
384
|
+
└── gui/
|
|
385
|
+
├── app.py # Streamlit app
|
|
386
|
+
├── helpers.py # parsing, templates, argument builders
|
|
387
|
+
├── launcher.py # `pinf-gui` entry point
|
|
388
|
+
└── seeded_data/ # example CSV/XLSX inputs
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
---
|
|
392
|
+
|
|
393
|
+
## License
|
|
394
|
+
|
|
395
|
+
This project is licensed under the MIT License. See [`LICENSE`](https://github.com/Jinbo-Zhao/pinf/blob/main/LICENSE) for details.
|
|
396
|
+
|
|
397
|
+
Copyright (c) 2026 Jinbo Zhao and David J. Eckman.
|
|
398
|
+
## Testing
|
|
399
|
+
<!-- start: testing -->
|
|
400
|
+
|
|
401
|
+
```bash
|
|
402
|
+
pip install -e ".[dev]"
|
|
403
|
+
pytest
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
Solve tests need Gurobi and SCIP available through Pyomo. The package
|
|
407
|
+
installs `gurobipy` and PySCIPOpt (for `scip_direct`). Tests of the `scip`
|
|
408
|
+
interface also need the SCIP executable on `PATH`
|
|
409
|
+
(e.g. `conda install -c conda-forge scip`).
|
|
410
|
+
<!-- end: testing -->
|
|
411
|
+
|
|
412
|
+
---
|
|
413
|
+
|
|
414
|
+
## References
|
|
415
|
+
<!-- start: references -->
|
|
416
|
+
|
|
417
|
+
- Zhao, J., G. Keslin, D. J. Eckman, and B. L. Nelson. "[Methods of Plausible Inference: The Definitive Cookbook](https://www.informs-sim.org/wsc25papers/inv171.pdf)". Proceedings of the 2025 Winter Simulation Conference. 2025. 88–102.
|
|
418
|
+
<!-- end: references -->
|