summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorPicca Frédéric-Emmanuel <picca@debian.org>2016-08-17 08:24:30 +0200
committerPicca Frédéric-Emmanuel <picca@debian.org>2016-08-17 08:24:30 +0200
commite1a98b942a00c8f8cc663535ca1e1c050a922ce3 (patch)
tree036eda82e18917e1072468d11c453e28a8ccee4f /tests
parent7be530f22592e2d2193230d863b85d2f5c91c116 (diff)
Imported Upstream version 0.9.5+dfsg
Diffstat (limited to 'tests')
-rw-r--r--tests/_test_ci.py9
-rw-r--r--tests/test_1variable.py6
-rw-r--r--tests/test_algebraic_constraint.py24
-rw-r--r--tests/test_algebraic_constraint2.py16
-rw-r--r--tests/test_basicfit.py8
-rw-r--r--tests/test_bounded_jacobian.py8
-rw-r--r--tests/test_bounds.py8
-rw-r--r--tests/test_confidence.py9
-rw-r--r--tests/test_copy_params.py6
-rw-r--r--tests/test_least_squares.py57
-rw-r--r--tests/test_model.py21
-rw-r--r--tests/test_multidatasets.py6
-rw-r--r--tests/test_nose.py103
-rw-r--r--tests/test_params_set.py2
14 files changed, 173 insertions, 110 deletions
diff --git a/tests/_test_ci.py b/tests/_test_ci.py
index 86afcaf..7e0d0f3 100644
--- a/tests/_test_ci.py
+++ b/tests/_test_ci.py
@@ -13,10 +13,10 @@ def test_ci():
p_true.add('decay', value=0.010)
def residual(pars, x, data=None):
- amp = pars['amp'].value
- per = pars['period'].value
- shift = pars['shift'].value
- decay = pars['decay'].value
+ amp = pars['amp']
+ per = pars['period']
+ shift = pars['shift']
+ decay = pars['decay']
if abs(shift) > pi / 2:
shift = shift - np.sign(shift) * pi
@@ -55,4 +55,3 @@ def test_ci():
stderr = out.params[p].stderr
assert(abs(diff1 - stderr) / stderr < 0.05)
assert(abs(diff2 - stderr) / stderr < 0.05)
-
diff --git a/tests/test_1variable.py b/tests/test_1variable.py
index 3e3d530..e7e34de 100644
--- a/tests/test_1variable.py
+++ b/tests/test_1variable.py
@@ -21,11 +21,7 @@ def linear_chisq(params, x, data, errs=None):
msg = "No intercept parameter (c) defined in the model"
raise KeyError(msg)
- m = params["m"].value
- c = params["c"].value
-
- model = m*x+c
-
+ model = params["m"]*x + params["c"]
residuals = (data-model)
if errs is not None:
residuals = residuals/errs
diff --git a/tests/test_algebraic_constraint.py b/tests/test_algebraic_constraint.py
index 1764b7f..e37cf15 100644
--- a/tests/test_algebraic_constraint.py
+++ b/tests/test_algebraic_constraint.py
@@ -5,14 +5,10 @@ from lmfit.printfuncs import report_fit
def test_constraints1():
def residual(pars, x, sigma=None, data=None):
- yg = gaussian(x, pars['amp_g'].value,
- pars['cen_g'].value, pars['wid_g'].value)
- yl = lorentzian(x, pars['amp_l'].value,
- pars['cen_l'].value, pars['wid_l'].value)
-
- slope = pars['line_slope'].value
- offset = pars['line_off'].value
- model = yg + yl + offset + x * slope
+ yg = gaussian(x, pars['amp_g'], pars['cen_g'], pars['wid_g'])
+ yl = lorentzian(x, pars['amp_l'], pars['cen_l'], pars['wid_l'])
+
+ model = yg + yl + pars['line_off'] + x * pars['line_slope']
if data is None:
return model
if sigma is None:
@@ -68,14 +64,10 @@ def test_constraints1():
def test_constraints2():
"""add a user-defined function to symbol table"""
def residual(pars, x, sigma=None, data=None):
- yg = gaussian(x, pars['amp_g'].value,
- pars['cen_g'].value, pars['wid_g'].value)
- yl = lorentzian(x, pars['amp_l'].value,
- pars['cen_l'].value, pars['wid_l'].value)
-
- slope = pars['line_slope'].value
- offset = pars['line_off'].value
- model = yg + yl + offset + x * slope
+ yg = gaussian(x, pars['amp_g'], pars['cen_g'], pars['wid_g'])
+ yl = lorentzian(x, pars['amp_l'], pars['cen_l'], pars['wid_l'])
+
+ model = yg + yl + pars['line_off'] + x * pars['line_slope']
if data is None:
return model
if sigma is None:
diff --git a/tests/test_algebraic_constraint2.py b/tests/test_algebraic_constraint2.py
index 45a9b6a..ab64cef 100644
--- a/tests/test_algebraic_constraint2.py
+++ b/tests/test_algebraic_constraint2.py
@@ -23,14 +23,10 @@ def test_constraints(with_plot=True):
with_plot = with_plot and WITHPLOT
def residual(pars, x, sigma=None, data=None):
- yg = gaussian(x, pars['amp_g'].value,
- pars['cen_g'].value, pars['wid_g'].value)
- yl = lorentzian(x, pars['amp_l'].value,
- pars['cen_l'].value, pars['wid_l'].value)
-
- slope = pars['line_slope'].value
- offset = pars['line_off'].value
- model = yg + yl + offset + x * slope
+ yg = gaussian(x, pars['amp_g'], pars['cen_g'], pars['wid_g'])
+ yl = lorentzian(x, pars['amp_l'], pars['cen_l'], pars['wid_l'])
+
+ model = yg + yl + pars['line_off'] + x * pars['line_slope']
if data is None:
return model
if sigma is None:
@@ -55,12 +51,12 @@ def test_constraints(with_plot=True):
pfit.add(name='amp_g', value=10)
pfit.add(name='cen_g', value=9)
pfit.add(name='wid_g', value=1)
-
+
pfit.add(name='amp_tot', value=20)
pfit.add(name='amp_l', expr='amp_tot - amp_g')
pfit.add(name='cen_l', expr='1.5+cen_g')
pfit.add(name='wid_l', expr='2*wid_g')
-
+
pfit.add(name='line_slope', value=0.0)
pfit.add(name='line_off', value=0.0)
diff --git a/tests/test_basicfit.py b/tests/test_basicfit.py
index 98b6338..f7f23bd 100644
--- a/tests/test_basicfit.py
+++ b/tests/test_basicfit.py
@@ -12,10 +12,10 @@ def test_basic():
# define objective function: returns the array to be minimized
def fcn2min(params, x, data):
""" model decaying sine wave, subtract data"""
- amp = params['amp'].value
- shift = params['shift'].value
- omega = params['omega'].value
- decay = params['decay'].value
+ amp = params['amp']
+ shift = params['shift']
+ omega = params['omega']
+ decay = params['decay']
model = amp * np.sin(x * omega + shift) * np.exp(-x*x*decay)
return model - data
diff --git a/tests/test_bounded_jacobian.py b/tests/test_bounded_jacobian.py
index 810a505..e88b425 100644
--- a/tests/test_bounded_jacobian.py
+++ b/tests/test_bounded_jacobian.py
@@ -14,16 +14,16 @@ def test_bounded_jacobian():
jac_count = 0
def resid(params):
- x0 = params['x0'].value
- x1 = params['x1'].value
+ x0 = params['x0']
+ x1 = params['x1']
return np.array([10 * (x1 - x0*x0), 1-x0])
def jac(params):
global jac_count
jac_count += 1
- x0 = params['x0'].value
+ x0 = params['x0']
return np.array([[-20*x0, 10], [-1, 0]])
-
+
out0 = minimize(resid, pars, Dfun=None)
assert_paramval(out0.params['x0'], 1.2243, tol=0.02)
diff --git a/tests/test_bounds.py b/tests/test_bounds.py
index 99c962d..a1f5ed4 100644
--- a/tests/test_bounds.py
+++ b/tests/test_bounds.py
@@ -11,10 +11,10 @@ def test_bounds():
p_true.add('decay', value=0.01000)
def residual(pars, x, data=None):
- amp = pars['amp'].value
- per = pars['period'].value
- shift = pars['shift'].value
- decay = pars['decay'].value
+ amp = pars['amp']
+ per = pars['period']
+ shift = pars['shift']
+ decay = pars['decay']
if abs(shift) > pi/2:
shift = shift - sign(shift)*pi
diff --git a/tests/test_confidence.py b/tests/test_confidence.py
index 2b5d290..f000d95 100644
--- a/tests/test_confidence.py
+++ b/tests/test_confidence.py
@@ -5,15 +5,10 @@ import lmfit
from lmfit_testutils import assert_paramval
def residual(params, x, data):
- a = params['a'].value
- b = params['b'].value
- return data - 1.0/(a*x)+b
+ return data - 1.0/(params['a']*x)+ params['b']
def residual2(params, x, data):
- a = params['a'].value
- b = params['b'].value
- c = params['c'].value
- return data - c/(a*x)+b
+ return data - params['c']/(params['a']*x)+params['b']
def test_confidence1():
x = np.linspace(0.3,10,100)
diff --git a/tests/test_copy_params.py b/tests/test_copy_params.py
index e17aa18..8841684 100644
--- a/tests/test_copy_params.py
+++ b/tests/test_copy_params.py
@@ -9,10 +9,7 @@ def get_data():
return x, y1, y2
def residual(params, x, data):
- a = params['a'].value
- b = params['b'].value
-
- model = a*np.exp(b*x)
+ model = params['a']*np.exp(params['b']*x)
return (data-model)
def test_copy_params():
@@ -33,4 +30,3 @@ def test_copy_params():
assert(abs(adiff) > 1.e-2)
assert(abs(bdiff) > 1.e-2)
-
diff --git a/tests/test_least_squares.py b/tests/test_least_squares.py
new file mode 100644
index 0000000..4195a4d
--- /dev/null
+++ b/tests/test_least_squares.py
@@ -0,0 +1,57 @@
+from lmfit import Parameters, minimize, fit_report, Minimizer
+from lmfit.minimizer import HAS_LEAST_SQUARES
+from lmfit_testutils import assert_paramval, assert_paramattr
+
+from numpy import linspace, zeros, sin, exp, random, pi, sign
+import nose
+
+def test_bounds():
+ if not HAS_LEAST_SQUARES:
+ raise nose.SkipTest
+ p_true = Parameters()
+ p_true.add('amp', value=14.0)
+ p_true.add('period', value=5.4321)
+ p_true.add('shift', value=0.12345)
+ p_true.add('decay', value=0.01000)
+
+ def residual(pars, x, data=None):
+ amp = pars['amp']
+ per = pars['period']
+ shift = pars['shift']
+ decay = pars['decay']
+
+ if abs(shift) > pi/2:
+ shift = shift - sign(shift)*pi
+
+ model = amp*sin(shift + x/per) * exp(-x*x*decay*decay)
+ if data is None:
+ return model
+ return (model - data)
+
+ n = 1500
+ xmin = 0.
+ xmax = 250.0
+ random.seed(0)
+ noise = random.normal(scale=2.80, size=n)
+ x = linspace(xmin, xmax, n)
+ data = residual(p_true, x) + noise
+
+ fit_params = Parameters()
+ fit_params.add('amp', value=13.0, max=20, min=0.0)
+ fit_params.add('period', value=2, max=10)
+ fit_params.add('shift', value=0.0, max=pi/2., min=-pi/2.)
+ fit_params.add('decay', value=0.02, max=0.10, min=0.00)
+
+ min = Minimizer(residual, fit_params, (x, data))
+ out = min.least_squares()
+
+ assert(out.nfev > 10)
+ assert(out.nfree > 50)
+ assert(out.chisqr > 1.0)
+
+ print(fit_report(out, show_correl=True, modelpars=p_true))
+ assert_paramval(out.params['decay'], 0.01, tol=1.e-2)
+ assert_paramval(out.params['shift'], 0.123, tol=1.e-2)
+
+if __name__ == '__main__':
+ test_bounds()
diff --git a/tests/test_model.py b/tests/test_model.py
index 9cede12..e176139 100644
--- a/tests/test_model.py
+++ b/tests/test_model.py
@@ -1,7 +1,7 @@
import unittest
import warnings
import nose
-from numpy.testing import assert_allclose
+from numpy.testing import assert_allclose, assert_raises
from numpy.testing.decorators import knownfailureif
import numpy as np
@@ -57,12 +57,12 @@ class CommonTests(object):
assert_results_close(result.values, self.true_values())
# Pass inidividual Parameter objects as kwargs.
- kwargs = {name: p for name, p in params.items()}
+ kwargs = dict((name, p) for name, p in params.items())
result = self.model.fit(self.data, x=self.x, **kwargs)
assert_results_close(result.values, self.true_values())
# Pass guess values (not Parameter objects) as kwargs.
- kwargs = {name: p.value for name, p in params.items()}
+ kwargs = dict((name, p.value) for name, p in params.items())
result = self.model.fit(self.data, x=self.x, **kwargs)
assert_results_close(result.values, self.true_values())
@@ -119,7 +119,6 @@ class CommonTests(object):
# Check eval() output against init_fit and best_fit.
pars = self.model.make_params(**self.guess())
result = self.model.fit(self.data, pars, x=self.x)
-
assert_allclose(result.eval(x=self.x, **result.values),
result.best_fit)
assert_allclose(result.eval(x=self.x, **result.init_values),
@@ -132,7 +131,8 @@ class CommonTests(object):
# Check that the independent variable is respected.
short_eval = result.eval(x=np.array([0, 1, 2]), **result.values)
- self.assertEqual(len(short_eval), 3)
+ if hasattr(short_eval, '__len__'):
+ self.assertEqual(len(short_eval), 3)
def test_data_alignment(self):
_skip_if_no_pandas()
@@ -218,7 +218,11 @@ class TestUserDefiniedModel(CommonTests, unittest.TestCase):
def test_lists_become_arrays(self):
# smoke test
self.model.fit([1, 2, 3], x=[1, 2, 3], **self.guess())
- self.model.fit([1, 2, None, 3], x=[1, 2, 3, 4], **self.guess())
+ assert_raises(ValueError,
+ self.model.fit,
+ [1, 2, None, 3],
+ x=[1, 2, 3, 4],
+ **self.guess())
def test_missing_param_raises_error(self):
@@ -429,7 +433,7 @@ class TestUserDefiniedModel(CommonTests, unittest.TestCase):
mx = (m1 + m2)
params = mx.make_params()
- param_values = {name: p.value for name, p in params.items()}
+ param_values = dict((name, p.value) for name, p in params.items())
self.assertEqual(param_values['p1_amplitude'], 1)
self.assertEqual(param_values['p2_amplitude'], 2)
@@ -448,7 +452,7 @@ class TestUserDefiniedModel(CommonTests, unittest.TestCase):
m = m1 + m2
- param_values = {name: p.value for name, p in params.items()}
+ param_values = dict((name, p.value) for name, p in params.items())
self.assertTrue(param_values['m1_intercept'] < -0.0)
self.assertEqual(param_values['m2_amplitude'], 1)
@@ -581,5 +585,4 @@ class TestComplexConstant(CommonTests, unittest.TestCase):
self.guess = lambda: dict(re=2,im=2)
self.model_constructor = models.ComplexConstantModel
super(TestComplexConstant, self).setUp()
-
#
diff --git a/tests/test_multidatasets.py b/tests/test_multidatasets.py
index 985a70c..5d99140 100644
--- a/tests/test_multidatasets.py
+++ b/tests/test_multidatasets.py
@@ -8,9 +8,9 @@ from lmfit.lineshapes import gaussian
def gauss_dataset(params, i, x):
"""calc gaussian from params for data set i
using simple, hardwired naming convention"""
- amp = params['amp_%i' % (i+1)].value
- cen = params['cen_%i' % (i+1)].value
- sig = params['sig_%i' % (i+1)].value
+ amp = params['amp_%i' % (i+1)]
+ cen = params['cen_%i' % (i+1)]
+ sig = params['sig_%i' % (i+1)]
return gaussian(x, amp, cen, sig)
def objective(params, x, data):
diff --git a/tests/test_nose.py b/tests/test_nose.py
index b5ad44a..9e4f4dd 100644
--- a/tests/test_nose.py
+++ b/tests/test_nose.py
@@ -2,12 +2,12 @@
from __future__ import print_function
from lmfit import minimize, Parameters, Parameter, report_fit, Minimizer
from lmfit.minimizer import (SCALAR_METHODS, HAS_EMCEE,
- MinimizerResult, _lnpost)
+ MinimizerResult, _lnpost, _nan_policy)
from lmfit.lineshapes import gaussian
import numpy as np
from numpy import pi
from numpy.testing import (assert_, decorators, assert_raises,
- assert_almost_equal)
+ assert_almost_equal, assert_equal)
import unittest
import nose
from nose import SkipTest
@@ -37,10 +37,10 @@ def test_simple():
# define objective function: returns the array to be minimized
def fcn2min(params, x, data):
""" model decaying sine wave, subtract data"""
- amp = params['amp'].value
- shift = params['shift'].value
- omega = params['omega'].value
- decay = params['decay'].value
+ amp = params['amp']
+ shift = params['shift']
+ omega = params['omega']
+ decay = params['decay']
model = amp * np.sin(x * omega + shift) * np.exp(-x*x*decay)
return model - data
@@ -77,10 +77,10 @@ def test_lbfgsb():
p_true.add('decay', value=0.010)
def residual(pars, x, data=None):
- amp = pars['amp'].value
- per = pars['period'].value
- shift = pars['shift'].value
- decay = pars['decay'].value
+ amp = pars['amp']
+ per = pars['period']
+ shift = pars['shift']
+ decay = pars['decay']
if abs(shift) > pi/2:
shift = shift - np.sign(shift) * pi
@@ -117,21 +117,14 @@ def test_lbfgsb():
def test_derive():
def func(pars, x, data=None):
- a = pars['a'].value
- b = pars['b'].value
- c = pars['c'].value
-
- model=a * np.exp(-b * x)+c
+ model= pars['a'] * np.exp(-pars['b'] * x) + pars['c']
if data is None:
return model
return model - data
def dfunc(pars, x, data=None):
- a = pars['a'].value
- b = pars['b'].value
- c = pars['c'].value
- v = np.exp(-b*x)
- return np.array([v, -a*x*v, np.ones(len(x))])
+ v = np.exp(-pars['b']*x)
+ return np.array([v, -pars['a']*x*v, np.ones(len(x))])
def f(var, x):
return var[0]* np.exp(-var[1] * x)+var[2]
@@ -187,8 +180,8 @@ def test_derive():
def test_peakfit():
def residual(pars, x, data=None):
- g1 = gaussian(x, pars['a1'].value, pars['c1'].value, pars['w1'].value)
- g2 = gaussian(x, pars['a2'].value, pars['c2'].value, pars['w2'].value)
+ g1 = gaussian(x, pars['a1'], pars['c1'], pars['w1'])
+ g2 = gaussian(x, pars['a2'], pars['c2'], pars['w2'])
model = g1 + g2
if data is None:
return model
@@ -256,10 +249,10 @@ def test_scalar_minimize_has_no_uncertainties():
# define objective function: returns the array to be minimized
def fcn2min(params, x, data):
""" model decaying sine wave, subtract data"""
- amp = params['amp'].value
- shift = params['shift'].value
- omega = params['omega'].value
- decay = params['decay'].value
+ amp = params['amp']
+ shift = params['shift']
+ omega = params['omega']
+ decay = params['decay']
model = amp * np.sin(x * omega + shift) * np.exp(-x*x*decay)
return model - data
@@ -301,9 +294,7 @@ def test_multidimensional_fit_GH205():
def fcn2min(params, xv, yv, data):
""" model decaying sine wave, subtract data"""
- lambda1 = params['lambda1'].value
- lambda2 = params['lambda2'].value
- model = f(xv, yv, lambda1, lambda2)
+ model = f(xv, yv, params['lambda1'], params['lambda2'])
return model - data
# create a set of Parameters
@@ -345,10 +336,10 @@ class CommonMinimizerTest(unittest.TestCase):
self.mini = Minimizer(self.residual, fit_params, [self.x, self.data])
def residual(self, pars, x, data=None):
- amp = pars['amp'].value
- per = pars['period'].value
- shift = pars['shift'].value
- decay = pars['decay'].value
+ amp = pars['amp']
+ per = pars['period']
+ shift = pars['shift']
+ decay = pars['decay']
if abs(shift) > pi/2:
shift = shift - np.sign(shift) * pi
@@ -361,9 +352,14 @@ class CommonMinimizerTest(unittest.TestCase):
# You need finite (min, max) for each parameter if you're using
# differential_evolution.
self.fit_params['decay'].min = -np.inf
+ self.fit_params['decay'].vary = True
self.minimizer = 'differential_evolution'
np.testing.assert_raises(ValueError, self.scalar_minimizer)
+ # but only if a parameter is not fixed
+ self.fit_params['decay'].vary = False
+ self.mini.scalar_minimize(method='differential_evolution', maxiter=1)
+
def test_scalar_minimizers(self):
# test all the scalar minimizers
for method in SCALAR_METHODS:
@@ -395,6 +391,39 @@ class CommonMinimizerTest(unittest.TestCase):
self.p_true.values()):
check_wo_stderr(para, true_para.value, sig=sig)
+ def test_nan_policy(self):
+ # check that an error is raised if there are nan in
+ # the data returned by userfcn
+ self.data[0] = np.nan
+
+ for method in SCALAR_METHODS:
+ assert_raises(ValueError,
+ self.mini.scalar_minimize,
+ SCALAR_METHODS[method])
+
+ assert_raises(ValueError, self.mini.minimize)
+
+ # now check that the fit proceeds if nan_policy is 'omit'
+ self.mini.nan_policy = 'omit'
+ res = self.mini.minimize()
+ assert_equal(res.ndata, np.size(self.data, 0) - 1)
+
+ for para, true_para in zip(res.params.values(),
+ self.p_true.values()):
+ check_wo_stderr(para, true_para.value, sig=0.15)
+
+ def test_nan_policy_function(self):
+ a = np.array([0, 1, 2, 3, np.nan])
+ assert_raises(ValueError, _nan_policy, a)
+ assert_(np.isnan(_nan_policy(a, nan_policy='propagate')[-1]))
+ assert_equal(_nan_policy(a, nan_policy='omit'), [0, 1, 2, 3])
+
+ a[-1] = np.inf
+ assert_raises(ValueError, _nan_policy, a)
+ assert_(np.isposinf(_nan_policy(a, nan_policy='propagate')[-1]))
+ assert_equal(_nan_policy(a, nan_policy='omit'), [0, 1, 2, 3])
+ assert_equal(_nan_policy(a, handle_inf=False), a)
+
@decorators.slow
def test_emcee(self):
# test emcee
@@ -591,10 +620,10 @@ class CommonMinimizerTest(unittest.TestCase):
def residual_for_multiprocessing(pars, x, data=None):
# a residual function defined in the top level is needed for
# multiprocessing. bound methods don't work.
- amp = pars['amp'].value
- per = pars['period'].value
- shift = pars['shift'].value
- decay = pars['decay'].value
+ amp = pars['amp']
+ per = pars['period']
+ shift = pars['shift']
+ decay = pars['decay']
if abs(shift) > pi/2:
shift = shift - np.sign(shift) * pi
diff --git a/tests/test_params_set.py b/tests/test_params_set.py
index 24b1089..ebf7ff9 100644
--- a/tests/test_params_set.py
+++ b/tests/test_params_set.py
@@ -45,4 +45,4 @@ def test_param_set():
assert(params['gamma'].vary)
assert_allclose(params['gamma'].value, gamval, 1e-4, 1e-4, '', True)
-test_param_set() \ No newline at end of file
+test_param_set()