Skip to content

Commit

Permalink
ENH/FIX: coerce 'data' and 'independent_var' in Model class
Browse files Browse the repository at this point in the history
- input 'data' will always become 'float64' or 'complex128'
- coercion is only done for certain data types in case of
    an 'independent_var' to still allow for more complicated
    (user-defined) data types

See: lmfit#723
Closes: lmfit#727
  • Loading branch information
reneeotten committed May 29, 2021
1 parent c4022eb commit 6caaaf0
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 11 deletions.
1 change: 1 addition & 0 deletions doc/whatsnew.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ New features:
Bug fixes/enhancements:
- do not overwrite user-specified figure titles in Model.plot() functions and allow setting with 'title' keyword argument (PR #711)
- preserve Parameters subclass in deepcopy (@jenshnielsen; PR #719)
- coerce ``data`` and ``indepdent_vars`` to NumPy array with ``dtype=float64`` whenever applicable (Issues #723 and #727)

Various:
- update asteval dependency to >=0.9.22 to avoid DeprecationWarnings from NumPy v1.20.0 (PR #707)
Expand Down
31 changes: 20 additions & 11 deletions lmfit/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -982,15 +982,6 @@ def fit(self, data, params=None, weights=None, method='leastsq',
msg += 'Non initialized parameters: %s' % str(blank)
raise ValueError(msg)

# Do not alter anything that implements the array interface (np.array, pd.Series)
# but convert other iterables (e.g., Python lists) to NumPy arrays.
if not hasattr(data, '__array__'):
data = np.asfarray(data)
for var in self.independent_vars:
var_data = kwargs[var]
if isinstance(var_data, (list, tuple)):
kwargs[var] = np.asfarray(var_data)

# Handle null/missing values.
if nan_policy is not None:
self.nan_policy = nan_policy
Expand All @@ -1005,12 +996,30 @@ def fit(self, data, params=None, weights=None, method='leastsq',

# If independent_vars and data are alignable (pandas), align them,
# and apply the mask from above if there is one.

for var in self.independent_vars:
if not np.isscalar(kwargs[var]):
# print("Model fit align ind dep ", var, mask.sum())
kwargs[var] = _align(kwargs[var], mask, data)

# Make sure `dtype` for data is always `float64` or `complex128`
if np.isrealobj(data):
data = np.asfarray(data)
elif np.iscomplexobj(data):
data = np.asarray(data, dtype='complex128')

# Coerce `dtype` for independent variable(s) to `float64` or
# `complex128` when the variable has one of the following types: list,
# tuple, numpy.ndarray, or pandas.Series
for var in self.independent_vars:
var_data = kwargs[var]
if isinstance(var_data, (list, tuple)):
kwargs[var] = np.asfarray(var_data)
elif (isinstance(var_data, (np.ndarray, Series)) and
np.isrealobj(var_data)):
kwargs[var] = np.asfarray(var_data)
elif (isinstance(var_data, (np.ndarray, Series)) and
np.iscomplexobj(var_data)):
kwargs[var] = np.asarray(var_data, dtype='complex128')

if fit_kws is None:
fit_kws = {}

Expand Down

0 comments on commit 6caaaf0

Please sign in to comment.