Global fitting of separate signals by models that may share parameters#1018
Global fitting of separate signals by models that may share parameters#1018erik-mansson wants to merge 1 commit intolmfit:masterfrom
Conversation
… models that may share parameters. A previous object-oriented version, including some questionable __mro__-modification for a PrefixedWrapper, was uploaded in https://github.com/orgs/lmfit/discussions/1012 but this new version is somewhat reduced in scope and is implented without any new classes. tests/test_global_fit.py has 8 fairly long test cases that can be read as extended usage examples, with plotting and some assertions at the end. Three consise examples intended as user documentation are in the module-level docstring of lmfit/global_fit.py.
|
@erik-mansson Thanks. But as in #1012, and started with #1015, I am pretty sure we want to use a Dataset container. In the code here, FWIW, independent variables really must be separately specified for each data array to be fit. Nothing about the shape or type of the independent variables can be assumed to be consistent for different sets of data. Encapsulating Like nearly every other Python project, documentation uses RST and Sphinx. Docstrings are fine, but separate docs beyond the API documentation of a docstring are also valuable. So, thanks for the PR but I think we want a better representation. |
|
Thanks for taking a look.
Well, in this PR, prefixes are not necessarily the same as the dict keys or list indices: I.e. the user has to either use some string keys or accept that list order matters for associating data and models, but
Yes. While possible with my |
Proposing tools to facilitate "global fitting" of separate signals by models that may share parameters.
Description
In principle, global fitting is already possible if one writes a custom function like in https://lmfit.github.io/lmfit-py/examples/example_fit_multi_datasets.html to concatenate all residuals to a single 1D signal array. But that example uses an objective-function to
minimize(), rather than the perspective of curve model functions to fit signals. It also seems undesirable that every user would have to manage boilerplate code like that rather than work at the higher abstraction level of "I have these signals with associated models, now I just want to fit them with some parameters shared instead of as independent fits".My previous object-oriented version that allowed multi-model fitting was uploaded in https://github.com/orgs/lmfit/discussions/1012 but it was not ready for inclusion in lmfit and included some questionable
__mro__-modification for a PrefixedWrapper class (able to prefix an already existingModelinstance) which in hindsight is a separate topic and not very important for global fitting. This this new version is somewhat reduced in scope and is implemented without any new classes, rather closer to a functional style. The main functionality happens by a call tomulti_fit()and there are supporting functions that may be used to facilitate the preparation of models, parameters and constraints. As data structure for the signal data arrays, the associated models and any additional information (weights, keyword arguments like independent variables) this implementation supports both dicts with string keys (more informative) and lists with automatic numeric indices (shorter to write, suitable when the signal data comes as rows of a 2D-array).TODO-markers in the code point out things that could be improved, e.g. perhaps another class than
ModelResultto better represent such a multi-signal & multi-model fit. If people want it, I'm not completely against retrying an object-oriented approach also for something like a multi-model wrapper, but it was slightly improper to have it as a subclass of Model when some methods need to take different arguments or return different types of objects.tests/test_global_fit.py has eight fairly long test cases that can be read as extended usage examples, with plotting and some assertions at the end. They give a test coverage of 72% which can of course be increased in case this PR has chances of being accepted. Three concise examples intended as user documentation are in the module-level docstring of lmfit/global_fit.py. I have not familiarized myself with the production of HTML documentation or whether I used enough markup in the docstrings, but I suppose a HTML page could be useful to create, for showing something like the the concise examples nicely formatted on the web.
Type of Changes
Tested on
Python: 3.10.10 | packaged by conda-forge | (main, Mar 24 2023, 20:08:06) [GCC 11.3.0]
lmfit: 1.2.2, scipy: 1.10.1, numpy: 1.24.4, asteval: 0.9.29, uncertainties: 3.1.7
Python: 3.13.3 | packaged by conda-forge | (main, Apr 14 2025, 20:44:03) [GCC 13.3.0]
lmfit: 1.3.3, scipy: 1.15.2, numpy: 2.2.5, asteval: 1.0.6, uncertainties: 3.2.3
lmfit: latest from git 26 August 2025, scipy: 1.15.2, numpy: 2.2.5, asteval: 1.0.6, uncertainties: 3.2.3
Verification