Skip to content

Commit 1a61d9d

Browse files
committed
Add backend fixture to test_miscellaneous
1 parent afc37a3 commit 1a61d9d

2 files changed

Lines changed: 97 additions & 79 deletions

File tree

python/tests/pyprima/test_miscellaneous.py

Lines changed: 0 additions & 79 deletions
This file was deleted.

python/tests/test_miscellaneous.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
from prima import minimize, NonlinearConstraint
2+
from prima.backends.pyprima.common.infos import CALLBACK_TERMINATE, SMALL_TR_RADIUS
3+
from prima.backends.pybindings import __cmake_build_type__
4+
import numpy as np
5+
import pytest
6+
import platform
7+
8+
def obj(x):
9+
return (x[0] - 1)**2 + (x[1] - 2.5)**2
10+
obj.x0 = np.array([5, 5])
11+
obj.optimal = np.array([1, 2.5])
12+
13+
14+
def test_callback_terminate(pyprima_turn_on_debugging, backend_fixture):
15+
def callback(x, *args):
16+
return True
17+
result = minimize(obj, obj.x0, method='cobyla', callback=callback, options={'backend': backend_fixture})
18+
assert result.nfev == 3
19+
assert result.status == CALLBACK_TERMINATE
20+
21+
22+
def test_callback_no_terminate(backend_fixture):
23+
def callback(x, *args):
24+
pass
25+
result = minimize(obj, obj.x0, method='cobyla', callback=callback, options={'backend': backend_fixture})
26+
# Different platforms finish with different nfev due to different optimizations
27+
assert result.nfev == (56 if (
28+
(platform.machine().lower() in ["x86_64", "amd64", "i386"]) or
29+
(__cmake_build_type__ == "Debug") or (backend_fixture == 'Python')
30+
) else 54)
31+
assert np.allclose(result.x, obj.optimal, atol=1e-3)
32+
assert result.status == SMALL_TR_RADIUS
33+
34+
35+
def test_rhoend_without_rhobeg(backend_fixture):
36+
result = minimize(obj, obj.x0, method='cobyla', options={'rhoend': 4e-4, 'backend': backend_fixture})
37+
assert np.allclose(result.x, obj.optimal, atol=1e-3)
38+
39+
40+
def test_rhobeg_without_rhoend(backend_fixture):
41+
# Needs to be negative to trigger the right section of code.
42+
if backend_fixture == "Python":
43+
with pytest.warns(UserWarning, match="COBYLA: Invalid RHOBEG; it should be a positive number; it is set to 1"):
44+
result = minimize(obj, obj.x0, method='cobyla', options={'rhobeg': -1, 'backend': backend_fixture})
45+
else:
46+
# The Fortran emits warnings to stdout as opposed to a Python warning
47+
result = minimize(obj, obj.x0, method='cobyla', options={'rhobeg': -1, 'backend': backend_fixture})
48+
assert np.allclose(result.x, obj.optimal, atol=1e-3)
49+
50+
51+
def test_eta2_without_eta1(backend_fixture):
52+
result = minimize(obj, obj.x0, method='cobyla', options={'eta2': 0.7, 'backemd': backend_fixture})
53+
assert np.allclose(result.x, obj.optimal, atol=1e-3)
54+
55+
56+
def test_eta2_without_eta1_and_eta2_out_of_range(backend_fixture):
57+
if backend_fixture == 'Python':
58+
with pytest.warns(UserWarning, match=r"COBYLA: Invalid ETA2; it should be in the interval \[0, 1\) and not less than ETA1; it is set to 0.7000000000000001"):
59+
result = minimize(obj, obj.x0, method='cobyla', options={'eta2': 1.7, 'backend': backend_fixture})
60+
else:
61+
result = minimize(obj, obj.x0, method='cobyla', options={'eta2': 1.7, 'backend': backend_fixture})
62+
assert np.allclose(result.x, obj.optimal, atol=1e-3)
63+
64+
65+
def test_eta1_without_eta2_and_eta1_out_of_range(backend_fixture):
66+
if backend_fixture == 'Python':
67+
with pytest.warns(UserWarning, match=r"COBYLA: Invalid ETA1; it should be in the interval \[0, 1\) and not more than ETA2; it is set to 0.09999999999999999"):
68+
with pytest.warns(UserWarning, match=r"COBYLA: Invalid ETA2; it should be in the interval \[0, 1\) and not less than ETA1; it is set to 0.7000000000000001"):
69+
result = minimize(obj, obj.x0, method='cobyla', options={'eta1': 1.7, 'backend': backend_fixture})
70+
else:
71+
result = minimize(obj, obj.x0, method='cobyla', options={'eta1': 1.7, 'backend': backend_fixture})
72+
assert np.allclose(result.x, obj.optimal, atol=1e-3)
73+
74+
@pytest.mark.parametrize('iprint', [-1, 0, 1, 2, 3, 4])
75+
def test_iprint(iprint, backend_fixture):
76+
if backend_fixture == 'Python' and iprint == 4:
77+
with pytest.warns(UserWarning, match=r"COBYLA: Invalid IPRINT; it should be 0, 1, -1, 2, -2, 3, or -3; it is set to 0"):
78+
result = minimize(obj, obj.x0, method='cobyla', options={'iprint': iprint, 'backend': backend_fixture})
79+
else:
80+
result = minimize(obj, obj.x0, method='cobyla', options={'iprint': iprint, 'backend': backend_fixture})
81+
assert np.allclose(result.x, obj.optimal, atol=1e-3)
82+
83+
84+
def test_minimize_constraint_violation(backend_fixture):
85+
# We set up conflicting constraints so that the algorithm will be
86+
# guaranteed to end up with maxcv > 0.
87+
cons = [NonlinearConstraint(lambda x: x - 4, -np.inf, 0),
88+
NonlinearConstraint(lambda x: 5 - x, -np.inf, 0)]
89+
result = minimize(lambda x: x[0], np.array([0]), method='cobyla', constraints=cons,
90+
options={'backend': backend_fixture})
91+
assert result.maxcv > 0.1
92+
assert result.status == SMALL_TR_RADIUS
93+
94+
95+
def test_scalar():
96+
result = minimize(lambda x: x**2, 5, method='cobyla')
97+
assert np.allclose(result.x, 0, atol=1e-3)

0 commit comments

Comments
 (0)