[Fix] Improve rank-deficient detection and bump odrpack to >=0.5

Fix incorrect ODRPACK95 info code parsing: rank deficiency is encoded
in the tens digit (info // 10 % 10), not the hundreds digit. Add
irank and inv_condnum to the warning message for diagnostics.
This commit is contained in:
Fabian Joswig 2026-03-29 20:41:19 +02:00
commit 8b3b1f3c95
2 changed files with 11 additions and 7 deletions

View file

@ -670,13 +670,17 @@ def total_least_squares(x, y, func, silent=False, **kwargs):
print('Residual variance:', output.residual_variance)
if not out.success:
# info % 5 gives the convergence status: 1=sum-of-sq, 2=param, 3=both
# If odrpack reports rank deficiency (e.g. vanishing chi-squared when
# n_obs == n_parms), convergence was still achieved allow with a warning.
if out.info % 5 in [1, 2, 3]:
# ODRPACK95 info code structure (see User Guide §4):
# info % 10 -> convergence: 1=sum-of-sq, 2=param, 3=both
# info // 10 % 10 -> 1 = problem not full rank at solution
convergence_status = out.info % 10
rank_deficient = (out.info // 10 % 10) == 1
if convergence_status in [1, 2, 3] and rank_deficient:
warnings.warn(
"ODR fit is rank deficient. This may indicate a vanishing "
"chi-squared (n_obs == n_parms). Results may be unreliable.",
f"ODR fit is rank deficient (irank={out.irank}, inv_condnum={out.inv_condnum:.2e}). "
"This may indicate a vanishing chi-squared (n_obs == n_parms). "
"Results may be unreliable.",
RuntimeWarning
)
else:

View file

@ -25,7 +25,7 @@ setup(name='pyerrors',
license="MIT",
packages=find_packages(),
python_requires='>=3.10.0',
install_requires=['numpy>=2.0', 'autograd>=1.7.0', 'numdifftools>=0.9.41', 'matplotlib>=3.9', 'scipy>=1.13', 'iminuit>=2.28', 'h5py>=3.11', 'lxml>=5.0', 'python-rapidjson>=1.20', 'pandas>=2.2', 'odrpack>=0.4'],
install_requires=['numpy>=2.0', 'autograd>=1.7.0', 'numdifftools>=0.9.41', 'matplotlib>=3.9', 'scipy>=1.13', 'iminuit>=2.28', 'h5py>=3.11', 'lxml>=5.0', 'python-rapidjson>=1.20', 'pandas>=2.2', 'odrpack>=0.5'],
extras_require={'test': ['pytest', 'pytest-cov', 'pytest-benchmark', 'hypothesis', 'nbmake', 'flake8']},
classifiers=[
'Development Status :: 5 - Production/Stable',