Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Retain default values for keyword arguments when manually choosing param_names #918

Closed
schtandard opened this issue Nov 7, 2023 · 0 comments

Comments

@schtandard
Copy link
Contributor

Description

I assume that the current behavior is intended, so I consider this a feature request.

By default, all model function arguments are turned into model parameters unless they are an independent variable or they have a non-numeric default value. Those arguments with a default value get turned into parameters with that as their initial value. However, when explicitly choosing the parameters using param_names, this stops being true and one has to set all initial values manually which feels redundant.

It would be really nice if the initial values were derived from the default argument values even when using param_names.

A Minimal, Complete, and Verifiable example
import lmfit

def foo(x, a=3, b=5, s=1):
    return a + s * b * x**2

print("\nDefault behavior:")
mdl = lmfit.Model(foo)
params = mdl.make_params()
for pname, par in params.items():
    print(pname, par)

print("\nExplicitly choosing parameter names:")
mdl = lmfit.Model(foo, param_names=['a', 'b'])
params = mdl.make_params()
for pname, par in params.items():
    print(pname, par)

print("\nWe have to explicitly set the initial values:")
mdl = lmfit.Model(foo, param_names=['a', 'b'])
mdl.set_param_hint('a', value=3)
mdl.set_param_hint('b', value=5)
params = mdl.make_params()
for pname, par in params.items():
    print(pname, par)

print("\nIn this particular case, we could cheat by using True instead of 1, but that's very hacky:")
def foo(x, a=3, b=5, s=True):
    return a + s * b * x**2
mdl = lmfit.Model(foo)
params = mdl.make_params()
for pname, par in params.items():
    print(pname, par)

Output:

Default behavior:
a <Parameter 'a', value=3, bounds=[-inf:inf]>
b <Parameter 'b', value=5, bounds=[-inf:inf]>
s <Parameter 's', value=1, bounds=[-inf:inf]>

Explicitly choosing parameter names:
a <Parameter 'a', value=-inf, bounds=[-inf:inf]>
b <Parameter 'b', value=-inf, bounds=[-inf:inf]>

We have to explicitly set the initial values:
a <Parameter 'a', value=3, bounds=[-inf:inf]>
b <Parameter 'b', value=5, bounds=[-inf:inf]>

In this particular case, we could cheat by using True instead of 1, but that's very hacky:
a <Parameter 'a', value=3, bounds=[-inf:inf]>
b <Parameter 'b', value=5, bounds=[-inf:inf]>
Version information
Python: 3.9.18 | packaged by conda-forge | (main, Aug 30 2023, 03:40:31) [MSC v.1929 64 bit (AMD64)]

lmfit: 1.2.2, scipy: 1.11.3, numpy: 1.26.0,asteval: 0.9.31, uncertainties: 3.1.7
@lmfit lmfit locked and limited conversation to collaborators Nov 7, 2023
@reneeotten reneeotten converted this issue into discussion #919 Nov 7, 2023

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant