Releases: Gnpd/HSPiPy
1.1.8
What's Changed
Bug Fixes
- Classic algorithm no longer freezes on certain datasets: the hill-climb loop in both single and double sphere modes could traverse large flat landscapes indefinitely due to a radius tie-breaking condition. The algorithm now only moves on strict datafit improvement, with radius minimization resolved once at convergence.
- Double sphere containment constraint bug fix: the containment check in
_classic_two_fitwas evaluated against the stale center position rather than the candidate being tested, leading to incorrect constraint enforcement.
Performance Improvements
- Classic algorithm: radius search is now fully vectorized — all ~87 candidates are evaluated in a single NumPy broadcast per corner instead of individual
compute_datafitcalls. All 8 corner distances are also computed simultaneously, significantly reducing per-iteration overhead. - Differential evolution: the loss functions now support batch evaluation of the entire population
(n_params, S) → (S,)in one NumPy operation, enabled via scipy'svectorized=Truemode. This replaces the previous per-member Python call loop.
Parameter Defaults Updated
de_maxiter:2000 → 1000(convergence typically occurs well before this limit)de_updating:'immediate' → 'deferred'(required by scipy for vectorized evaluation)
Full Changelog: v1.1.7...v1.1.8
1.1.7
fix: correct HSP sphere visualization by scaling D axis by 2
The Hansen distance formula sqrt(4·dD² + dP² + dH²) defines an ellipsoid with semi-axis R/2 in D and R in P and H. The previous code drew a Euclidean sphere of radius R, making the visual boundary twice too wide in D — solvents with RED > 1 (outside) could appear inside the drawn shape.
Fix by plotting 2D on the D axis (matching the standard HSP convention), which maps the true ellipsoidal boundary to a perfect circle/sphere in the plot. A FuncFormatter divides tick values by 2 so axis labels still display real D values. Applies to all D-bearing axes in both plot_3d (y-axis) and plot_2d (ax2 H×D and ax3 P×D). The P×H subplot is unaffected since both axes have coefficient 1 in the Hansen formula.
1.1.6
fix: make Score optional in HSDXReader to handle unclassified solvents
HSDX files with Score="-" (no classification done yet) were silently dropping all rows because float("-") raised ValueError before reaching
_validate_dataframe's existing coercion logic. Score is now passed through as-is and coerced to NaN downstream, consistent with HSDReader.
1.1.5
Add solvent classification counts to HSPResult
HSPResult now exposes n_solvents_in, n_solvents_out, n_total, n_wrong_in (false positives), and n_wrong_out (false negatives).
Stats are computed in HSPEstimator.score() and work for both single- and double-sphere models. Updated repr, HTML display, tests, and documentation accordingly.
1.1.4
return HSPResult from get() with Jupyter-friendly display
Replace the bare tuple return value of HSP.get() with HSPResult, a lightweight result object that renders as a formatted table in Jupyter
notebooks via repr_html() and as plain text via repr(). Attributes (.hsp, .radius, .error, .accuracy, .datafit) replace positional tuple
unpacking. Update README and docs/HSP.md to reflect the new return type, fix some typos, and bump version to 1.1.4.
v1.1.3
fix bugs, add type hints, replace print with logging, expand tests
- Fix missing numpy import in readers.py (NameError at runtime)
- Remove dead code
return DATAFITin hsp_estimator.py - Fix n_spheres dispatch: classic fit now correctly routes to _classic_two_fit only when n_spheres == 2 (was >= 2)
- Fix duplicate scatter in plot_3d() (good solvents plotted twice)
- Make plot_3d(), plot_2d(), and plots() return their figure objects (plots() previously returned None despite docstring claiming otherwise)
- Replace all print() calls in library code with logging.getLogger()
- Add type hints to public API: fit, predict, transform, score, read, get, plot_3d, plot_2d, plots, and all utils/loss functions
- Improve docstrings: _binarize_labels label semantics, compute_datafit DATAFIT formula, transform RED metric, loss penalty rationale
- Make discovery walker skip modules with missing optional dependencies
- Add tests/test_hsp.py and tests/test_readers.py (18 new tests)
1.1.1
1.0.0
Final release for 1.0.0:
- Read solvent data from multiple formats (CSV, HSD, HSDX)
- Calculate Hansen Solubility Parameters using robust optimization methods
- Support for single or multiple (up to 2) solubility spheres
- Fully compatible with scikit-learn for machine learning workflows