195 lines
4.4 KiB
Python
195 lines
4.4 KiB
Python
from statsmodels.compat.scipy import SP_LT_15, SP_LT_17
|
|
import pytest
|
|
from numpy.testing import assert_
|
|
from numpy.testing import assert_almost_equal
|
|
|
|
from statsmodels.base.optimizer import (
|
|
_fit_newton,
|
|
_fit_nm,
|
|
_fit_bfgs,
|
|
_fit_cg,
|
|
_fit_ncg,
|
|
_fit_powell,
|
|
_fit_lbfgs,
|
|
_fit_basinhopping,
|
|
_fit_minimize,
|
|
)
|
|
|
|
fit_funcs = {
|
|
"newton": _fit_newton,
|
|
"nm": _fit_nm, # Nelder-Mead
|
|
"bfgs": _fit_bfgs,
|
|
"cg": _fit_cg,
|
|
"ncg": _fit_ncg,
|
|
"powell": _fit_powell,
|
|
"lbfgs": _fit_lbfgs,
|
|
"basinhopping": _fit_basinhopping,
|
|
"minimize": _fit_minimize,
|
|
}
|
|
|
|
|
|
def dummy_func(x):
|
|
return x ** 2
|
|
|
|
|
|
def dummy_score(x):
|
|
return 2.0 * x
|
|
|
|
|
|
def dummy_hess(x):
|
|
return [[2.0]]
|
|
|
|
|
|
def dummy_bounds_constraint_func(x):
|
|
return (x[0] - 1) ** 2 + (x[1] - 2.5) ** 2
|
|
|
|
|
|
def dummy_bounds():
|
|
return ((0, None), (0, None))
|
|
|
|
|
|
def dummy_bounds_tight():
|
|
return ((2, None), (3.5, None))
|
|
|
|
|
|
def dummy_constraints():
|
|
cons = (
|
|
{"type": "ineq", "fun": lambda x: x[0] - 2 * x[1] + 2},
|
|
{"type": "ineq", "fun": lambda x: -x[0] - 2 * x[1] + 6},
|
|
{"type": "ineq", "fun": lambda x: -x[0] + 2 * x[1] + 2},
|
|
)
|
|
return cons
|
|
|
|
|
|
@pytest.mark.smoke
|
|
def test_full_output_false(reset_randomstate):
|
|
# newton needs f, score, start, fargs, kwargs
|
|
# bfgs needs f, score start, fargs, kwargs
|
|
# nm needs ""
|
|
# cg ""
|
|
# ncg ""
|
|
# powell ""
|
|
for method in fit_funcs:
|
|
func = fit_funcs[method]
|
|
if method == "newton":
|
|
xopt, retvals = func(
|
|
dummy_func,
|
|
dummy_score,
|
|
[1.0],
|
|
(),
|
|
{},
|
|
hess=dummy_hess,
|
|
full_output=False,
|
|
disp=0,
|
|
)
|
|
|
|
else:
|
|
xopt, retvals = func(
|
|
dummy_func,
|
|
dummy_score,
|
|
[1.0],
|
|
(),
|
|
{},
|
|
full_output=False,
|
|
disp=0
|
|
)
|
|
assert_(retvals is None)
|
|
if method == "powell" and SP_LT_15:
|
|
# Fixed in SP 1.5
|
|
assert_(xopt.shape == () and xopt.size == 1)
|
|
else:
|
|
assert_(len(xopt) == 1)
|
|
|
|
|
|
def test_full_output(reset_randomstate):
|
|
for method in fit_funcs:
|
|
func = fit_funcs[method]
|
|
if method == "newton":
|
|
xopt, retvals = func(
|
|
dummy_func,
|
|
dummy_score,
|
|
[1.0],
|
|
(),
|
|
{},
|
|
hess=dummy_hess,
|
|
full_output=True,
|
|
disp=0,
|
|
)
|
|
|
|
else:
|
|
xopt, retvals = func(
|
|
dummy_func,
|
|
dummy_score,
|
|
[1.0],
|
|
(),
|
|
{},
|
|
full_output=True,
|
|
disp=0
|
|
)
|
|
|
|
assert_(retvals is not None)
|
|
assert_("converged" in retvals)
|
|
|
|
if method == "powell" and SP_LT_15:
|
|
# Fixed in SP 1.5
|
|
assert_(xopt.shape == () and xopt.size == 1)
|
|
else:
|
|
assert_(len(xopt) == 1)
|
|
|
|
|
|
def test_minimize_scipy_slsqp():
|
|
func = fit_funcs["minimize"]
|
|
xopt, _ = func(
|
|
dummy_bounds_constraint_func,
|
|
None,
|
|
(2.0, 0.0),
|
|
(),
|
|
{
|
|
"min_method": "SLSQP",
|
|
"bounds": dummy_bounds(),
|
|
"constraints": dummy_constraints(),
|
|
},
|
|
hess=None,
|
|
full_output=False,
|
|
disp=0,
|
|
)
|
|
assert_almost_equal(xopt, [1.4, 1.7], 4)
|
|
|
|
|
|
@pytest.mark.skipif(SP_LT_15, reason="Powell bounds support added in SP 1.5")
|
|
def test_minimize_scipy_powell():
|
|
func = fit_funcs["minimize"]
|
|
xopt, _ = func(
|
|
dummy_bounds_constraint_func,
|
|
None,
|
|
(3, 4.5),
|
|
(),
|
|
{
|
|
"min_method": "Powell",
|
|
"bounds": dummy_bounds_tight(),
|
|
},
|
|
hess=None,
|
|
full_output=False,
|
|
disp=0,
|
|
)
|
|
assert_almost_equal(xopt, [2, 3.5], 4)
|
|
|
|
|
|
@pytest.mark.skipif(SP_LT_17, reason="NM bounds support added in SP 1.7")
|
|
def test_minimize_scipy_nm():
|
|
func = fit_funcs["minimize"]
|
|
xopt, _ = func(
|
|
dummy_bounds_constraint_func,
|
|
None,
|
|
(3, 4.5),
|
|
(),
|
|
{
|
|
"min_method": "Nelder-Mead",
|
|
"bounds": dummy_bounds_tight(),
|
|
},
|
|
hess=None,
|
|
full_output=False,
|
|
disp=0,
|
|
)
|
|
assert_almost_equal(xopt, [2, 3.5], 4)
|