def test_merge(self): """Test merging functions. """ # sum_entries x = Variable(10) fn1 = sum_entries(x, gamma=1.0) fn2 = norm1(x) assert can_merge(fn1, fn2) merged = merge_fns(fn1, fn2) v = np.arange(10) * 1.0 - 5.0 prox_val1 = merged.prox(1.0, v.copy()) tmp = norm1(x, c=np.ones(10), gamma=1.0) prox_val2 = tmp.prox(1.0, v.copy()) self.assertItemsAlmostEqual(prox_val1, prox_val2) # sum_squares x = Variable(10) val = np.arange(10) fn1 = sum_squares(x, gamma=1.0, beta=2.0, alpha=3.0, b=val) fn2 = norm1(x) assert can_merge(fn1, fn2) merged = merge_fns(fn1, fn2) v = np.arange(10) * 1.0 - 5.0 prox_val1 = merged.prox(1.0, v.copy()) tmp = norm1(x, c=-12 * val, gamma=1.0 + 12, d=val.dot(val)) prox_val2 = tmp.prox(1.0, v.copy()) self.assertItemsAlmostEqual(prox_val1, prox_val2)
def test_problem_absorb(self): """Test problem object with absorption. """ X = Variable((4, 2)) B = np.reshape(np.arange(8, dtype=np.float32), (4, 2), order='F') # Absorbing lin ops. prox_fns = sum_squares(-2 * X, b=B) + norm1(5 * mul_elemwise(B, X)) prob = Problem(prox_fns) prob.set_absorb(True) prob.solve(solver="admm", eps_rel=1e-6, eps_abs=1e-6) cvx_X = cvx.Variable((4, 2)) cost = cvx.sum_squares(-2 * cvx_X - B) + cvx.norm( 5 * cvx.multiply(B, cvx_X), 1) cvx_prob = cvx.Problem(cvx.Minimize(cost)) cvx_prob.solve(solver=cvx.SCS) self.assertItemsAlmostEqual(X.value, cvx_X.value, places=2) prob.set_absorb(False) prob.solve(solver="admm", eps_rel=1e-6, eps_abs=1e-6) self.assertItemsAlmostEqual(X.value, cvx_X.value, places=2) # Constant offsets. prox_fns = sum_squares(-2 * X - B) + norm1(5 * mul_elemwise(B, X)) prob = Problem(prox_fns) prob.solve(solver="admm", eps_rel=1e-6, eps_abs=1e-6) self.assertItemsAlmostEqual(X.value, cvx_X.value, places=2)
def test_problem(self): """Test problem object. """ X = Variable((4, 2)) B = np.reshape(np.arange(8), (4, 2)) * 1. prox_fns = [norm1(X), sum_squares(X, b=B)] prob = Problem(prox_fns) # prob.partition(quad_funcs = [prox_fns[0], prox_fns[1]]) prob.set_automatic_frequency_split(False) prob.set_absorb(False) prob.set_implementation(Impl['halide']) prob.set_solver('admm') prob.solve() true_X = norm1(X).prox(2, B.copy()) self.assertItemsAlmostEqual(X.value, true_X, places=2) prob.solve(solver="pc") self.assertItemsAlmostEqual(X.value, true_X, places=2) prob.solve(solver="hqs", eps_rel=1e-6, rho_0=1.0, rho_scale=np.sqrt(2.0) * 2.0, rho_max=2**16, max_iters=20, max_inner_iters=500, verbose=False) self.assertItemsAlmostEqual(X.value, true_X, places=2) # CG prob = Problem(prox_fns) prob.set_lin_solver("cg") prob.solve(solver="admm") self.assertItemsAlmostEqual(X.value, true_X, places=2) prob.solve(solver="hqs", eps_rel=1e-6, rho_0=1.0, rho_scale=np.sqrt(2.0) * 2.0, rho_max=2**16, max_iters=20, max_inner_iters=500, verbose=False) self.assertItemsAlmostEqual(X.value, true_X, places=2) # Quad funcs. prob = Problem(prox_fns) prob.solve(solver="admm") self.assertItemsAlmostEqual(X.value, true_X, places=2) # Absorbing lin ops. prox_fns = [norm1(5 * mul_elemwise(B, X)), sum_squares(-2 * X, b=B)] prob = Problem(prox_fns) prob.set_absorb(True) prob.solve(solver="admm", eps_rel=1e-6, eps_abs=1e-6) cvx_X = cvx.Variable(4, 2) cost = cvx.sum_squares(-2 * cvx_X - B) + cvx.norm(5 * cvx.mul_elemwise(B, cvx_X), 1) cvx_prob = cvx.Problem(cvx.Minimize(cost)) cvx_prob.solve(solver=cvx.SCS) self.assertItemsAlmostEqual(X.value, cvx_X.value, places=2) prob.set_absorb(False) prob.solve(solver="admm", eps_rel=1e-6, eps_abs=1e-6) self.assertItemsAlmostEqual(X.value, cvx_X.value, places=2) # Constant offsets. prox_fns = [norm1(5 * mul_elemwise(B, X)), sum_squares(-2 * X - B)] prob = Problem(prox_fns) prob.solve(solver="admm", eps_rel=1e-6, eps_abs=1e-6) self.assertItemsAlmostEqual(X.value, cvx_X.value, places=2)
def test_norm1(self): """Test L1 norm prox fn. """ # No modifiers. tmp = Variable(10) fn = norm1(tmp) rho = 1 v = np.arange(10) * 1.0 - 5.0 x = fn.prox(rho, v.copy()) self.assertItemsAlmostEqual( x, np.sign(v) * np.maximum(np.abs(v) - 1.0 / rho, 0)) rho = 2 x = fn.prox(rho, v.copy()) self.assertItemsAlmostEqual( x, np.sign(v) * np.maximum(np.abs(v) - 1.0 / rho, 0)) # With modifiers. mod_fn = norm1(tmp, alpha=0.1, beta=5, c=np.ones(10) * 1.0, b=np.ones(10) * -1.0, gamma=4) rho = 2 v = np.arange(10) * 1.0 x = mod_fn.prox(rho, v.copy()) # vhat = mod_fn.beta*(v - mod_fn.c/rho)*rho/(rho+2*mod_fn.gamma) - mod_fn.b # rho_hat = rho/(mod_fn.alpha*mod_fn.beta**2) # xhat = fn.prox(rho_hat, vhat) x_var = cvx.Variable(10) cost = 0.1 * cvx.norm1(5 * x_var + np.ones(10)) + np.ones(10).T * x_var + \ 4 * cvx.sum_squares(x_var) + (rho / 2) * cvx.sum_squares(x_var - v) prob = cvx.Problem(cvx.Minimize(cost)) prob.solve() self.assertItemsAlmostEqual(x, x_var.value, places=3) # With weights. tmp = Variable(10) v = np.arange(10) * 1.0 - 5.0 fn = weighted_norm1(tmp, -v + 1) rho = 2 x = fn.prox(rho, v.copy()) self.assertItemsAlmostEqual( x, np.sign(v) * np.maximum(np.abs(v) - np.abs(-v + 1) / rho, 0))
def test_overloading(self): """Test operator overloading. """ x = Variable(1) fn = sum_squares(x, b=1) val = fn.prox(2.0, 0) self.assertItemsAlmostEqual([val], [0.5]) fn = 2 * sum_squares(x, b=1) val = fn.prox(4.0, 0) self.assertItemsAlmostEqual([val], [0.5]) fn = sum_squares(x, b=1) * 2 val = fn.prox(4.0, 0) self.assertItemsAlmostEqual([val], [0.5]) fn = sum_squares(x, b=1) / 2 val = fn.prox(1.0, 0) self.assertItemsAlmostEqual([val], [0.5]) fn1 = sum_squares(x, b=1) fn2 = norm1(x) arr = fn1 + fn2 self.assertEqual(type(arr), list) self.assertEqual(len(arr), 2) arr = arr + fn2 self.assertEqual(type(arr), list) self.assertEqual(len(arr), 3)
def test_norm1(self): """Test L1 norm prox fn. """ # No modifiers. tmp = Variable(10) fn = norm1(tmp) rho = 1 v = np.arange(10) * 1.0 - 5.0 x = fn.prox(rho, v.copy()) self.assertItemsAlmostEqual(x, np.sign(v) * np.maximum(np.abs(v) - 1.0 / rho, 0)) rho = 2 x = fn.prox(rho, v.copy()) self.assertItemsAlmostEqual(x, np.sign(v) * np.maximum(np.abs(v) - 1.0 / rho, 0)) # With modifiers. mod_fn = norm1(tmp, alpha=0.1, beta=5, c=np.ones(10) * 1.0, b=np.ones(10) * -1.0, gamma=4) rho = 2 v = np.arange(10) * 1.0 x = mod_fn.prox(rho, v.copy()) # vhat = mod_fn.beta*(v - mod_fn.c/rho)*rho/(rho+2*mod_fn.gamma) - mod_fn.b # rho_hat = rho/(mod_fn.alpha*mod_fn.beta**2) # xhat = fn.prox(rho_hat, vhat) x_var = cvx.Variable(10) cost = 0.1 * cvx.norm1(5 * x_var + np.ones(10)) + np.ones(10).T * x_var + \ 4 * cvx.sum_squares(x_var) + (rho / 2) * cvx.sum_squares(x_var - v) prob = cvx.Problem(cvx.Minimize(cost)) prob.solve() self.assertItemsAlmostEqual(x, x_var.value, places=3) # With weights. tmp = Variable(10) v = np.arange(10) * 1.0 - 5.0 fn = weighted_norm1(tmp, -v + 1) rho = 2 x = fn.prox(rho, v) self.assertItemsAlmostEqual(x, np.sign(v) * np.maximum(np.abs(v) - np.abs(-v + 1) / rho, 0))
def test_problem_no_absorb(self): """Test problem object without absorption. """ X = Variable((4, 2)) B = np.reshape(np.arange(8, dtype=np.float32), (4, 2), order='F') prox_fns = [norm1(X), sum_squares(X, b=B)] prob = Problem(prox_fns) # prob.partition(quad_funcs = [prox_fns[0], prox_fns[1]]) prob.set_automatic_frequency_split(False) prob.set_absorb(False) prob.set_solver('admm') prob.solve() cvx_X = cvx.Variable((4, 2)) cost = cvx.sum_squares(cvx_X - B) + cvx.norm(cvx_X, 1) cvx_prob = cvx.Problem(cvx.Minimize(cost)) cvx_prob.solve(solver=cvx.SCS) true_X = cvx_X.value self.assertItemsAlmostEqual(X.value, true_X, places=2) prob.solve(solver="pc") self.assertItemsAlmostEqual(X.value, true_X, places=2) prob.solve(solver="hqs", eps_rel=1e-6, rho_0=1.0, rho_scale=np.sqrt(2.0) * 2.0, rho_max=2**16, max_iters=20, max_inner_iters=500, verbose=False) self.assertItemsAlmostEqual(X.value, true_X, places=2) # CG prob = Problem(prox_fns) prob.set_lin_solver("cg") prob.solve(solver="admm") self.assertItemsAlmostEqual(X.value, true_X, places=2) prob.solve(solver="hqs", eps_rel=1e-6, rho_0=1.0, rho_scale=np.sqrt(2.0) * 2.0, rho_max=2**16, max_iters=20, max_inner_iters=500, verbose=False) self.assertItemsAlmostEqual(X.value, true_X, places=2) # Quad funcs. prob = Problem(prox_fns) prob.solve(solver="admm") self.assertItemsAlmostEqual(X.value, true_X, places=2)
def test_problem(self): """Test problem object. """ X = Variable((4, 2)) B = np.reshape(np.arange(8), (4, 2)) * 1. prox_fns = [norm1(X), sum_squares(X, b=B)] prob = Problem(prox_fns) # prob.partition(quad_funcs = [prox_fns[0], prox_fns[1]]) prob.set_automatic_frequency_split(False) prob.set_absorb(False) prob.set_implementation(Impl['halide']) prob.set_solver('admm') prob.solve() true_X = norm1(X).prox(2, B.copy()) self.assertItemsAlmostEqual(X.value, true_X, places=2) prob.solve(solver="pc") self.assertItemsAlmostEqual(X.value, true_X, places=2) prob.solve(solver="hqs", eps_rel=1e-6, rho_0=1.0, rho_scale=np.sqrt(2.0) * 2.0, rho_max=2**16, max_iters=20, max_inner_iters=500, verbose=False) self.assertItemsAlmostEqual(X.value, true_X, places=2) # CG prob = Problem(prox_fns) prob.set_lin_solver("cg") prob.solve(solver="admm") self.assertItemsAlmostEqual(X.value, true_X, places=2) prob.solve(solver="hqs", eps_rel=1e-6, rho_0=1.0, rho_scale=np.sqrt(2.0) * 2.0, rho_max=2**16, max_iters=20, max_inner_iters=500, verbose=False) self.assertItemsAlmostEqual(X.value, true_X, places=2) # Quad funcs. prob = Problem(prox_fns) prob.solve(solver="admm") self.assertItemsAlmostEqual(X.value, true_X, places=2) # Absorbing lin ops. prox_fns = [norm1(5 * mul_elemwise(B, X)), sum_squares(-2 * X, b=B)] prob = Problem(prox_fns) prob.set_absorb(True) prob.solve(solver="admm", eps_rel=1e-6, eps_abs=1e-6) cvx_X = cvx.Variable(4, 2) cost = cvx.sum_squares(-2 * cvx_X - B) + cvx.norm( 5 * cvx.mul_elemwise(B, cvx_X), 1) cvx_prob = cvx.Problem(cvx.Minimize(cost)) cvx_prob.solve(solver=cvx.SCS) self.assertItemsAlmostEqual(X.value, cvx_X.value, places=2) prob.set_absorb(False) prob.solve(solver="admm", eps_rel=1e-6, eps_abs=1e-6) self.assertItemsAlmostEqual(X.value, cvx_X.value, places=2) # Constant offsets. prox_fns = [norm1(5 * mul_elemwise(B, X)), sum_squares(-2 * X - B)] prob = Problem(prox_fns) prob.solve(solver="admm", eps_rel=1e-6, eps_abs=1e-6) self.assertItemsAlmostEqual(X.value, cvx_X.value, places=2)
def test_absorb_lin_op(self): """Test absorb lin op operator. """ # norm1. tmp = Variable(10) v = np.arange(10) * 1.0 - 5.0 fn = norm1(mul_elemwise(-v, tmp), alpha=5.) rho = 2 new_prox = absorb_lin_op(fn)[0] x = new_prox.prox(rho, v.copy()) self.assertItemsAlmostEqual(x, np.sign(v) * np.maximum(np.abs(v) - 5. * np.abs(v) / rho, 0)) fn = norm1(mul_elemwise(-v, mul_elemwise(2 * v, tmp)), alpha=5.) rho = 2 new_prox = absorb_lin_op(fn)[0] x = new_prox.prox(rho, v.copy()) self.assertItemsAlmostEqual(x, np.sign(v) * np.maximum(np.abs(v) - 5. * np.abs(v) / rho, 0)) new_prox = absorb_lin_op(new_prox)[0] x = new_prox.prox(rho, v.copy()) new_v = 2 * v * v self.assertItemsAlmostEqual(x, np.sign(new_v) * np.maximum(np.abs(new_v) - 5. * np.abs(new_v) / rho, 0)) # nonneg. tmp = Variable(10) v = np.arange(10) * 1.0 - 5.0 fn = nonneg(mul_elemwise(-v, tmp), alpha=5.) rho = 2 new_prox = absorb_lin_op(fn)[0] x = new_prox.prox(rho, v.copy()) self.assertItemsAlmostEqual(x, fn.prox(rho, -np.abs(v))) # sum_squares. tmp = Variable(10) v = np.arange(10) * 1.0 - 5.0 alpha = 5. val = np.arange(10) fn = sum_squares(mul_elemwise(-v, tmp), alpha=alpha, c=val) rho = 2 new_prox = absorb_lin_op(fn)[0] x = new_prox.prox(rho, v.copy()) cvx_x = cvx.Variable(10) prob = cvx.Problem(cvx.Minimize(cvx.sum_squares(cvx_x - v) * (rho / 2) + 5 * cvx.sum_squares(cvx.mul_elemwise(-v, cvx_x)) + (val * -v).T * cvx_x )) prob.solve() self.assertItemsAlmostEqual(x, cvx_x.value, places=3) # Test scale. tmp = Variable(10) v = np.arange(10) * 1.0 - 5.0 fn = norm1(10 * tmp) rho = 2 new_prox = absorb_lin_op(fn)[0] x = new_prox.prox(rho, v.copy()) cvx_x = cvx.Variable(10) prob = cvx.Problem(cvx.Minimize(cvx.sum_squares(cvx_x - v) + cvx.norm(10 * cvx_x, 1))) prob.solve() self.assertItemsAlmostEqual(x, cvx_x.value, places=3) val = np.arange(10) fn = norm1(10 * tmp, c=val, b=val, gamma=0.01) rho = 2 new_prox = absorb_lin_op(fn)[0] x = new_prox.prox(rho, v.copy()) cvx_x = cvx.Variable(10) prob = cvx.Problem(cvx.Minimize(cvx.sum_squares(cvx_x - v) + cvx.norm(10 * cvx_x - val, 1) + 10 * val.T * \ cvx_x + cvx.sum_squares(cvx_x) )) prob.solve() self.assertItemsAlmostEqual(x, cvx_x.value, places=2) # sum_entries tmp = Variable(10) v = np.arange(10) * 1.0 - 5.0 fn = sum_entries(sum([10 * tmp, mul_elemwise(v, tmp)])) funcs = absorb.absorb_all_lin_ops([fn]) c = __builtins__['sum']([func.c for func in funcs]) self.assertItemsAlmostEqual(c, v + 10, places=3)
def test_absorb_lin_op(self): """Test absorb lin op operator. """ # norm1. tmp = Variable(10) v = np.arange(10) * 1.0 - 5.0 fn = norm1(mul_elemwise(-v, tmp), alpha=5.) rho = 2 new_prox = absorb_lin_op(fn)[0] x = new_prox.prox(rho, v.copy()) self.assertItemsAlmostEqual( x, np.sign(v) * np.maximum(np.abs(v) - 5. * np.abs(v) / rho, 0)) fn = norm1(mul_elemwise(-v, mul_elemwise(2 * v, tmp)), alpha=5.) rho = 2 new_prox = absorb_lin_op(fn)[0] x = new_prox.prox(rho, v.copy()) self.assertItemsAlmostEqual( x, np.sign(v) * np.maximum(np.abs(v) - 5. * np.abs(v) / rho, 0)) new_prox = absorb_lin_op(new_prox)[0] x = new_prox.prox(rho, v.copy()) new_v = 2 * v * v self.assertItemsAlmostEqual( x, np.sign(new_v) * np.maximum(np.abs(new_v) - 5. * np.abs(new_v) / rho, 0)) # nonneg. tmp = Variable(10) v = np.arange(10) * 1.0 - 5.0 fn = nonneg(mul_elemwise(-v, tmp), alpha=5.) rho = 2 new_prox = absorb_lin_op(fn)[0] x = new_prox.prox(rho, v.copy()) self.assertItemsAlmostEqual(x, fn.prox(rho, -np.abs(v))) # sum_squares. tmp = Variable(10) v = np.arange(10) * 1.0 - 5.0 alpha = 5. val = np.arange(10) fn = sum_squares(mul_elemwise(-v, tmp), alpha=alpha, c=val) rho = 2 new_prox = absorb_lin_op(fn)[0] x = new_prox.prox(rho, v.copy()) cvx_x = cvx.Variable(10) prob = cvx.Problem( cvx.Minimize( cvx.sum_squares(cvx_x - v) * (rho / 2) + 5 * cvx.sum_squares(cvx.mul_elemwise(-v, cvx_x)) + (val * -v).T * cvx_x)) prob.solve() self.assertItemsAlmostEqual(x, cvx_x.value, places=3) # Test scale. tmp = Variable(10) v = np.arange(10) * 1.0 - 5.0 fn = norm1(10 * tmp) rho = 2 new_prox = absorb_lin_op(fn)[0] x = new_prox.prox(rho, v.copy()) cvx_x = cvx.Variable(10) prob = cvx.Problem( cvx.Minimize(cvx.sum_squares(cvx_x - v) + cvx.norm(10 * cvx_x, 1))) prob.solve() self.assertItemsAlmostEqual(x, cvx_x.value, places=3) val = np.arange(10) fn = norm1(10 * tmp, c=val, b=val, gamma=0.01) rho = 2 new_prox = absorb_lin_op(fn)[0] x = new_prox.prox(rho, v.copy()) cvx_x = cvx.Variable(10) prob = cvx.Problem(cvx.Minimize(cvx.sum_squares(cvx_x - v) + cvx.norm(10 * cvx_x - val, 1) + 10 * val.T * \ cvx_x + cvx.sum_squares(cvx_x) )) prob.solve() self.assertItemsAlmostEqual(x, cvx_x.value, places=2) # sum_entries tmp = Variable(10) v = np.arange(10) * 1.0 - 5.0 fn = sum_entries(sum([10 * tmp, mul_elemwise(v, tmp)])) funcs = absorb.absorb_all_lin_ops([fn]) c = __builtins__['sum']([func.c for func in funcs]) self.assertItemsAlmostEqual(c, v + 10, places=3)