Metadata-Version: 2.4
Name: pls4all
Version: 1.0.6
Summary: Slim PLS-focused Python binding for the libn4m C ABI from nirs4all-methods.
Author: Grégory Beurier and contributors
License-Expression: CECILL-2.1
Project-URL: Homepage, https://github.com/GBeurier/nirs4all-methods
Project-URL: Repository, https://github.com/GBeurier/nirs4all-methods
Project-URL: Issues, https://github.com/GBeurier/nirs4all-methods/issues
Project-URL: Documentation, https://methods.nirs4all.org/
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Developers
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
Classifier: Topic :: Scientific/Engineering :: Chemistry
Classifier: Topic :: Scientific/Engineering :: Mathematics
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.21
Dynamic: license-file

# pls4all

`pls4all` is the slim, PLS-only subset of **nirs4all-methods** — a thin Python
binding over the portable `libn4m` C ABI (a C++17 PLS / NIRS engine). The wheel
bundles the `libn4m` shared library, so `pip install pls4all` is self-contained;
no separate native build is required. For the full method surface (preprocessing,
selectors, diagnostics, augmenters, …) install the `nirs4all-methods` package
instead and import it as `n4m` — both load the same `libn4m`.

The binding loads `libn4m` with `ctypes.CDLL` (so the GIL is released during
native calls) and exposes:

- `version()` / `abi_version()` introspection,
- a Pythonic `Context` and `Config` (RAII lifecycle wrappers),
- the PLS fit/predict surface and a scikit-learn-compatible
  `pls4all.sklearn.PLSRegression` (and the other PLS-family estimators),
- a typed `Pls4allError` raised on any non-OK status, carrying the
  context's `last_error` message.

## Quick start

```python
import numpy as np
import pls4all
from pls4all.sklearn import PLSRegression

print(pls4all.version())      # e.g. "1.0.3+abi.2.0.0"
print(pls4all.abi_version())  # (2, 0, 0)

rng = np.random.default_rng(0)
X = rng.standard_normal((40, 12))
y = X @ rng.standard_normal(12)

model = PLSRegression(n_components=5).fit(X, y)
print(model.predict(X).shape)  # (40,)
```

Low-level lifecycle, if you need it:

```python
with pls4all.Context() as ctx, pls4all.Config() as cfg:
    cfg.algorithm = pls4all.Algorithm.PLS_REGRESSION
    cfg.solver = pls4all.Solver.SIMPLS
    cfg.n_components = 5
    # ... drive a fit through the C ABI ...
```

`scikit-learn` is an optional dependency (only `pls4all.sklearn` needs it); the
core `import pls4all` works with NumPy alone.

## Loading `libn4m`

The bundled wheel ships `libn4m` inside `pls4all/lib/`, found automatically. For
development against a local build the loader searches, in order:

1. `$PLS4ALL_LIB_PATH` — explicit path to `libn4m` for this package,
2. `$N4M_LIB_PATH` — shared `libn4m` override honoured by both `pls4all` and `n4m`,
3. `pls4all/lib/libn4m*` next to the installed package (wheel layout),
4. `<repo-root>/build/dev-release/cpp/src/libn4m*` (developer convenience),
5. the standard system search path (`LD_LIBRARY_PATH`, macOS rpath, Windows `PATH`).

## Building `libn4m` from source (developers)

```bash
cmake --preset dev-release
cmake --build --preset dev-release --parallel
```

This produces `build/dev-release/cpp/src/libn4m.so` (`.dylib` / `.dll` on
macOS / Windows), which the loader rules above pick up.

See <https://github.com/GBeurier/nirs4all-methods> for the full project.
