|
2 | 2 | import pytest
|
3 | 3 | from scipy.linalg import block_diag
|
4 | 4 | from scipy.sparse import csc_matrix
|
5 |
| -from numpy.testing import (TestCase, assert_array_almost_equal, |
| 5 | +from numpy.testing import (assert_array_almost_equal, |
6 | 6 | assert_array_less, assert_, assert_allclose,
|
7 | 7 | suppress_warnings)
|
8 | 8 | from scipy.optimize import (NonlinearConstraint,
|
@@ -443,67 +443,70 @@ def hess(x, v):
|
443 | 443 | return NonlinearConstraint(fun, -np.inf, 0, jac, hess)
|
444 | 444 |
|
445 | 445 |
|
446 |
| -class TestTrustRegionConstr(TestCase): |
447 |
| - |
448 |
| - @pytest.mark.slow |
449 |
| - def test_list_of_problems(self): |
450 |
| - list_of_problems = [Maratos(), |
451 |
| - Maratos(constr_hess='2-point'), |
452 |
| - Maratos(constr_hess=SR1()), |
453 |
| - Maratos(constr_jac='2-point', constr_hess=SR1()), |
454 |
| - MaratosGradInFunc(), |
455 |
| - HyperbolicIneq(), |
456 |
| - HyperbolicIneq(constr_hess='3-point'), |
457 |
| - HyperbolicIneq(constr_hess=BFGS()), |
458 |
| - HyperbolicIneq(constr_jac='3-point', |
459 |
| - constr_hess=BFGS()), |
460 |
| - Rosenbrock(), |
461 |
| - IneqRosenbrock(), |
462 |
| - EqIneqRosenbrock(), |
463 |
| - BoundedRosenbrock(), |
464 |
| - Elec(n_electrons=2), |
465 |
| - Elec(n_electrons=2, constr_hess='2-point'), |
466 |
| - Elec(n_electrons=2, constr_hess=SR1()), |
467 |
| - Elec(n_electrons=2, constr_jac='3-point', |
468 |
| - constr_hess=SR1())] |
469 |
| - |
470 |
| - for prob in list_of_problems: |
471 |
| - for grad in (prob.grad, '3-point', False): |
472 |
| - for hess in (prob.hess, |
473 |
| - '3-point', |
474 |
| - SR1(), |
475 |
| - BFGS(exception_strategy='damp_update'), |
476 |
| - BFGS(exception_strategy='skip_update')): |
477 |
| - |
478 |
| - # Remove exceptions |
479 |
| - if grad in ('2-point', '3-point', 'cs', False) and \ |
480 |
| - hess in ('2-point', '3-point', 'cs'): |
481 |
| - continue |
482 |
| - if prob.grad is True and grad in ('3-point', False): |
483 |
| - continue |
484 |
| - with suppress_warnings() as sup: |
485 |
| - sup.filter(UserWarning, "delta_grad == 0.0") |
486 |
| - result = minimize(prob.fun, prob.x0, |
487 |
| - method='trust-constr', |
488 |
| - jac=grad, hess=hess, |
489 |
| - bounds=prob.bounds, |
490 |
| - constraints=prob.constr) |
491 |
| - |
492 |
| - if prob.x_opt is not None: |
493 |
| - assert_array_almost_equal(result.x, prob.x_opt, |
494 |
| - decimal=5) |
495 |
| - # gtol |
496 |
| - if result.status == 1: |
497 |
| - assert_array_less(result.optimality, 1e-8) |
498 |
| - # xtol |
499 |
| - if result.status == 2: |
500 |
| - assert_array_less(result.tr_radius, 1e-8) |
501 |
| - |
502 |
| - if result.method == "tr_interior_point": |
503 |
| - assert_array_less(result.barrier_parameter, 1e-8) |
504 |
| - # max iter |
505 |
| - if result.status in (0, 3): |
506 |
| - raise RuntimeError("Invalid termination condition.") |
| 446 | +class TestTrustRegionConstr: |
| 447 | + list_of_problems = [Maratos(), |
| 448 | + Maratos(constr_hess='2-point'), |
| 449 | + Maratos(constr_hess=SR1()), |
| 450 | + Maratos(constr_jac='2-point', constr_hess=SR1()), |
| 451 | + MaratosGradInFunc(), |
| 452 | + HyperbolicIneq(), |
| 453 | + HyperbolicIneq(constr_hess='3-point'), |
| 454 | + HyperbolicIneq(constr_hess=BFGS()), |
| 455 | + HyperbolicIneq(constr_jac='3-point', |
| 456 | + constr_hess=BFGS()), |
| 457 | + Rosenbrock(), |
| 458 | + IneqRosenbrock(), |
| 459 | + EqIneqRosenbrock(), |
| 460 | + BoundedRosenbrock(), |
| 461 | + Elec(n_electrons=2), |
| 462 | + Elec(n_electrons=2, constr_hess='2-point'), |
| 463 | + Elec(n_electrons=2, constr_hess=SR1()), |
| 464 | + Elec(n_electrons=2, constr_jac='3-point', |
| 465 | + constr_hess=SR1())] |
| 466 | + |
| 467 | + @pytest.mark.parametrize('prob', list_of_problems) |
| 468 | + @pytest.mark.parametrize('grad', ('prob.grad', '3-point', False)) |
| 469 | + @pytest.mark.parametrize('hess', ("prob.hess", '3-point', SR1(), |
| 470 | + BFGS(exception_strategy='damp_update'), |
| 471 | + BFGS(exception_strategy='skip_update'))) |
| 472 | + def test_list_of_problems(self, prob, grad, hess): |
| 473 | + grad = prob.grad if grad == "prob.grad" else grad |
| 474 | + hess = prob.hess if hess == "prob.hess" else hess |
| 475 | + # Remove exceptions |
| 476 | + if (grad in {'2-point', '3-point', 'cs', False} and |
| 477 | + hess in {'2-point', '3-point', 'cs'}): |
| 478 | + pytest.skip("Numerical Hessian needs analytical gradient") |
| 479 | + if prob.grad is True and grad in {'3-point', False}: |
| 480 | + pytest.skip("prob.grad incompatible with grad in {'3-point', False}") |
| 481 | + sensitive = (isinstance(prob, BoundedRosenbrock) and grad == '3-point' |
| 482 | + and isinstance(hess, BFGS)) |
| 483 | + if sensitive: |
| 484 | + pytest.xfail("Seems sensitive to initial conditions w/ Accelerate") |
| 485 | + with suppress_warnings() as sup: |
| 486 | + sup.filter(UserWarning, "delta_grad == 0.0") |
| 487 | + result = minimize(prob.fun, prob.x0, |
| 488 | + method='trust-constr', |
| 489 | + jac=grad, hess=hess, |
| 490 | + bounds=prob.bounds, |
| 491 | + constraints=prob.constr) |
| 492 | + |
| 493 | + if prob.x_opt is not None: |
| 494 | + assert_array_almost_equal(result.x, prob.x_opt, |
| 495 | + decimal=5) |
| 496 | + # gtol |
| 497 | + if result.status == 1: |
| 498 | + assert_array_less(result.optimality, 1e-8) |
| 499 | + # xtol |
| 500 | + if result.status == 2: |
| 501 | + assert_array_less(result.tr_radius, 1e-8) |
| 502 | + |
| 503 | + if result.method == "tr_interior_point": |
| 504 | + assert_array_less(result.barrier_parameter, 1e-8) |
| 505 | + |
| 506 | + # check for max iter |
| 507 | + message = f"Invalid termination condition: {result.status}." |
| 508 | + assert result.status not in {0, 3}, message |
| 509 | + |
507 | 510 |
|
508 | 511 | def test_default_jac_and_hess(self):
|
509 | 512 | def fun(x):
|
@@ -641,7 +644,7 @@ def obj(x):
|
641 | 644 |
|
642 | 645 | assert result['success']
|
643 | 646 |
|
644 |
| -class TestEmptyConstraint(TestCase): |
| 647 | +class TestEmptyConstraint: |
645 | 648 | """
|
646 | 649 | Here we minimize x^2+y^2 subject to x^2-y^2>1.
|
647 | 650 | The actual minimum is at (0, 0) which fails the constraint.
|
|
0 commit comments