fitwise 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.
Files changed (63) hide show
  1. fitwise-0.1.0/.gitignore +229 -0
  2. fitwise-0.1.0/CHANGELOG.md +27 -0
  3. fitwise-0.1.0/LICENSE +28 -0
  4. fitwise-0.1.0/PKG-INFO +104 -0
  5. fitwise-0.1.0/README.md +55 -0
  6. fitwise-0.1.0/pyproject.toml +170 -0
  7. fitwise-0.1.0/src/fitwise/__init__.py +30 -0
  8. fitwise-0.1.0/src/fitwise/_typing.py +11 -0
  9. fitwise-0.1.0/src/fitwise/_validate.py +110 -0
  10. fitwise-0.1.0/src/fitwise/api.py +230 -0
  11. fitwise-0.1.0/src/fitwise/backends/__init__.py +6 -0
  12. fitwise-0.1.0/src/fitwise/backends/base.py +103 -0
  13. fitwise-0.1.0/src/fitwise/backends/least_squares.py +145 -0
  14. fitwise-0.1.0/src/fitwise/model.py +450 -0
  15. fitwise-0.1.0/src/fitwise/models/__init__.py +21 -0
  16. fitwise-0.1.0/src/fitwise/models/_heuristics.py +105 -0
  17. fitwise-0.1.0/src/fitwise/models/basic.py +102 -0
  18. fitwise-0.1.0/src/fitwise/models/curves.py +136 -0
  19. fitwise-0.1.0/src/fitwise/models/peaks.py +105 -0
  20. fitwise-0.1.0/src/fitwise/parameters.py +115 -0
  21. fitwise-0.1.0/src/fitwise/plotting.py +103 -0
  22. fitwise-0.1.0/src/fitwise/py.typed +0 -0
  23. fitwise-0.1.0/src/fitwise/report.py +154 -0
  24. fitwise-0.1.0/src/fitwise/result.py +361 -0
  25. fitwise-0.1.0/src/fitwise/serialize.py +138 -0
  26. fitwise-0.1.0/src/fitwise/warnings.py +48 -0
  27. fitwise-0.1.0/tests/conftest.py +16 -0
  28. fitwise-0.1.0/tests/data/nist/Bennett5.dat +214 -0
  29. fitwise-0.1.0/tests/data/nist/BoxBOD.dat +66 -0
  30. fitwise-0.1.0/tests/data/nist/Chwirut1.dat +274 -0
  31. fitwise-0.1.0/tests/data/nist/Chwirut2.dat +114 -0
  32. fitwise-0.1.0/tests/data/nist/DanWood.dat +66 -0
  33. fitwise-0.1.0/tests/data/nist/ENSO.dat +228 -0
  34. fitwise-0.1.0/tests/data/nist/Eckerle4.dat +95 -0
  35. fitwise-0.1.0/tests/data/nist/Gauss1.dat +310 -0
  36. fitwise-0.1.0/tests/data/nist/Gauss2.dat +310 -0
  37. fitwise-0.1.0/tests/data/nist/Gauss3.dat +310 -0
  38. fitwise-0.1.0/tests/data/nist/Hahn1.dat +296 -0
  39. fitwise-0.1.0/tests/data/nist/Kirby2.dat +211 -0
  40. fitwise-0.1.0/tests/data/nist/Lanczos1.dat +84 -0
  41. fitwise-0.1.0/tests/data/nist/Lanczos2.dat +84 -0
  42. fitwise-0.1.0/tests/data/nist/Lanczos3.dat +84 -0
  43. fitwise-0.1.0/tests/data/nist/MGH09.dat +71 -0
  44. fitwise-0.1.0/tests/data/nist/MGH10.dat +76 -0
  45. fitwise-0.1.0/tests/data/nist/MGH17.dat +93 -0
  46. fitwise-0.1.0/tests/data/nist/Misra1a.dat +74 -0
  47. fitwise-0.1.0/tests/data/nist/Misra1b.dat +74 -0
  48. fitwise-0.1.0/tests/data/nist/Misra1c.dat +74 -0
  49. fitwise-0.1.0/tests/data/nist/Misra1d.dat +74 -0
  50. fitwise-0.1.0/tests/data/nist/Nelson.dat +188 -0
  51. fitwise-0.1.0/tests/data/nist/Rat42.dat +69 -0
  52. fitwise-0.1.0/tests/data/nist/Rat43.dat +75 -0
  53. fitwise-0.1.0/tests/data/nist/Roszman1.dat +85 -0
  54. fitwise-0.1.0/tests/data/nist/Thurber.dat +97 -0
  55. fitwise-0.1.0/tests/nist_strd.py +251 -0
  56. fitwise-0.1.0/tests/synthetic.py +156 -0
  57. fitwise-0.1.0/tests/test_fit.py +333 -0
  58. fitwise-0.1.0/tests/test_model.py +198 -0
  59. fitwise-0.1.0/tests/test_models.py +106 -0
  60. fitwise-0.1.0/tests/test_nist.py +40 -0
  61. fitwise-0.1.0/tests/test_nist_fixtures.py +49 -0
  62. fitwise-0.1.0/tests/test_output.py +191 -0
  63. fitwise-0.1.0/tests/test_package.py +12 -0
