Metadata-Version: 2.4
Name: bam-solver
Version: 4.1.0
Summary: Python wrapper for the BAM derivative-free global optimization solver
Keywords: optimization,global,derivative-free,black-box,BAM
Author: minlp.com
License-Expression: LicenseRef-Proprietary
License-File: LICENSES/ARPACK.txt
License-File: LICENSES/Apache-2.0.txt
License-File: LICENSES/Burkardt.txt
License-File: LICENSES/EPL-1.0.txt
License-File: LICENSES/EPL-2.0.txt
License-File: LICENSES/GCC-Runtime-Library-Exception-3.1.txt
License-File: LICENSES/GPL-3.0.txt
License-File: LICENSES/HSL.txt
License-File: LICENSES/HiGHS.txt
License-File: LICENSES/L-BFGS-B.txt
License-File: LICENSES/LAPACK.txt
License-File: LICENSES/LGPL-2.1.txt
License-File: LICENSES/Metis.txt
License-File: LICENSES/Prima.txt
License-File: LICENSES/WNNLS-ACM.txt
License-File: LICENSES/dejavu.txt
License-File: LICENSES/fparser.txt
License-File: LICENSES/pthreads-win32.txt
License-File: THIRD-PARTY-LICENSES
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Education
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Intended Audience :: Healthcare Industry
Classifier: Intended Audience :: Information Technology
Classifier: Intended Audience :: Manufacturing
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft :: Windows
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Topic :: Scientific/Engineering :: Mathematics
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Project-URL: Homepage, https://minlp.com/bam-data-driven-optimizer
Project-URL: Documentation, https://minlp.com/bam-user-manual
Project-URL: License Request, https://minlp.com/bam-licenses
Requires-Python: >=3.10
Requires-Dist: numpy>=1.24
Requires-Dist: cffi>=1.16
Provides-Extra: test
Requires-Dist: pytest>=7; extra == "test"
Requires-Dist: pytest-timeout>=2; extra == "test"
Provides-Extra: dev
Requires-Dist: bump-my-version>=1.0; extra == "dev"
Description-Content-Type: text/markdown

# bam-solver

Python wrapper for the BAM (Branch-And-Model) derivative-free global
optimization solver.

Three layers of API ergonomics:

1. **`bam.minimize`**: SciPy-style functional facade.
2. **`Bam`**: full-control mirror of the BAM C API.
3. **`bam.AskTell`**: ask/tell interface for off-process or
   asynchronous evaluators.

## Requirements

- Python >= 3.10
- Linux (x86_64, aarch64), macOS (Intel, Apple Silicon), or Windows (x86_64)

No compiler and no separate BAM installation are needed: each wheel bundles
`libbam` and its runtime libraries inside the package. The only runtime
dependencies are NumPy and CFFI, installed automatically.

## Installation

```sh
pip install bam-solver
```

That is all; there is nothing else to install or configure to start solving.
BAM runs in free mode for small problems; larger problems need a license (see
**Licensing** below).

> **Building from source** (maintainers/contributors only) requires a local
> BAM build providing `bam.h` and `libbam.*`:
> ```sh
> BAM_INCLUDE_DIR=/path/to/bam/include BAM_LIB_DIR=/path/to/bam/lib \
>     uv build --wheel
> ```
> See `release/README.md` for the full in-house build/test/publish process.

## Quick examples

### Functional (SciPy-style): `bam.minimize`

```python
import bam

def shc(x):
    x1, x2 = x
    return ((4 - 2.1*x1**2 + x1**4/3) * x1**2
            + x1*x2 + (-4 + 4*x2**2) * x2**2)

res = bam.minimize(shc, x0=[0, 0],
                   bounds=[(-3, 3), (-1.5, 1.5)],
                   options={"max_evals": 80})
print(res.x, res.fun, res.nfev, res.message)
```

`bam.minimize` is also usable as the `method=` argument to
`scipy.optimize.minimize`:

```python
from scipy.optimize import minimize
res = minimize(shc, [0, 0], method=bam.minimize,
               bounds=[(-3, 3), (-1.5, 1.5)],
               options={"max_evals": 80})
```

Bounds are optional: omit them and BAM uses its default box, exactly as the
full-control `Bam` class and the C API do. Common BAM `options` keys: `max_evals`,
`max_time`, `max_iter`, `max_no_gain`, `print_to_screen`, `outfname`,
`tracefname`, `evalsfname`, `prevals`; setting `outfname`/`tracefname` enables
the listing/trace file, and `evalsfname` is required whenever `prevals` is
nonzero. Any other BAM option is forwarded verbatim with a single warning
naming it, or pass it through `raw_options={"name": value}` to forward without
the warning. The wrapper also accepts `x_evaluated`/`f_evaluated`
(pre-evaluated points) and `history=True` (attaches the full `x_hist`/`f_hist`
evaluation trajectory to the result). Use `integrality=[0, 1, ...]` for
mixed-integer problems (SciPy convention).

### Ask/tell: `bam.AskTell`

For evaluators that BAM cannot call directly (a remote simulator, a
long-running batch job, an HPC scheduler):

```python
import bam

opt = bam.AskTell(nvars=2, bounds=[(-3, 3), (-1.5, 1.5)], max_evals=80)
while not opt.is_done():
    try:
        x = opt.ask()
    except StopIteration:
        break
    f = my_simulator(x)             # may take seconds, minutes, hours
    opt.tell(x, f)
res = opt.recommendation()
print(res.x, res.fun)
```

BAM runs in a background thread; `ask()` blocks until BAM requests a
point, `tell(x, f)` feeds the result back. Bounds are optional here too
(`nvars` gives the dimension). Use the context-manager form
(`with bam.AskTell(...) as opt: ...`) so the worker thread is always
cleaned up. One ask outstanding at a time; pickling / cross-process resume
is not supported.

### Full-control: `Bam`

```python
import numpy as np
from bam import Bam

with Bam(nvars=2) as solver:
    solver.set_real_vector("xmin", [-3, -1.5])
    solver.set_real_vector("xmax", [ 3,  1.5])
    solver.set_int("maxevals", 80)
    solver.set_objective(shc)
    result = solver.solve(x0=[0.0, 0.0])

print(result.x, result.fun, result.nfev, result.message)
```

## Licensing

BAM is free for problems with up to **two** variables. Larger
problems require a license file, free for academic users at
<https://minlp.com/bam-licenses>.

The wrapper defers to BAM for license-file discovery; BAM searches
CWD, the executable's directory, and every entry of `$PATH` for a
file whose name is configured via the `licfname` string option
(default `bamlice.txt`). To override:

```python
import bam
bam.set_license_file("/path/to/bam.lic")
# or set BAM_LICENSE_FILE in the environment before importing bam
```

Diagnostics: `bam.license_status()` returns a dict with `state`,
`path`, and `free_limit_nvars`. If BAM is in free mode at solve
time the wrapper emits a one-time `BamLicenseWarning`.

## Tests

```sh
pytest                                   # runs the in-package suite
BAM_TEST_LICENSE=/usr/local/bin/bamlice.txt pytest    # also exercises licensed-mode paths
```
