Fixed database typo and removed unnecessary class identifier.
This commit is contained in:
parent
00ad49a143
commit
45fb349a7d
5098 changed files with 952558 additions and 85 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,296 @@
|
|||
import numpy as np
|
||||
from numpy.testing import assert_array_equal, assert_equal
|
||||
from scipy.optimize._constraints import (NonlinearConstraint, Bounds,
|
||||
PreparedConstraint)
|
||||
from scipy.optimize._trustregion_constr.canonical_constraint \
|
||||
import CanonicalConstraint, initial_constraints_as_canonical
|
||||
|
||||
|
||||
def create_quadratic_function(n, m, rng):
|
||||
a = rng.rand(m)
|
||||
A = rng.rand(m, n)
|
||||
H = rng.rand(m, n, n)
|
||||
HT = np.transpose(H, (1, 2, 0))
|
||||
|
||||
def fun(x):
|
||||
return a + A.dot(x) + 0.5 * H.dot(x).dot(x)
|
||||
|
||||
def jac(x):
|
||||
return A + H.dot(x)
|
||||
|
||||
def hess(x, v):
|
||||
return HT.dot(v)
|
||||
|
||||
return fun, jac, hess
|
||||
|
||||
|
||||
def test_bounds_cases():
|
||||
# Test 1: no constraints.
|
||||
user_constraint = Bounds(-np.inf, np.inf)
|
||||
x0 = np.array([-1, 2])
|
||||
prepared_constraint = PreparedConstraint(user_constraint, x0, False)
|
||||
c = CanonicalConstraint.from_PreparedConstraint(prepared_constraint)
|
||||
|
||||
assert_equal(c.n_eq, 0)
|
||||
assert_equal(c.n_ineq, 0)
|
||||
|
||||
c_eq, c_ineq = c.fun(x0)
|
||||
assert_array_equal(c_eq, [])
|
||||
assert_array_equal(c_ineq, [])
|
||||
|
||||
J_eq, J_ineq = c.jac(x0)
|
||||
assert_array_equal(J_eq, np.empty((0, 2)))
|
||||
assert_array_equal(J_ineq, np.empty((0, 2)))
|
||||
|
||||
assert_array_equal(c.keep_feasible, [])
|
||||
|
||||
# Test 2: infinite lower bound.
|
||||
user_constraint = Bounds(-np.inf, [0, np.inf, 1], [False, True, True])
|
||||
x0 = np.array([-1, -2, -3], dtype=float)
|
||||
prepared_constraint = PreparedConstraint(user_constraint, x0, False)
|
||||
c = CanonicalConstraint.from_PreparedConstraint(prepared_constraint)
|
||||
|
||||
assert_equal(c.n_eq, 0)
|
||||
assert_equal(c.n_ineq, 2)
|
||||
|
||||
c_eq, c_ineq = c.fun(x0)
|
||||
assert_array_equal(c_eq, [])
|
||||
assert_array_equal(c_ineq, [-1, -4])
|
||||
|
||||
J_eq, J_ineq = c.jac(x0)
|
||||
assert_array_equal(J_eq, np.empty((0, 3)))
|
||||
assert_array_equal(J_ineq, np.array([[1, 0, 0], [0, 0, 1]]))
|
||||
|
||||
assert_array_equal(c.keep_feasible, [False, True])
|
||||
|
||||
# Test 3: infinite upper bound.
|
||||
user_constraint = Bounds([0, 1, -np.inf], np.inf, [True, False, True])
|
||||
x0 = np.array([1, 2, 3], dtype=float)
|
||||
prepared_constraint = PreparedConstraint(user_constraint, x0, False)
|
||||
c = CanonicalConstraint.from_PreparedConstraint(prepared_constraint)
|
||||
|
||||
assert_equal(c.n_eq, 0)
|
||||
assert_equal(c.n_ineq, 2)
|
||||
|
||||
c_eq, c_ineq = c.fun(x0)
|
||||
assert_array_equal(c_eq, [])
|
||||
assert_array_equal(c_ineq, [-1, -1])
|
||||
|
||||
J_eq, J_ineq = c.jac(x0)
|
||||
assert_array_equal(J_eq, np.empty((0, 3)))
|
||||
assert_array_equal(J_ineq, np.array([[-1, 0, 0], [0, -1, 0]]))
|
||||
|
||||
assert_array_equal(c.keep_feasible, [True, False])
|
||||
|
||||
# Test 4: interval constraint.
|
||||
user_constraint = Bounds([-1, -np.inf, 2, 3], [1, np.inf, 10, 3],
|
||||
[False, True, True, True])
|
||||
x0 = np.array([0, 10, 8, 5])
|
||||
prepared_constraint = PreparedConstraint(user_constraint, x0, False)
|
||||
c = CanonicalConstraint.from_PreparedConstraint(prepared_constraint)
|
||||
|
||||
assert_equal(c.n_eq, 1)
|
||||
assert_equal(c.n_ineq, 4)
|
||||
|
||||
c_eq, c_ineq = c.fun(x0)
|
||||
assert_array_equal(c_eq, [2])
|
||||
assert_array_equal(c_ineq, [-1, -2, -1, -6])
|
||||
|
||||
J_eq, J_ineq = c.jac(x0)
|
||||
assert_array_equal(J_eq, [[0, 0, 0, 1]])
|
||||
assert_array_equal(J_ineq, [[1, 0, 0, 0],
|
||||
[0, 0, 1, 0],
|
||||
[-1, 0, 0, 0],
|
||||
[0, 0, -1, 0]])
|
||||
|
||||
assert_array_equal(c.keep_feasible, [False, True, False, True])
|
||||
|
||||
|
||||
def test_nonlinear_constraint():
|
||||
n = 3
|
||||
m = 5
|
||||
rng = np.random.RandomState(0)
|
||||
x0 = rng.rand(n)
|
||||
|
||||
fun, jac, hess = create_quadratic_function(n, m, rng)
|
||||
f = fun(x0)
|
||||
J = jac(x0)
|
||||
|
||||
lb = [-10, 3, -np.inf, -np.inf, -5]
|
||||
ub = [10, 3, np.inf, 3, np.inf]
|
||||
user_constraint = NonlinearConstraint(
|
||||
fun, lb, ub, jac, hess, [True, False, False, True, False])
|
||||
|
||||
for sparse_jacobian in [False, True]:
|
||||
prepared_constraint = PreparedConstraint(user_constraint, x0,
|
||||
sparse_jacobian)
|
||||
c = CanonicalConstraint.from_PreparedConstraint(prepared_constraint)
|
||||
|
||||
assert_array_equal(c.n_eq, 1)
|
||||
assert_array_equal(c.n_ineq, 4)
|
||||
|
||||
c_eq, c_ineq = c.fun(x0)
|
||||
assert_array_equal(c_eq, [f[1] - lb[1]])
|
||||
assert_array_equal(c_ineq, [f[3] - ub[3], lb[4] - f[4],
|
||||
f[0] - ub[0], lb[0] - f[0]])
|
||||
|
||||
J_eq, J_ineq = c.jac(x0)
|
||||
if sparse_jacobian:
|
||||
J_eq = J_eq.toarray()
|
||||
J_ineq = J_ineq.toarray()
|
||||
|
||||
assert_array_equal(J_eq, J[1, None])
|
||||
assert_array_equal(J_ineq, np.vstack((J[3], -J[4], J[0], -J[0])))
|
||||
|
||||
v_eq = rng.rand(c.n_eq)
|
||||
v_ineq = rng.rand(c.n_ineq)
|
||||
v = np.zeros(m)
|
||||
v[1] = v_eq[0]
|
||||
v[3] = v_ineq[0]
|
||||
v[4] = -v_ineq[1]
|
||||
v[0] = v_ineq[2] - v_ineq[3]
|
||||
assert_array_equal(c.hess(x0, v_eq, v_ineq), hess(x0, v))
|
||||
|
||||
assert_array_equal(c.keep_feasible, [True, False, True, True])
|
||||
|
||||
|
||||
def test_concatenation():
|
||||
rng = np.random.RandomState(0)
|
||||
n = 4
|
||||
x0 = rng.rand(n)
|
||||
|
||||
f1 = x0
|
||||
J1 = np.eye(n)
|
||||
lb1 = [-1, -np.inf, -2, 3]
|
||||
ub1 = [1, np.inf, np.inf, 3]
|
||||
bounds = Bounds(lb1, ub1, [False, False, True, False])
|
||||
|
||||
fun, jac, hess = create_quadratic_function(n, 5, rng)
|
||||
f2 = fun(x0)
|
||||
J2 = jac(x0)
|
||||
lb2 = [-10, 3, -np.inf, -np.inf, -5]
|
||||
ub2 = [10, 3, np.inf, 5, np.inf]
|
||||
nonlinear = NonlinearConstraint(
|
||||
fun, lb2, ub2, jac, hess, [True, False, False, True, False])
|
||||
|
||||
for sparse_jacobian in [False, True]:
|
||||
bounds_prepared = PreparedConstraint(bounds, x0, sparse_jacobian)
|
||||
nonlinear_prepared = PreparedConstraint(nonlinear, x0, sparse_jacobian)
|
||||
|
||||
c1 = CanonicalConstraint.from_PreparedConstraint(bounds_prepared)
|
||||
c2 = CanonicalConstraint.from_PreparedConstraint(nonlinear_prepared)
|
||||
c = CanonicalConstraint.concatenate([c1, c2], sparse_jacobian)
|
||||
|
||||
assert_equal(c.n_eq, 2)
|
||||
assert_equal(c.n_ineq, 7)
|
||||
|
||||
c_eq, c_ineq = c.fun(x0)
|
||||
assert_array_equal(c_eq, [f1[3] - lb1[3], f2[1] - lb2[1]])
|
||||
assert_array_equal(c_ineq, [lb1[2] - f1[2], f1[0] - ub1[0],
|
||||
lb1[0] - f1[0], f2[3] - ub2[3],
|
||||
lb2[4] - f2[4], f2[0] - ub2[0],
|
||||
lb2[0] - f2[0]])
|
||||
|
||||
J_eq, J_ineq = c.jac(x0)
|
||||
if sparse_jacobian:
|
||||
J_eq = J_eq.toarray()
|
||||
J_ineq = J_ineq.toarray()
|
||||
|
||||
assert_array_equal(J_eq, np.vstack((J1[3], J2[1])))
|
||||
assert_array_equal(J_ineq, np.vstack((-J1[2], J1[0], -J1[0], J2[3],
|
||||
-J2[4], J2[0], -J2[0])))
|
||||
|
||||
v_eq = rng.rand(c.n_eq)
|
||||
v_ineq = rng.rand(c.n_ineq)
|
||||
v = np.zeros(5)
|
||||
v[1] = v_eq[1]
|
||||
v[3] = v_ineq[3]
|
||||
v[4] = -v_ineq[4]
|
||||
v[0] = v_ineq[5] - v_ineq[6]
|
||||
H = c.hess(x0, v_eq, v_ineq).dot(np.eye(n))
|
||||
assert_array_equal(H, hess(x0, v))
|
||||
|
||||
assert_array_equal(c.keep_feasible,
|
||||
[True, False, False, True, False, True, True])
|
||||
|
||||
|
||||
def test_empty():
|
||||
x = np.array([1, 2, 3])
|
||||
c = CanonicalConstraint.empty(3)
|
||||
assert_equal(c.n_eq, 0)
|
||||
assert_equal(c.n_ineq, 0)
|
||||
|
||||
c_eq, c_ineq = c.fun(x)
|
||||
assert_array_equal(c_eq, [])
|
||||
assert_array_equal(c_ineq, [])
|
||||
|
||||
J_eq, J_ineq = c.jac(x)
|
||||
assert_array_equal(J_eq, np.empty((0, 3)))
|
||||
assert_array_equal(J_ineq, np.empty((0, 3)))
|
||||
|
||||
H = c.hess(x, None, None).toarray()
|
||||
assert_array_equal(H, np.zeros((3, 3)))
|
||||
|
||||
|
||||
def test_initial_constraints_as_canonical():
|
||||
# rng is only used to generate the coefficients of the quadratic
|
||||
# function that is used by the nonlinear constraint.
|
||||
rng = np.random.RandomState(0)
|
||||
|
||||
x0 = np.array([0.5, 0.4, 0.3, 0.2])
|
||||
n = len(x0)
|
||||
|
||||
lb1 = [-1, -np.inf, -2, 3]
|
||||
ub1 = [1, np.inf, np.inf, 3]
|
||||
bounds = Bounds(lb1, ub1, [False, False, True, False])
|
||||
|
||||
fun, jac, hess = create_quadratic_function(n, 5, rng)
|
||||
lb2 = [-10, 3, -np.inf, -np.inf, -5]
|
||||
ub2 = [10, 3, np.inf, 5, np.inf]
|
||||
nonlinear = NonlinearConstraint(
|
||||
fun, lb2, ub2, jac, hess, [True, False, False, True, False])
|
||||
|
||||
for sparse_jacobian in [False, True]:
|
||||
bounds_prepared = PreparedConstraint(bounds, x0, sparse_jacobian)
|
||||
nonlinear_prepared = PreparedConstraint(nonlinear, x0, sparse_jacobian)
|
||||
|
||||
f1 = bounds_prepared.fun.f
|
||||
J1 = bounds_prepared.fun.J
|
||||
f2 = nonlinear_prepared.fun.f
|
||||
J2 = nonlinear_prepared.fun.J
|
||||
|
||||
c_eq, c_ineq, J_eq, J_ineq = initial_constraints_as_canonical(
|
||||
n, [bounds_prepared, nonlinear_prepared], sparse_jacobian)
|
||||
|
||||
assert_array_equal(c_eq, [f1[3] - lb1[3], f2[1] - lb2[1]])
|
||||
assert_array_equal(c_ineq, [lb1[2] - f1[2], f1[0] - ub1[0],
|
||||
lb1[0] - f1[0], f2[3] - ub2[3],
|
||||
lb2[4] - f2[4], f2[0] - ub2[0],
|
||||
lb2[0] - f2[0]])
|
||||
|
||||
if sparse_jacobian:
|
||||
J1 = J1.toarray()
|
||||
J2 = J2.toarray()
|
||||
J_eq = J_eq.toarray()
|
||||
J_ineq = J_ineq.toarray()
|
||||
|
||||
assert_array_equal(J_eq, np.vstack((J1[3], J2[1])))
|
||||
assert_array_equal(J_ineq, np.vstack((-J1[2], J1[0], -J1[0], J2[3],
|
||||
-J2[4], J2[0], -J2[0])))
|
||||
|
||||
|
||||
def test_initial_constraints_as_canonical_empty():
|
||||
n = 3
|
||||
for sparse_jacobian in [False, True]:
|
||||
c_eq, c_ineq, J_eq, J_ineq = initial_constraints_as_canonical(
|
||||
n, [], sparse_jacobian)
|
||||
|
||||
assert_array_equal(c_eq, [])
|
||||
assert_array_equal(c_ineq, [])
|
||||
|
||||
if sparse_jacobian:
|
||||
J_eq = J_eq.toarray()
|
||||
J_ineq = J_ineq.toarray()
|
||||
|
||||
assert_array_equal(J_eq, np.empty((0, n)))
|
||||
assert_array_equal(J_ineq, np.empty((0, n)))
|
|
@ -0,0 +1,214 @@
|
|||
import numpy as np
|
||||
import scipy.linalg
|
||||
from scipy.sparse import csc_matrix
|
||||
from scipy.optimize._trustregion_constr.projections \
|
||||
import projections, orthogonality
|
||||
from numpy.testing import (TestCase, assert_array_almost_equal,
|
||||
assert_equal, assert_allclose)
|
||||
|
||||
try:
|
||||
from sksparse.cholmod import cholesky_AAt
|
||||
sksparse_available = True
|
||||
available_sparse_methods = ("NormalEquation", "AugmentedSystem")
|
||||
except ImportError:
|
||||
sksparse_available = False
|
||||
available_sparse_methods = ("AugmentedSystem",)
|
||||
available_dense_methods = ('QRFactorization', 'SVDFactorization')
|
||||
|
||||
|
||||
class TestProjections(TestCase):
|
||||
|
||||
def test_nullspace_and_least_squares_sparse(self):
|
||||
A_dense = np.array([[1, 2, 3, 4, 0, 5, 0, 7],
|
||||
[0, 8, 7, 0, 1, 5, 9, 0],
|
||||
[1, 0, 0, 0, 0, 1, 2, 3]])
|
||||
At_dense = A_dense.T
|
||||
A = csc_matrix(A_dense)
|
||||
test_points = ([1, 2, 3, 4, 5, 6, 7, 8],
|
||||
[1, 10, 3, 0, 1, 6, 7, 8],
|
||||
[1.12, 10, 0, 0, 100000, 6, 0.7, 8])
|
||||
|
||||
for method in available_sparse_methods:
|
||||
Z, LS, _ = projections(A, method)
|
||||
for z in test_points:
|
||||
# Test if x is in the null_space
|
||||
x = Z.matvec(z)
|
||||
assert_array_almost_equal(A.dot(x), 0)
|
||||
# Test orthogonality
|
||||
assert_array_almost_equal(orthogonality(A, x), 0)
|
||||
# Test if x is the least square solution
|
||||
x = LS.matvec(z)
|
||||
x2 = scipy.linalg.lstsq(At_dense, z)[0]
|
||||
assert_array_almost_equal(x, x2)
|
||||
|
||||
def test_iterative_refinements_sparse(self):
|
||||
A_dense = np.array([[1, 2, 3, 4, 0, 5, 0, 7],
|
||||
[0, 8, 7, 0, 1, 5, 9, 0],
|
||||
[1, 0, 0, 0, 0, 1, 2, 3]])
|
||||
A = csc_matrix(A_dense)
|
||||
test_points = ([1, 2, 3, 4, 5, 6, 7, 8],
|
||||
[1, 10, 3, 0, 1, 6, 7, 8],
|
||||
[1.12, 10, 0, 0, 100000, 6, 0.7, 8],
|
||||
[1, 0, 0, 0, 0, 1, 2, 3+1e-10])
|
||||
|
||||
for method in available_sparse_methods:
|
||||
Z, LS, _ = projections(A, method, orth_tol=1e-18, max_refin=100)
|
||||
for z in test_points:
|
||||
# Test if x is in the null_space
|
||||
x = Z.matvec(z)
|
||||
atol = 1e-13 * abs(x).max()
|
||||
assert_allclose(A.dot(x), 0, atol=atol)
|
||||
# Test orthogonality
|
||||
assert_allclose(orthogonality(A, x), 0, atol=1e-13)
|
||||
|
||||
def test_rowspace_sparse(self):
|
||||
A_dense = np.array([[1, 2, 3, 4, 0, 5, 0, 7],
|
||||
[0, 8, 7, 0, 1, 5, 9, 0],
|
||||
[1, 0, 0, 0, 0, 1, 2, 3]])
|
||||
A = csc_matrix(A_dense)
|
||||
test_points = ([1, 2, 3],
|
||||
[1, 10, 3],
|
||||
[1.12, 10, 0])
|
||||
|
||||
for method in available_sparse_methods:
|
||||
_, _, Y = projections(A, method)
|
||||
for z in test_points:
|
||||
# Test if x is solution of A x = z
|
||||
x = Y.matvec(z)
|
||||
assert_array_almost_equal(A.dot(x), z)
|
||||
# Test if x is in the return row space of A
|
||||
A_ext = np.vstack((A_dense, x))
|
||||
assert_equal(np.linalg.matrix_rank(A_dense),
|
||||
np.linalg.matrix_rank(A_ext))
|
||||
|
||||
def test_nullspace_and_least_squares_dense(self):
|
||||
A = np.array([[1, 2, 3, 4, 0, 5, 0, 7],
|
||||
[0, 8, 7, 0, 1, 5, 9, 0],
|
||||
[1, 0, 0, 0, 0, 1, 2, 3]])
|
||||
At = A.T
|
||||
test_points = ([1, 2, 3, 4, 5, 6, 7, 8],
|
||||
[1, 10, 3, 0, 1, 6, 7, 8],
|
||||
[1.12, 10, 0, 0, 100000, 6, 0.7, 8])
|
||||
|
||||
for method in available_dense_methods:
|
||||
Z, LS, _ = projections(A, method)
|
||||
for z in test_points:
|
||||
# Test if x is in the null_space
|
||||
x = Z.matvec(z)
|
||||
assert_array_almost_equal(A.dot(x), 0)
|
||||
# Test orthogonality
|
||||
assert_array_almost_equal(orthogonality(A, x), 0)
|
||||
# Test if x is the least square solution
|
||||
x = LS.matvec(z)
|
||||
x2 = scipy.linalg.lstsq(At, z)[0]
|
||||
assert_array_almost_equal(x, x2)
|
||||
|
||||
def test_compare_dense_and_sparse(self):
|
||||
D = np.diag(range(1, 101))
|
||||
A = np.hstack([D, D, D, D])
|
||||
A_sparse = csc_matrix(A)
|
||||
np.random.seed(0)
|
||||
|
||||
Z, LS, Y = projections(A)
|
||||
Z_sparse, LS_sparse, Y_sparse = projections(A_sparse)
|
||||
for k in range(20):
|
||||
z = np.random.normal(size=(400,))
|
||||
assert_array_almost_equal(Z.dot(z), Z_sparse.dot(z))
|
||||
assert_array_almost_equal(LS.dot(z), LS_sparse.dot(z))
|
||||
x = np.random.normal(size=(100,))
|
||||
assert_array_almost_equal(Y.dot(x), Y_sparse.dot(x))
|
||||
|
||||
def test_compare_dense_and_sparse2(self):
|
||||
D1 = np.diag([-1.7, 1, 0.5])
|
||||
D2 = np.diag([1, -0.6, -0.3])
|
||||
D3 = np.diag([-0.3, -1.5, 2])
|
||||
A = np.hstack([D1, D2, D3])
|
||||
A_sparse = csc_matrix(A)
|
||||
np.random.seed(0)
|
||||
|
||||
Z, LS, Y = projections(A)
|
||||
Z_sparse, LS_sparse, Y_sparse = projections(A_sparse)
|
||||
for k in range(1):
|
||||
z = np.random.normal(size=(9,))
|
||||
assert_array_almost_equal(Z.dot(z), Z_sparse.dot(z))
|
||||
assert_array_almost_equal(LS.dot(z), LS_sparse.dot(z))
|
||||
x = np.random.normal(size=(3,))
|
||||
assert_array_almost_equal(Y.dot(x), Y_sparse.dot(x))
|
||||
|
||||
def test_iterative_refinements_dense(self):
|
||||
A = np.array([[1, 2, 3, 4, 0, 5, 0, 7],
|
||||
[0, 8, 7, 0, 1, 5, 9, 0],
|
||||
[1, 0, 0, 0, 0, 1, 2, 3]])
|
||||
test_points = ([1, 2, 3, 4, 5, 6, 7, 8],
|
||||
[1, 10, 3, 0, 1, 6, 7, 8],
|
||||
[1, 0, 0, 0, 0, 1, 2, 3+1e-10])
|
||||
|
||||
for method in available_dense_methods:
|
||||
Z, LS, _ = projections(A, method, orth_tol=1e-18, max_refin=10)
|
||||
for z in test_points:
|
||||
# Test if x is in the null_space
|
||||
x = Z.matvec(z)
|
||||
assert_array_almost_equal(A.dot(x), 0, decimal=14)
|
||||
# Test orthogonality
|
||||
assert_array_almost_equal(orthogonality(A, x), 0, decimal=16)
|
||||
|
||||
def test_rowspace_dense(self):
|
||||
A = np.array([[1, 2, 3, 4, 0, 5, 0, 7],
|
||||
[0, 8, 7, 0, 1, 5, 9, 0],
|
||||
[1, 0, 0, 0, 0, 1, 2, 3]])
|
||||
test_points = ([1, 2, 3],
|
||||
[1, 10, 3],
|
||||
[1.12, 10, 0])
|
||||
|
||||
for method in available_dense_methods:
|
||||
_, _, Y = projections(A, method)
|
||||
for z in test_points:
|
||||
# Test if x is solution of A x = z
|
||||
x = Y.matvec(z)
|
||||
assert_array_almost_equal(A.dot(x), z)
|
||||
# Test if x is in the return row space of A
|
||||
A_ext = np.vstack((A, x))
|
||||
assert_equal(np.linalg.matrix_rank(A),
|
||||
np.linalg.matrix_rank(A_ext))
|
||||
|
||||
|
||||
class TestOrthogonality(TestCase):
|
||||
|
||||
def test_dense_matrix(self):
|
||||
A = np.array([[1, 2, 3, 4, 0, 5, 0, 7],
|
||||
[0, 8, 7, 0, 1, 5, 9, 0],
|
||||
[1, 0, 0, 0, 0, 1, 2, 3]])
|
||||
test_vectors = ([-1.98931144, -1.56363389,
|
||||
-0.84115584, 2.2864762,
|
||||
5.599141, 0.09286976,
|
||||
1.37040802, -0.28145812],
|
||||
[697.92794044, -4091.65114008,
|
||||
-3327.42316335, 836.86906951,
|
||||
99434.98929065, -1285.37653682,
|
||||
-4109.21503806, 2935.29289083])
|
||||
test_expected_orth = (0, 0)
|
||||
|
||||
for i in range(len(test_vectors)):
|
||||
x = test_vectors[i]
|
||||
orth = test_expected_orth[i]
|
||||
assert_array_almost_equal(orthogonality(A, x), orth)
|
||||
|
||||
def test_sparse_matrix(self):
|
||||
A = np.array([[1, 2, 3, 4, 0, 5, 0, 7],
|
||||
[0, 8, 7, 0, 1, 5, 9, 0],
|
||||
[1, 0, 0, 0, 0, 1, 2, 3]])
|
||||
A = csc_matrix(A)
|
||||
test_vectors = ([-1.98931144, -1.56363389,
|
||||
-0.84115584, 2.2864762,
|
||||
5.599141, 0.09286976,
|
||||
1.37040802, -0.28145812],
|
||||
[697.92794044, -4091.65114008,
|
||||
-3327.42316335, 836.86906951,
|
||||
99434.98929065, -1285.37653682,
|
||||
-4109.21503806, 2935.29289083])
|
||||
test_expected_orth = (0, 0)
|
||||
|
||||
for i in range(len(test_vectors)):
|
||||
x = test_vectors[i]
|
||||
orth = test_expected_orth[i]
|
||||
assert_array_almost_equal(orthogonality(A, x), orth)
|
|
@ -0,0 +1,645 @@
|
|||
import numpy as np
|
||||
from scipy.sparse import csc_matrix
|
||||
from scipy.optimize._trustregion_constr.qp_subproblem \
|
||||
import (eqp_kktfact,
|
||||
projected_cg,
|
||||
box_intersections,
|
||||
sphere_intersections,
|
||||
box_sphere_intersections,
|
||||
modified_dogleg)
|
||||
from scipy.optimize._trustregion_constr.projections \
|
||||
import projections
|
||||
from numpy.testing import (TestCase, assert_array_almost_equal, assert_equal)
|
||||
import pytest
|
||||
|
||||
|
||||
class TestEQPDirectFactorization(TestCase):
|
||||
|
||||
# From Example 16.2 Nocedal/Wright "Numerical
|
||||
# Optimization" p.452.
|
||||
def test_nocedal_example(self):
|
||||
H = csc_matrix([[6, 2, 1],
|
||||
[2, 5, 2],
|
||||
[1, 2, 4]])
|
||||
A = csc_matrix([[1, 0, 1],
|
||||
[0, 1, 1]])
|
||||
c = np.array([-8, -3, -3])
|
||||
b = -np.array([3, 0])
|
||||
x, lagrange_multipliers = eqp_kktfact(H, c, A, b)
|
||||
assert_array_almost_equal(x, [2, -1, 1])
|
||||
assert_array_almost_equal(lagrange_multipliers, [3, -2])
|
||||
|
||||
|
||||
class TestSphericalBoundariesIntersections(TestCase):
|
||||
|
||||
def test_2d_sphere_constraints(self):
|
||||
# Interior inicial point
|
||||
ta, tb, intersect = sphere_intersections([0, 0],
|
||||
[1, 0], 0.5)
|
||||
assert_array_almost_equal([ta, tb], [0, 0.5])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
# No intersection between line and circle
|
||||
ta, tb, intersect = sphere_intersections([2, 0],
|
||||
[0, 1], 1)
|
||||
assert_equal(intersect, False)
|
||||
|
||||
# Outside initial point pointing toward outside the circle
|
||||
ta, tb, intersect = sphere_intersections([2, 0],
|
||||
[1, 0], 1)
|
||||
assert_equal(intersect, False)
|
||||
|
||||
# Outside initial point pointing toward inside the circle
|
||||
ta, tb, intersect = sphere_intersections([2, 0],
|
||||
[-1, 0], 1.5)
|
||||
assert_array_almost_equal([ta, tb], [0.5, 1])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
# Initial point on the boundary
|
||||
ta, tb, intersect = sphere_intersections([2, 0],
|
||||
[1, 0], 2)
|
||||
assert_array_almost_equal([ta, tb], [0, 0])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
def test_2d_sphere_constraints_line_intersections(self):
|
||||
# Interior initial point
|
||||
ta, tb, intersect = sphere_intersections([0, 0],
|
||||
[1, 0], 0.5,
|
||||
entire_line=True)
|
||||
assert_array_almost_equal([ta, tb], [-0.5, 0.5])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
# No intersection between line and circle
|
||||
ta, tb, intersect = sphere_intersections([2, 0],
|
||||
[0, 1], 1,
|
||||
entire_line=True)
|
||||
assert_equal(intersect, False)
|
||||
|
||||
# Outside initial point pointing toward outside the circle
|
||||
ta, tb, intersect = sphere_intersections([2, 0],
|
||||
[1, 0], 1,
|
||||
entire_line=True)
|
||||
assert_array_almost_equal([ta, tb], [-3, -1])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
# Outside initial point pointing toward inside the circle
|
||||
ta, tb, intersect = sphere_intersections([2, 0],
|
||||
[-1, 0], 1.5,
|
||||
entire_line=True)
|
||||
assert_array_almost_equal([ta, tb], [0.5, 3.5])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
# Initial point on the boundary
|
||||
ta, tb, intersect = sphere_intersections([2, 0],
|
||||
[1, 0], 2,
|
||||
entire_line=True)
|
||||
assert_array_almost_equal([ta, tb], [-4, 0])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
|
||||
class TestBoxBoundariesIntersections(TestCase):
|
||||
|
||||
def test_2d_box_constraints(self):
|
||||
# Box constraint in the direction of vector d
|
||||
ta, tb, intersect = box_intersections([2, 0], [0, 2],
|
||||
[1, 1], [3, 3])
|
||||
assert_array_almost_equal([ta, tb], [0.5, 1])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
# Negative direction
|
||||
ta, tb, intersect = box_intersections([2, 0], [0, 2],
|
||||
[1, -3], [3, -1])
|
||||
assert_equal(intersect, False)
|
||||
|
||||
# Some constraints are absent (set to +/- inf)
|
||||
ta, tb, intersect = box_intersections([2, 0], [0, 2],
|
||||
[-np.inf, 1],
|
||||
[np.inf, np.inf])
|
||||
assert_array_almost_equal([ta, tb], [0.5, 1])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
# Intersect on the face of the box
|
||||
ta, tb, intersect = box_intersections([1, 0], [0, 1],
|
||||
[1, 1], [3, 3])
|
||||
assert_array_almost_equal([ta, tb], [1, 1])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
# Interior initial point
|
||||
ta, tb, intersect = box_intersections([0, 0], [4, 4],
|
||||
[-2, -3], [3, 2])
|
||||
assert_array_almost_equal([ta, tb], [0, 0.5])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
# No intersection between line and box constraints
|
||||
ta, tb, intersect = box_intersections([2, 0], [0, 2],
|
||||
[-3, -3], [-1, -1])
|
||||
assert_equal(intersect, False)
|
||||
ta, tb, intersect = box_intersections([2, 0], [0, 2],
|
||||
[-3, 3], [-1, 1])
|
||||
assert_equal(intersect, False)
|
||||
ta, tb, intersect = box_intersections([2, 0], [0, 2],
|
||||
[-3, -np.inf],
|
||||
[-1, np.inf])
|
||||
assert_equal(intersect, False)
|
||||
ta, tb, intersect = box_intersections([0, 0], [1, 100],
|
||||
[1, 1], [3, 3])
|
||||
assert_equal(intersect, False)
|
||||
ta, tb, intersect = box_intersections([0.99, 0], [0, 2],
|
||||
[1, 1], [3, 3])
|
||||
assert_equal(intersect, False)
|
||||
|
||||
# Initial point on the boundary
|
||||
ta, tb, intersect = box_intersections([2, 2], [0, 1],
|
||||
[-2, -2], [2, 2])
|
||||
assert_array_almost_equal([ta, tb], [0, 0])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
def test_2d_box_constraints_entire_line(self):
|
||||
# Box constraint in the direction of vector d
|
||||
ta, tb, intersect = box_intersections([2, 0], [0, 2],
|
||||
[1, 1], [3, 3],
|
||||
entire_line=True)
|
||||
assert_array_almost_equal([ta, tb], [0.5, 1.5])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
# Negative direction
|
||||
ta, tb, intersect = box_intersections([2, 0], [0, 2],
|
||||
[1, -3], [3, -1],
|
||||
entire_line=True)
|
||||
assert_array_almost_equal([ta, tb], [-1.5, -0.5])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
# Some constraints are absent (set to +/- inf)
|
||||
ta, tb, intersect = box_intersections([2, 0], [0, 2],
|
||||
[-np.inf, 1],
|
||||
[np.inf, np.inf],
|
||||
entire_line=True)
|
||||
assert_array_almost_equal([ta, tb], [0.5, np.inf])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
# Intersect on the face of the box
|
||||
ta, tb, intersect = box_intersections([1, 0], [0, 1],
|
||||
[1, 1], [3, 3],
|
||||
entire_line=True)
|
||||
assert_array_almost_equal([ta, tb], [1, 3])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
# Interior initial pointoint
|
||||
ta, tb, intersect = box_intersections([0, 0], [4, 4],
|
||||
[-2, -3], [3, 2],
|
||||
entire_line=True)
|
||||
assert_array_almost_equal([ta, tb], [-0.5, 0.5])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
# No intersection between line and box constraints
|
||||
ta, tb, intersect = box_intersections([2, 0], [0, 2],
|
||||
[-3, -3], [-1, -1],
|
||||
entire_line=True)
|
||||
assert_equal(intersect, False)
|
||||
ta, tb, intersect = box_intersections([2, 0], [0, 2],
|
||||
[-3, 3], [-1, 1],
|
||||
entire_line=True)
|
||||
assert_equal(intersect, False)
|
||||
ta, tb, intersect = box_intersections([2, 0], [0, 2],
|
||||
[-3, -np.inf],
|
||||
[-1, np.inf],
|
||||
entire_line=True)
|
||||
assert_equal(intersect, False)
|
||||
ta, tb, intersect = box_intersections([0, 0], [1, 100],
|
||||
[1, 1], [3, 3],
|
||||
entire_line=True)
|
||||
assert_equal(intersect, False)
|
||||
ta, tb, intersect = box_intersections([0.99, 0], [0, 2],
|
||||
[1, 1], [3, 3],
|
||||
entire_line=True)
|
||||
assert_equal(intersect, False)
|
||||
|
||||
# Initial point on the boundary
|
||||
ta, tb, intersect = box_intersections([2, 2], [0, 1],
|
||||
[-2, -2], [2, 2],
|
||||
entire_line=True)
|
||||
assert_array_almost_equal([ta, tb], [-4, 0])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
def test_3d_box_constraints(self):
|
||||
# Simple case
|
||||
ta, tb, intersect = box_intersections([1, 1, 0], [0, 0, 1],
|
||||
[1, 1, 1], [3, 3, 3])
|
||||
assert_array_almost_equal([ta, tb], [1, 1])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
# Negative direction
|
||||
ta, tb, intersect = box_intersections([1, 1, 0], [0, 0, -1],
|
||||
[1, 1, 1], [3, 3, 3])
|
||||
assert_equal(intersect, False)
|
||||
|
||||
# Interior point
|
||||
ta, tb, intersect = box_intersections([2, 2, 2], [0, -1, 1],
|
||||
[1, 1, 1], [3, 3, 3])
|
||||
assert_array_almost_equal([ta, tb], [0, 1])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
def test_3d_box_constraints_entire_line(self):
|
||||
# Simple case
|
||||
ta, tb, intersect = box_intersections([1, 1, 0], [0, 0, 1],
|
||||
[1, 1, 1], [3, 3, 3],
|
||||
entire_line=True)
|
||||
assert_array_almost_equal([ta, tb], [1, 3])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
# Negative direction
|
||||
ta, tb, intersect = box_intersections([1, 1, 0], [0, 0, -1],
|
||||
[1, 1, 1], [3, 3, 3],
|
||||
entire_line=True)
|
||||
assert_array_almost_equal([ta, tb], [-3, -1])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
# Interior point
|
||||
ta, tb, intersect = box_intersections([2, 2, 2], [0, -1, 1],
|
||||
[1, 1, 1], [3, 3, 3],
|
||||
entire_line=True)
|
||||
assert_array_almost_equal([ta, tb], [-1, 1])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
|
||||
class TestBoxSphereBoundariesIntersections(TestCase):
|
||||
|
||||
def test_2d_box_constraints(self):
|
||||
# Both constraints are active
|
||||
ta, tb, intersect = box_sphere_intersections([1, 1], [-2, 2],
|
||||
[-1, -2], [1, 2], 2,
|
||||
entire_line=False)
|
||||
assert_array_almost_equal([ta, tb], [0, 0.5])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
# None of the constraints are active
|
||||
ta, tb, intersect = box_sphere_intersections([1, 1], [-1, 1],
|
||||
[-1, -3], [1, 3], 10,
|
||||
entire_line=False)
|
||||
assert_array_almost_equal([ta, tb], [0, 1])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
# Box constraints are active
|
||||
ta, tb, intersect = box_sphere_intersections([1, 1], [-4, 4],
|
||||
[-1, -3], [1, 3], 10,
|
||||
entire_line=False)
|
||||
assert_array_almost_equal([ta, tb], [0, 0.5])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
# Spherical constraints are active
|
||||
ta, tb, intersect = box_sphere_intersections([1, 1], [-4, 4],
|
||||
[-1, -3], [1, 3], 2,
|
||||
entire_line=False)
|
||||
assert_array_almost_equal([ta, tb], [0, 0.25])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
# Infeasible problems
|
||||
ta, tb, intersect = box_sphere_intersections([2, 2], [-4, 4],
|
||||
[-1, -3], [1, 3], 2,
|
||||
entire_line=False)
|
||||
assert_equal(intersect, False)
|
||||
ta, tb, intersect = box_sphere_intersections([1, 1], [-4, 4],
|
||||
[2, 4], [2, 4], 2,
|
||||
entire_line=False)
|
||||
assert_equal(intersect, False)
|
||||
|
||||
def test_2d_box_constraints_entire_line(self):
|
||||
# Both constraints are active
|
||||
ta, tb, intersect = box_sphere_intersections([1, 1], [-2, 2],
|
||||
[-1, -2], [1, 2], 2,
|
||||
entire_line=True)
|
||||
assert_array_almost_equal([ta, tb], [0, 0.5])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
# None of the constraints are active
|
||||
ta, tb, intersect = box_sphere_intersections([1, 1], [-1, 1],
|
||||
[-1, -3], [1, 3], 10,
|
||||
entire_line=True)
|
||||
assert_array_almost_equal([ta, tb], [0, 2])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
# Box constraints are active
|
||||
ta, tb, intersect = box_sphere_intersections([1, 1], [-4, 4],
|
||||
[-1, -3], [1, 3], 10,
|
||||
entire_line=True)
|
||||
assert_array_almost_equal([ta, tb], [0, 0.5])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
# Spherical constraints are active
|
||||
ta, tb, intersect = box_sphere_intersections([1, 1], [-4, 4],
|
||||
[-1, -3], [1, 3], 2,
|
||||
entire_line=True)
|
||||
assert_array_almost_equal([ta, tb], [0, 0.25])
|
||||
assert_equal(intersect, True)
|
||||
|
||||
# Infeasible problems
|
||||
ta, tb, intersect = box_sphere_intersections([2, 2], [-4, 4],
|
||||
[-1, -3], [1, 3], 2,
|
||||
entire_line=True)
|
||||
assert_equal(intersect, False)
|
||||
ta, tb, intersect = box_sphere_intersections([1, 1], [-4, 4],
|
||||
[2, 4], [2, 4], 2,
|
||||
entire_line=True)
|
||||
assert_equal(intersect, False)
|
||||
|
||||
|
||||
class TestModifiedDogleg(TestCase):
|
||||
|
||||
def test_cauchypoint_equalsto_newtonpoint(self):
|
||||
A = np.array([[1, 8]])
|
||||
b = np.array([-16])
|
||||
_, _, Y = projections(A)
|
||||
newton_point = np.array([0.24615385, 1.96923077])
|
||||
|
||||
# Newton point inside boundaries
|
||||
x = modified_dogleg(A, Y, b, 2, [-np.inf, -np.inf], [np.inf, np.inf])
|
||||
assert_array_almost_equal(x, newton_point)
|
||||
|
||||
# Spherical constraint active
|
||||
x = modified_dogleg(A, Y, b, 1, [-np.inf, -np.inf], [np.inf, np.inf])
|
||||
assert_array_almost_equal(x, newton_point/np.linalg.norm(newton_point))
|
||||
|
||||
# Box constraints active
|
||||
x = modified_dogleg(A, Y, b, 2, [-np.inf, -np.inf], [0.1, np.inf])
|
||||
assert_array_almost_equal(x, (newton_point/newton_point[0]) * 0.1)
|
||||
|
||||
def test_3d_example(self):
|
||||
A = np.array([[1, 8, 1],
|
||||
[4, 2, 2]])
|
||||
b = np.array([-16, 2])
|
||||
Z, LS, Y = projections(A)
|
||||
|
||||
newton_point = np.array([-1.37090909, 2.23272727, -0.49090909])
|
||||
cauchy_point = np.array([0.11165723, 1.73068711, 0.16748585])
|
||||
origin = np.zeros_like(newton_point)
|
||||
|
||||
# newton_point inside boundaries
|
||||
x = modified_dogleg(A, Y, b, 3, [-np.inf, -np.inf, -np.inf],
|
||||
[np.inf, np.inf, np.inf])
|
||||
assert_array_almost_equal(x, newton_point)
|
||||
|
||||
# line between cauchy_point and newton_point contains best point
|
||||
# (spherical constraint is active).
|
||||
x = modified_dogleg(A, Y, b, 2, [-np.inf, -np.inf, -np.inf],
|
||||
[np.inf, np.inf, np.inf])
|
||||
z = cauchy_point
|
||||
d = newton_point-cauchy_point
|
||||
t = ((x-z)/(d))
|
||||
assert_array_almost_equal(t, np.full(3, 0.40807330))
|
||||
assert_array_almost_equal(np.linalg.norm(x), 2)
|
||||
|
||||
# line between cauchy_point and newton_point contains best point
|
||||
# (box constraint is active).
|
||||
x = modified_dogleg(A, Y, b, 5, [-1, -np.inf, -np.inf],
|
||||
[np.inf, np.inf, np.inf])
|
||||
z = cauchy_point
|
||||
d = newton_point-cauchy_point
|
||||
t = ((x-z)/(d))
|
||||
assert_array_almost_equal(t, np.full(3, 0.7498195))
|
||||
assert_array_almost_equal(x[0], -1)
|
||||
|
||||
# line between origin and cauchy_point contains best point
|
||||
# (spherical constraint is active).
|
||||
x = modified_dogleg(A, Y, b, 1, [-np.inf, -np.inf, -np.inf],
|
||||
[np.inf, np.inf, np.inf])
|
||||
z = origin
|
||||
d = cauchy_point
|
||||
t = ((x-z)/(d))
|
||||
assert_array_almost_equal(t, np.full(3, 0.573936265))
|
||||
assert_array_almost_equal(np.linalg.norm(x), 1)
|
||||
|
||||
# line between origin and newton_point contains best point
|
||||
# (box constraint is active).
|
||||
x = modified_dogleg(A, Y, b, 2, [-np.inf, -np.inf, -np.inf],
|
||||
[np.inf, 1, np.inf])
|
||||
z = origin
|
||||
d = newton_point
|
||||
t = ((x-z)/(d))
|
||||
assert_array_almost_equal(t, np.full(3, 0.4478827364))
|
||||
assert_array_almost_equal(x[1], 1)
|
||||
|
||||
|
||||
class TestProjectCG(TestCase):
|
||||
|
||||
# From Example 16.2 Nocedal/Wright "Numerical
|
||||
# Optimization" p.452.
|
||||
def test_nocedal_example(self):
|
||||
H = csc_matrix([[6, 2, 1],
|
||||
[2, 5, 2],
|
||||
[1, 2, 4]])
|
||||
A = csc_matrix([[1, 0, 1],
|
||||
[0, 1, 1]])
|
||||
c = np.array([-8, -3, -3])
|
||||
b = -np.array([3, 0])
|
||||
Z, _, Y = projections(A)
|
||||
x, info = projected_cg(H, c, Z, Y, b)
|
||||
assert_equal(info["stop_cond"], 4)
|
||||
assert_equal(info["hits_boundary"], False)
|
||||
assert_array_almost_equal(x, [2, -1, 1])
|
||||
|
||||
def test_compare_with_direct_fact(self):
|
||||
H = csc_matrix([[6, 2, 1, 3],
|
||||
[2, 5, 2, 4],
|
||||
[1, 2, 4, 5],
|
||||
[3, 4, 5, 7]])
|
||||
A = csc_matrix([[1, 0, 1, 0],
|
||||
[0, 1, 1, 1]])
|
||||
c = np.array([-2, -3, -3, 1])
|
||||
b = -np.array([3, 0])
|
||||
Z, _, Y = projections(A)
|
||||
x, info = projected_cg(H, c, Z, Y, b, tol=0)
|
||||
x_kkt, _ = eqp_kktfact(H, c, A, b)
|
||||
assert_equal(info["stop_cond"], 1)
|
||||
assert_equal(info["hits_boundary"], False)
|
||||
assert_array_almost_equal(x, x_kkt)
|
||||
|
||||
def test_trust_region_infeasible(self):
|
||||
H = csc_matrix([[6, 2, 1, 3],
|
||||
[2, 5, 2, 4],
|
||||
[1, 2, 4, 5],
|
||||
[3, 4, 5, 7]])
|
||||
A = csc_matrix([[1, 0, 1, 0],
|
||||
[0, 1, 1, 1]])
|
||||
c = np.array([-2, -3, -3, 1])
|
||||
b = -np.array([3, 0])
|
||||
trust_radius = 1
|
||||
Z, _, Y = projections(A)
|
||||
with pytest.raises(ValueError):
|
||||
projected_cg(H, c, Z, Y, b, trust_radius=trust_radius)
|
||||
|
||||
def test_trust_region_barely_feasible(self):
|
||||
H = csc_matrix([[6, 2, 1, 3],
|
||||
[2, 5, 2, 4],
|
||||
[1, 2, 4, 5],
|
||||
[3, 4, 5, 7]])
|
||||
A = csc_matrix([[1, 0, 1, 0],
|
||||
[0, 1, 1, 1]])
|
||||
c = np.array([-2, -3, -3, 1])
|
||||
b = -np.array([3, 0])
|
||||
trust_radius = 2.32379000772445021283
|
||||
Z, _, Y = projections(A)
|
||||
x, info = projected_cg(H, c, Z, Y, b,
|
||||
tol=0,
|
||||
trust_radius=trust_radius)
|
||||
assert_equal(info["stop_cond"], 2)
|
||||
assert_equal(info["hits_boundary"], True)
|
||||
assert_array_almost_equal(np.linalg.norm(x), trust_radius)
|
||||
assert_array_almost_equal(x, -Y.dot(b))
|
||||
|
||||
def test_hits_boundary(self):
|
||||
H = csc_matrix([[6, 2, 1, 3],
|
||||
[2, 5, 2, 4],
|
||||
[1, 2, 4, 5],
|
||||
[3, 4, 5, 7]])
|
||||
A = csc_matrix([[1, 0, 1, 0],
|
||||
[0, 1, 1, 1]])
|
||||
c = np.array([-2, -3, -3, 1])
|
||||
b = -np.array([3, 0])
|
||||
trust_radius = 3
|
||||
Z, _, Y = projections(A)
|
||||
x, info = projected_cg(H, c, Z, Y, b,
|
||||
tol=0,
|
||||
trust_radius=trust_radius)
|
||||
assert_equal(info["stop_cond"], 2)
|
||||
assert_equal(info["hits_boundary"], True)
|
||||
assert_array_almost_equal(np.linalg.norm(x), trust_radius)
|
||||
|
||||
def test_negative_curvature_unconstrained(self):
|
||||
H = csc_matrix([[1, 2, 1, 3],
|
||||
[2, 0, 2, 4],
|
||||
[1, 2, 0, 2],
|
||||
[3, 4, 2, 0]])
|
||||
A = csc_matrix([[1, 0, 1, 0],
|
||||
[0, 1, 0, 1]])
|
||||
c = np.array([-2, -3, -3, 1])
|
||||
b = -np.array([3, 0])
|
||||
Z, _, Y = projections(A)
|
||||
with pytest.raises(ValueError):
|
||||
projected_cg(H, c, Z, Y, b, tol=0)
|
||||
|
||||
def test_negative_curvature(self):
|
||||
H = csc_matrix([[1, 2, 1, 3],
|
||||
[2, 0, 2, 4],
|
||||
[1, 2, 0, 2],
|
||||
[3, 4, 2, 0]])
|
||||
A = csc_matrix([[1, 0, 1, 0],
|
||||
[0, 1, 0, 1]])
|
||||
c = np.array([-2, -3, -3, 1])
|
||||
b = -np.array([3, 0])
|
||||
Z, _, Y = projections(A)
|
||||
trust_radius = 1000
|
||||
x, info = projected_cg(H, c, Z, Y, b,
|
||||
tol=0,
|
||||
trust_radius=trust_radius)
|
||||
assert_equal(info["stop_cond"], 3)
|
||||
assert_equal(info["hits_boundary"], True)
|
||||
assert_array_almost_equal(np.linalg.norm(x), trust_radius)
|
||||
|
||||
# The box constraints are inactive at the solution but
|
||||
# are active during the iterations.
|
||||
def test_inactive_box_constraints(self):
|
||||
H = csc_matrix([[6, 2, 1, 3],
|
||||
[2, 5, 2, 4],
|
||||
[1, 2, 4, 5],
|
||||
[3, 4, 5, 7]])
|
||||
A = csc_matrix([[1, 0, 1, 0],
|
||||
[0, 1, 1, 1]])
|
||||
c = np.array([-2, -3, -3, 1])
|
||||
b = -np.array([3, 0])
|
||||
Z, _, Y = projections(A)
|
||||
x, info = projected_cg(H, c, Z, Y, b,
|
||||
tol=0,
|
||||
lb=[0.5, -np.inf,
|
||||
-np.inf, -np.inf],
|
||||
return_all=True)
|
||||
x_kkt, _ = eqp_kktfact(H, c, A, b)
|
||||
assert_equal(info["stop_cond"], 1)
|
||||
assert_equal(info["hits_boundary"], False)
|
||||
assert_array_almost_equal(x, x_kkt)
|
||||
|
||||
# The box constraints active and the termination is
|
||||
# by maximum iterations (infeasible iteraction).
|
||||
def test_active_box_constraints_maximum_iterations_reached(self):
|
||||
H = csc_matrix([[6, 2, 1, 3],
|
||||
[2, 5, 2, 4],
|
||||
[1, 2, 4, 5],
|
||||
[3, 4, 5, 7]])
|
||||
A = csc_matrix([[1, 0, 1, 0],
|
||||
[0, 1, 1, 1]])
|
||||
c = np.array([-2, -3, -3, 1])
|
||||
b = -np.array([3, 0])
|
||||
Z, _, Y = projections(A)
|
||||
x, info = projected_cg(H, c, Z, Y, b,
|
||||
tol=0,
|
||||
lb=[0.8, -np.inf,
|
||||
-np.inf, -np.inf],
|
||||
return_all=True)
|
||||
assert_equal(info["stop_cond"], 1)
|
||||
assert_equal(info["hits_boundary"], True)
|
||||
assert_array_almost_equal(A.dot(x), -b)
|
||||
assert_array_almost_equal(x[0], 0.8)
|
||||
|
||||
# The box constraints are active and the termination is
|
||||
# because it hits boundary (without infeasible iteraction).
|
||||
def test_active_box_constraints_hits_boundaries(self):
|
||||
H = csc_matrix([[6, 2, 1, 3],
|
||||
[2, 5, 2, 4],
|
||||
[1, 2, 4, 5],
|
||||
[3, 4, 5, 7]])
|
||||
A = csc_matrix([[1, 0, 1, 0],
|
||||
[0, 1, 1, 1]])
|
||||
c = np.array([-2, -3, -3, 1])
|
||||
b = -np.array([3, 0])
|
||||
trust_radius = 3
|
||||
Z, _, Y = projections(A)
|
||||
x, info = projected_cg(H, c, Z, Y, b,
|
||||
tol=0,
|
||||
ub=[np.inf, np.inf, 1.6, np.inf],
|
||||
trust_radius=trust_radius,
|
||||
return_all=True)
|
||||
assert_equal(info["stop_cond"], 2)
|
||||
assert_equal(info["hits_boundary"], True)
|
||||
assert_array_almost_equal(x[2], 1.6)
|
||||
|
||||
# The box constraints are active and the termination is
|
||||
# because it hits boundary (infeasible iteraction).
|
||||
def test_active_box_constraints_hits_boundaries_infeasible_iter(self):
|
||||
H = csc_matrix([[6, 2, 1, 3],
|
||||
[2, 5, 2, 4],
|
||||
[1, 2, 4, 5],
|
||||
[3, 4, 5, 7]])
|
||||
A = csc_matrix([[1, 0, 1, 0],
|
||||
[0, 1, 1, 1]])
|
||||
c = np.array([-2, -3, -3, 1])
|
||||
b = -np.array([3, 0])
|
||||
trust_radius = 4
|
||||
Z, _, Y = projections(A)
|
||||
x, info = projected_cg(H, c, Z, Y, b,
|
||||
tol=0,
|
||||
ub=[np.inf, 0.1, np.inf, np.inf],
|
||||
trust_radius=trust_radius,
|
||||
return_all=True)
|
||||
assert_equal(info["stop_cond"], 2)
|
||||
assert_equal(info["hits_boundary"], True)
|
||||
assert_array_almost_equal(x[1], 0.1)
|
||||
|
||||
# The box constraints are active and the termination is
|
||||
# because it hits boundary (no infeasible iteraction).
|
||||
def test_active_box_constraints_negative_curvature(self):
|
||||
H = csc_matrix([[1, 2, 1, 3],
|
||||
[2, 0, 2, 4],
|
||||
[1, 2, 0, 2],
|
||||
[3, 4, 2, 0]])
|
||||
A = csc_matrix([[1, 0, 1, 0],
|
||||
[0, 1, 0, 1]])
|
||||
c = np.array([-2, -3, -3, 1])
|
||||
b = -np.array([3, 0])
|
||||
Z, _, Y = projections(A)
|
||||
trust_radius = 1000
|
||||
x, info = projected_cg(H, c, Z, Y, b,
|
||||
tol=0,
|
||||
ub=[np.inf, np.inf, 100, np.inf],
|
||||
trust_radius=trust_radius)
|
||||
assert_equal(info["stop_cond"], 3)
|
||||
assert_equal(info["hits_boundary"], True)
|
||||
assert_array_almost_equal(x[2], 100)
|
|
@ -0,0 +1,10 @@
|
|||
from scipy.optimize import minimize, Bounds
|
||||
|
||||
def test_gh10880():
|
||||
# checks that verbose reporting works with trust-constr
|
||||
bnds = Bounds(1, 2)
|
||||
opts = {'maxiter': 1000, 'verbose': 2}
|
||||
minimize(lambda x: x**2, x0=2., method='trust-constr', bounds=bnds, options=opts)
|
||||
|
||||
opts = {'maxiter': 1000, 'verbose': 3}
|
||||
minimize(lambda x: x**2, x0=2., method='trust-constr', bounds=bnds, options=opts)
|
Loading…
Add table
Add a link
Reference in a new issue