@@ -0,0 +1,229 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[codz]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py.cover
50
+ *.lcov
51
+ .hypothesis/
52
+ .pytest_cache/
53
+ cover/
54
+
55
+ # Translations
56
+ *.mo
57
+ *.pot
58
+
59
+ # Django stuff:
60
+ *.log
61
+ local_settings.py
62
+ db.sqlite3
63
+ db.sqlite3-journal
64
+
65
+ # Flask stuff:
66
+ instance/
67
+ .webassets-cache
68
+
69
+ # Scrapy stuff:
70
+ .scrapy
71
+
72
+ # Sphinx documentation
73
+ docs/_build/
74
+
75
+ # PyBuilder
76
+ .pybuilder/
77
+ target/
78
+
79
+ # Jupyter Notebook
80
+ .ipynb_checkpoints
81
+
82
+ # IPython
83
+ profile_default/
84
+ ipython_config.py
85
+
86
+ # pyenv
87
+ # For a library or package, you might want to ignore these files since the code is
88
+ # intended to run in multiple environments; otherwise, check them in:
89
+ # .python-version
90
+
91
+ # pipenv
92
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
93
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
94
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
95
+ # install all needed dependencies.
96
+ # Pipfile.lock
97
+
98
+ # uv
99
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
100
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
101
+ # commonly ignored for libraries.
102
+ # uv.lock
103
+
104
+ # poetry
105
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
106
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
107
+ # commonly ignored for libraries.
108
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
109
+ # poetry.lock
110
+ # poetry.toml
111
+
112
+ # pdm
113
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
114
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
115
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
116
+ # pdm.lock
117
+ # pdm.toml
118
+ .pdm-python
119
+ .pdm-build/
120
+
121
+ # pixi
122
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
123
+ # pixi.lock
124
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
125
+ # in the .venv directory. It is recommended not to include this directory in version control.
126
+ .pixi/*
127
+ !.pixi/config.toml
128
+
129
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
130
+ __pypackages__/
131
+
132
+ # Celery stuff
133
+ celerybeat-schedule*
134
+ celerybeat.pid
135
+
136
+ # Redis
137
+ *.rdb
138
+ *.aof
139
+ *.pid
140
+
141
+ # RabbitMQ
142
+ mnesia/
143
+ rabbitmq/
144
+ rabbitmq-data/
145
+
146
+ # ActiveMQ
147
+ activemq-data/
148
+
149
+ # SageMath parsed files
150
+ *.sage.py
151
+
152
+ # Environments
153
+ .env
154
+ .envrc
155
+ .venv
156
+ env/
157
+ venv/
158
+ ENV/
159
+ env.bak/
160
+ venv.bak/
161
+
162
+ # Spyder project settings
163
+ .spyderproject
164
+ .spyproject
165
+
166
+ # Rope project settings
167
+ .ropeproject
168
+
169
+ # mkdocs/Zensical documentation
170
+ /site
171
+
172
+ # mypy
173
+ .mypy_cache/
174
+ .dmypy.json
175
+ dmypy.json
176
+
177
+ # Pyre type checker
178
+ .pyre/
179
+
180
+ # pytype static type analyzer
181
+ .pytype/
182
+
183
+ # Cython debug symbols
184
+ cython_debug/
185
+
186
+ # PyCharm
187
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
188
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
189
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
190
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
191
+ # .idea/
192
+
193
+ # Abstra
194
+ # Abstra is an AI-powered process automation framework.
195
+ # Ignore directories containing user credentials, local state, and settings.
196
+ # Learn more at https://abstra.io/docs
197
+ .abstra/
198
+
199
+ # Visual Studio Code
200
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore that
201
+ # can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
202
+ # and can be added to the global gitignore or merged into this file. However, if you prefer, you
203
+ # could uncomment the following to ignore the entire vscode folder
204
+ # .vscode/
205
+ # Temporary file for partial code execution
206
+ tempCodeRunnerFile.py
207
+
208
+ # Ruff stuff:
209
+ .ruff_cache/
210
+
211
+ # PyPI configuration file
212
+ .pypirc
213
+
214
+ # Marimo
215
+ marimo/_static/
216
+ marimo/_lsp/
217
+ __marimo__/
218
+
219
+ # Streamlit
220
+ .streamlit/secrets.toml
221
+
222
+ # macOS
223
+ .DS_Store
224
+
225
+ # Sphinx / sphinx-gallery output
226
+ docs/_build/
227
+ docs/auto_examples/
228
+ docs/generated/
229
+ docs/sg_execution_times.rst
@@ -0,0 +1,27 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented in this file.
4
+ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
5
+ and the project adheres to [Semantic Versioning](https://semver.org/).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [0.1.0] - 2026-10-22
10
+
11
+ First public release.
12
+
13
+ ### Added
14
+
15
+ - `fitwise.fit()` with `yerr`, `p0`, `bounds`, `fixed`, `scale_covar` and `nan_policy`.
16
+ - `Model` from plain Python functions; composition with `+` and `*`, automatic prefixes.
17
+ - Built-in models: `constant`, `linear`, `polynomial`, `gaussian`, `lorentzian`, `voigt`,
18
+ `exponential`, `sigmoid`, `powerlaw`, `damped_sine`, all with starting-value heuristics.
19
+ - Nonlinear least squares on `scipy.optimize.least_squares` with normalized parameters and
20
+ restarts; all 27 NIST StRD problems are solved from both starting points.
21
+ - `FitResult` with goodness-of-fit statistics, a documented covariance convention and
22
+ warnings for questionable results.
23
+ - Text report, `plot()` with residual panel, `to_dict()` for JSON export.
24
+ - Documentation: quickstart, guides on models and uncertainties, 10 gallery examples.
25
+
26
+ [Unreleased]: https://github.com/maroba/fitwise/compare/v0.1.0...HEAD
27
+ [0.1.0]: https://github.com/maroba/fitwise/releases/tag/v0.1.0
fitwise-0.1.0/LICENSE ADDED
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026, Matthias Baer
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
fitwise-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,104 @@
1
+ Metadata-Version: 2.5
2
+ Name: fitwise
3
+ Version: 0.1.0
4
+ Summary: Curve fitting made easy: one call, one fit, one report you can trust.
5
+ Project-URL: Homepage, https://github.com/maroba/fitwise
6
+ Project-URL: Documentation, https://maroba.github.io/fitwise/
7
+ Project-URL: Repository, https://github.com/maroba/fitwise
8
+ Project-URL: Issues, https://github.com/maroba/fitwise/issues
9
+ Project-URL: Changelog, https://github.com/maroba/fitwise/blob/main/CHANGELOG.md
10
+ Author-email: Matthias Baer <matthias.r.baer@googlemail.com>
11
+ License-Expression: BSD-3-Clause
12
+ License-File: LICENSE
13
+ Keywords: curve fitting,data analysis,least squares,lmfit,regression,uncertainty
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Intended Audience :: Education
16
+ Classifier: Intended Audience :: Science/Research
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Programming Language :: Python :: 3.14
23
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
24
+ Classifier: Topic :: Scientific/Engineering :: Physics
25
+ Classifier: Typing :: Typed
26
+ Requires-Python: >=3.11
27
+ Requires-Dist: lmfit>=1.3
28
+ Requires-Dist: numpy>=1.26
29
+ Requires-Dist: scipy>=1.12
30
+ Provides-Extra: all
31
+ Requires-Dist: matplotlib>=3.8; extra == 'all'
32
+ Requires-Dist: odrpack>=0.6; extra == 'all'
33
+ Requires-Dist: pandas>=2.1; extra == 'all'
34
+ Requires-Dist: pint>=0.23; extra == 'all'
35
+ Requires-Dist: sympy>=1.12; extra == 'all'
36
+ Requires-Dist: uncertainties>=3.2; extra == 'all'
37
+ Provides-Extra: batch
38
+ Requires-Dist: pandas>=2.1; extra == 'batch'
39
+ Provides-Extra: odr
40
+ Requires-Dist: odrpack>=0.6; extra == 'odr'
41
+ Provides-Extra: plot
42
+ Requires-Dist: matplotlib>=3.8; extra == 'plot'
43
+ Provides-Extra: symbolic
44
+ Requires-Dist: sympy>=1.12; extra == 'symbolic'
45
+ Provides-Extra: units
46
+ Requires-Dist: pint>=0.23; extra == 'units'
47
+ Requires-Dist: uncertainties>=3.2; extra == 'units'
48
+ Description-Content-Type: text/markdown
49
+
50
+ # fitwise
51
+
52
+ **One call. One fit. One report you can trust.**
53
+
54
+ [![Tests](https://github.com/maroba/fitwise/actions/workflows/test.yml/badge.svg)](https://github.com/maroba/fitwise/actions/workflows/test.yml)
55
+ [![PyPI](https://img.shields.io/pypi/v/fitwise.svg)](https://pypi.org/project/fitwise/)
56
+ [![License: BSD-3-Clause](https://img.shields.io/badge/license-BSD--3--Clause-blue.svg)](LICENSE)
57
+
58
+ > **Status: alpha (0.1).** Fitting, built-in models, report, plot and export work and are
59
+ > tested against the NIST reference data. The API may still change before 1.0.
60
+ > **Documentation: https://maroba.github.io/fitwise/**
61
+
62
+ `fitwise` is an ergonomic layer over [`lmfit`](https://lmfit.github.io/lmfit-py/) and
63
+ [`scipy`](https://scipy.org/) for curve fitting in the lab. It brings no new solver of its own.
64
+ Instead it makes the existing ones fast to use and hard to misuse:
65
+
66
+ ```python
67
+ import fitwise as fw
68
+
69
+ result = fw.fit(fw.models.gaussian, x, y, yerr=dy)
70
+ print(result) # report: parameters ± errors, χ²/ndf, R², correlations, warnings
71
+ result.plot() # data, fit, confidence band, residuals
72
+ result.params["sigma"] # value, uncertainty, unit
73
+ ```
74
+
75
+ ## What it does for you
76
+
77
+ - **Picks the solver:** direct linear least squares when the model is linear in its parameters,
78
+ Levenberg–Marquardt otherwise, and orthogonal distance regression when `xerr` is given.
79
+ - **Finds starting values,** including for your own functions, and shows how it found them.
80
+ - **Gives honest uncertainties:** a documented covariance convention, confidence and prediction
81
+ bands, and bootstrap or profile likelihood on request.
82
+ - **Warns instead of returning wrong numbers:** non-convergence, parameters at a bound, poor
83
+ χ²/ndf and strong correlations all show up in the report.
84
+ - **Makes fits reproducible:** `result.to_dict()` captures everything needed to repeat the fit.
85
+
86
+ ## Installation
87
+
88
+ ```bash
89
+ pip install fitwise # core: numpy, scipy, lmfit
90
+ pip install "fitwise[all]" # + plotting, ODR, units, symbolic models, batch fits
91
+ ```
92
+
93
+ ## Development
94
+
95
+ ```bash
96
+ uv sync --all-extras # create .venv with all extras and dev tools
97
+ uv run pre-commit install
98
+ uv run pytest # fast tests
99
+ uv run pytest -m nist # NIST StRD reference suite
100
+ ```
101
+
102
+ ## License
103
+
104
+ BSD-3-Clause
@@ -0,0 +1,55 @@
1
+ # fitwise
2
+
3
+ **One call. One fit. One report you can trust.**
4
+
5
+ [![Tests](https://github.com/maroba/fitwise/actions/workflows/test.yml/badge.svg)](https://github.com/maroba/fitwise/actions/workflows/test.yml)
6
+ [![PyPI](https://img.shields.io/pypi/v/fitwise.svg)](https://pypi.org/project/fitwise/)
7
+ [![License: BSD-3-Clause](https://img.shields.io/badge/license-BSD--3--Clause-blue.svg)](LICENSE)
8
+
9
+ > **Status: alpha (0.1).** Fitting, built-in models, report, plot and export work and are
10
+ > tested against the NIST reference data. The API may still change before 1.0.
11
+ > **Documentation: https://maroba.github.io/fitwise/**
12
+
13
+ `fitwise` is an ergonomic layer over [`lmfit`](https://lmfit.github.io/lmfit-py/) and
14
+ [`scipy`](https://scipy.org/) for curve fitting in the lab. It brings no new solver of its own.
15
+ Instead it makes the existing ones fast to use and hard to misuse:
16
+
17
+ ```python
18
+ import fitwise as fw
19
+
20
+ result = fw.fit(fw.models.gaussian, x, y, yerr=dy)
21
+ print(result) # report: parameters ± errors, χ²/ndf, R², correlations, warnings
22
+ result.plot() # data, fit, confidence band, residuals
23
+ result.params["sigma"] # value, uncertainty, unit
24
+ ```
25
+
26
+ ## What it does for you
27
+
28
+ - **Picks the solver:** direct linear least squares when the model is linear in its parameters,
29
+ Levenberg–Marquardt otherwise, and orthogonal distance regression when `xerr` is given.
30
+ - **Finds starting values,** including for your own functions, and shows how it found them.
31
+ - **Gives honest uncertainties:** a documented covariance convention, confidence and prediction
32
+ bands, and bootstrap or profile likelihood on request.
33
+ - **Warns instead of returning wrong numbers:** non-convergence, parameters at a bound, poor
34
+ χ²/ndf and strong correlations all show up in the report.
35
+ - **Makes fits reproducible:** `result.to_dict()` captures everything needed to repeat the fit.
36
+
37
+ ## Installation
38
+
39
+ ```bash
40
+ pip install fitwise # core: numpy, scipy, lmfit
41
+ pip install "fitwise[all]" # + plotting, ODR, units, symbolic models, batch fits
42
+ ```
43
+
44
+ ## Development
45
+
46
+ ```bash
47
+ uv sync --all-extras # create .venv with all extras and dev tools
48
+ uv run pre-commit install
49
+ uv run pytest # fast tests
50
+ uv run pytest -m nist # NIST StRD reference suite
51
+ ```
52
+
53
+ ## License
54
+
55
+ BSD-3-Clause
@@ -0,0 +1,170 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "fitwise"
7
+ dynamic = ["version"]
8
+ description = "Curve fitting made easy: one call, one fit, one report you can trust."
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = "BSD-3-Clause"
12
+ license-files = ["LICENSE"]
13
+ authors = [{ name = "Matthias Baer", email = "matthias.r.baer@googlemail.com" }]
14
+ keywords = ["curve fitting", "least squares", "regression", "lmfit", "uncertainty", "data analysis"]
15
+ classifiers = [
16
+ "Development Status :: 3 - Alpha",
17
+ "Intended Audience :: Science/Research",
18
+ "Intended Audience :: Education",
19
+ "Operating System :: OS Independent",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Programming Language :: Python :: 3.13",
24
+ "Programming Language :: Python :: 3.14",
25
+ "Topic :: Scientific/Engineering :: Physics",
26
+ "Topic :: Scientific/Engineering :: Mathematics",
27
+ "Typing :: Typed",
28
+ ]
29
+ dependencies = [
30
+ "numpy>=1.26",
31
+ "scipy>=1.12",
32
+ "lmfit>=1.3",
33
+ ]
34
+
35
+ [project.optional-dependencies]
36
+ plot = ["matplotlib>=3.8"]
37
+ odr = ["odrpack>=0.6"]
38
+ units = ["pint>=0.23", "uncertainties>=3.2"]
39
+ symbolic = ["sympy>=1.12"]
40
+ batch = ["pandas>=2.1"]
41
+ all = ["fitwise[plot,odr,units,symbolic,batch]"]
42
+
43
+ [project.urls]
44
+ Homepage = "https://github.com/maroba/fitwise"
45
+ Documentation = "https://maroba.github.io/fitwise/"
46
+ Repository = "https://github.com/maroba/fitwise"
47
+ Issues = "https://github.com/maroba/fitwise/issues"
48
+ Changelog = "https://github.com/maroba/fitwise/blob/main/CHANGELOG.md"
49
+
50
+ [dependency-groups]
51
+ test = [
52
+ "pytest>=8.0",
53
+ "pytest-cov>=5.0",
54
+ "hypothesis>=6.100",
55
+ ]
56
+ lint = [
57
+ "ruff>=0.14",
58
+ "mypy>=1.18",
59
+ "pre-commit>=4.0",
60
+ "scipy-stubs>=1.17.1.5",
61
+ ]
62
+ docs = [
63
+ "sphinx>=8.0",
64
+ "pydata-sphinx-theme>=0.16",
65
+ "myst-parser>=4.0",
66
+ "sphinx-gallery>=0.19",
67
+ "sphinx-copybutton>=0.5",
68
+ "matplotlib>=3.8",
69
+ ]
70
+ dev = [
71
+ { include-group = "test" },
72
+ { include-group = "lint" },
73
+ ]
74
+
75
+ [tool.uv]
76
+ default-groups = ["dev"]
77
+
78
+ [tool.hatch.version]
79
+ path = "src/fitwise/__init__.py"
80
+
81
+ [tool.hatch.build.targets.wheel]
82
+ packages = ["src/fitwise"]
83
+
84
+ [tool.hatch.build.targets.sdist]
85
+ include = ["/src", "/tests", "/LICENSE", "/README.md", "/CHANGELOG.md"]
86
+
87
+ # --- Ruff ---------------------------------------------------------------
88
+
89
+ [tool.ruff]
90
+ line-length = 100
91
+ target-version = "py311"
92
+
93
+ [tool.ruff.format]
94
+ # Code blocks in Markdown are aligned by hand for readability.
95
+ exclude = ["*.md"]
96
+
97
+ [tool.ruff.lint]
98
+ select = [
99
+ "E", "W", # pycodestyle
100
+ "F", # pyflakes
101
+ "I", # isort
102
+ "B", # bugbear
103
+ "UP", # pyupgrade
104
+ "N", # pep8-naming
105
+ "SIM", # simplify
106
+ "RUF", # ruff-specific
107
+ "NPY", # numpy
108
+ "PT", # pytest style
109
+ "D", # docstrings
110
+ ]
111
+ ignore = [
112
+ "D105", # magic methods need no docstring
113
+ "D107", # __init__ is documented on the class
114
+ "RUF001", # ambiguous unicode (σ, χ², ± are intended)
115
+ "RUF002",
116
+ "RUF003",
117
+ ]
118
+
119
+ [tool.ruff.lint.pydocstyle]
120
+ convention = "numpy"
121
+
122
+ [tool.ruff.lint.per-file-ignores]
123
+ "tests/**" = ["D"]
124
+ "conftest.py" = ["D"]
125
+ # sphinx-gallery: titled docstrings, imports per cell, physics symbols such as T or Ea
126
+ "examples/**" = ["D", "E402", "N803", "N806", "N816"]
127
+ "docs/**" = ["D"]
128
+
129
+ # --- mypy ---------------------------------------------------------------
130
+
131
+ [tool.mypy]
132
+ python_version = "3.11"
133
+ strict = true
134
+ files = ["src/fitwise"]
135
+ warn_unreachable = true
136
+
137
+ [[tool.mypy.overrides]]
138
+ module = ["lmfit.*", "odrpack.*", "pint.*", "uncertainties.*", "sympy.*"]
139
+ ignore_missing_imports = true
140
+
141
+ # --- pytest -------------------------------------------------------------
142
+
143
+ [tool.pytest.ini_options]
144
+ testpaths = ["tests", "src"]
145
+ addopts = "--strict-markers --strict-config -ra --doctest-modules"
146
+ xfail_strict = true
147
+ filterwarnings = [
148
+ "error",
149
+ # deprecations in third-party packages must not break the suite, ours must
150
+ "default::DeprecationWarning",
151
+ "default::PendingDeprecationWarning",
152
+ "error::DeprecationWarning:fitwise",
153
+ ]
154
+ markers = [
155
+ "slow: long-running tests (deselect with '-m \"not slow\"')",
156
+ "nist: NIST StRD nonlinear regression reference tests",
157
+ ]
158
+
159
+ [tool.coverage.run]
160
+ source = ["fitwise"]
161
+ branch = true
162
+
163
+ [tool.coverage.report]
164
+ fail_under = 90
165
+ show_missing = true
166
+ exclude_also = [
167
+ "if TYPE_CHECKING:",
168
+ "@overload",
169
+ "raise NotImplementedError",
170
+ ]
@@ -0,0 +1,30 @@
1
+ """fitwise: curve fitting made easy.
2
+
3
+ One call, one fit, one report you can trust.
4
+
5
+ >>> import fitwise as fw
6
+ >>> result = fw.fit(fw.models.gaussian, x, y, yerr=dy) # doctest: +SKIP
7
+ >>> print(result) # doctest: +SKIP
8
+ """
9
+
10
+ from fitwise import models, warnings
11
+ from fitwise.api import fit
12
+ from fitwise.model import CompositeModel, Model
13
+ from fitwise.parameters import Parameter, Parameters
14
+ from fitwise.result import FitResult
15
+ from fitwise.warnings import FitWarning
16
+
17
+ __version__ = "0.1.0"
18
+
19
+ __all__ = [
20
+ "CompositeModel",
21
+ "FitResult",
22
+ "FitWarning",
23
+ "Model",
24
+ "Parameter",
25
+ "Parameters",
26
+ "__version__",
27
+ "fit",
28
+ "models",
29
+ "warnings",
30
+ ]
@@ -0,0 +1,11 @@
1
+ """Shared type aliases."""
2
+
3
+ from typing import TypeAlias
4
+
5
+ import numpy as np
6
+ from numpy.typing import ArrayLike, NDArray
7
+
8
+ FloatArray: TypeAlias = NDArray[np.float64]
9
+ Bounds: TypeAlias = tuple[float, float]
10
+
11
+ __all__ = ["ArrayLike", "Bounds", "FloatArray"]