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_sum(self): # Forward. x = Variable((2, 3)) y = Variable((2, 3)) fn = sum([x, y]) x_val = np.reshape(np.arange(6) * 1.0, x.shape) y_val = np.reshape(np.arange(6) * 1.0 - 5, x.shape) out = np.zeros(fn.shape) fn.forward([x_val, y_val], [out]) self.assertItemsAlmostEqual(out, 2 * np.arange(6) - 5) # Adjoint. x_val = np.reshape(np.arange(6) * 1.0, x.shape) out = [np.zeros(fn.shape), np.zeros(fn.shape)] fn.adjoint([x_val], out) for arr in out: self.assertItemsAlmostEqual(arr, x_val) # Constant args. x = Variable((2, 3)) y = Variable((2, 3)) x_val = np.reshape(np.arange(6) * 1.0, x.shape) y_val = np.reshape(np.arange(6) * 1.0 - 5, x.shape) fn = sum([x_val, y_val]) self.assertItemsAlmostEqual(fn.value, 2 * np.arange(6) - 5) # Diagonal form. x = Variable(5) term = mul_elemwise(np.arange(5) - 3, x) fn = sum([term, x]) assert not fn.is_diag(freq=True) assert fn.is_diag(freq=False) self.assertItemsAlmostEqual( fn.get_diag(freq=False)[x], np.arange(5) - 3 + np.ones(5))
def test_mul_elemwise(self): """Test mul_elemwise lin op. """ # Forward. var = Variable((2, 5)) W = np.arange(10) W = np.reshape(W, (2, 5)) fn = mul_elemwise(W, var) x = W.copy() out = np.zeros(x.shape) fn.forward([x], [out]) self.assertItemsAlmostEqual(out, W * W) # Adjoint. x = W.copy() out = np.zeros(x.shape) fn.adjoint([x], [out]) self.assertItemsAlmostEqual(out, W * W) # Diagonal form. x = Variable(5) fn = mul_elemwise(np.arange(5) - 3, x) assert not fn.is_diag(freq=True) assert fn.is_diag(freq=False) self.assertItemsAlmostEqual( fn.get_diag(freq=False)[x], np.arange(5) - 3)
def test_variable(self): """Test Variable""" var = Variable(3) self.assertEqual(var.shape, (3, )) var = Variable((3, )) self.assertEqual(var.shape, (3, )) var = Variable((3, 2)) self.assertEqual(var.shape, (3, 2)) var = Variable([3, 2]) self.assertEqual(var.shape, (3, 2))
def test_conv(self): """Test convolution lin op. """ # Forward. var = Variable((2, 3)) kernel = np.array([[1, 2, 3], [4, 5, 6]]) # 2x3 fn = conv(kernel, var) x = np.arange(6) * 1.0 x = np.reshape(x, (2, 3)) out = np.zeros(fn.shape) fn.forward([x], [out]) ks = np.array(kernel.shape) cc = np.floor((ks - 1) / 2.0).astype(np.int) # Center coordinate y = np.zeros((2, 3)) for i in range(2): for j in range(3): for s in range(2): for t in range(3): y[i, j] += kernel[ks[0] - 1 - s, ks[1] - 1 - t] * \ x[(s + i - cc[0]) % 2, (t + j - cc[1]) % 3] # For loop same as convolve # y = ndimage.convolve(x, kernel, mode='wrap') self.assertItemsAlmostEqual(out, y) # Adjoint.# x = np.arange(6) * 1.0 x = np.reshape(x, (2, 3)) out = np.zeros(var.shape) fn.adjoint([x], [out]) y = np.zeros((2, 3)) for i in range(2): for j in range(3): for s in range(2): for t in range(3): y[i, j] += kernel[s, t] * x[(s + i - (ks[0] - 1 - cc[0])) % 2, (t + j - (ks[1] - 1 - cc[1])) % 3] # For loop same as correlate # y = ndimage.correlate(x, kernel, mode='wrap') self.assertItemsAlmostEqual(out, y) # Diagonal form. x = Variable(5) kernel = np.arange(5) fn = conv(kernel, x) assert fn.is_diag(freq=True) assert not fn.is_diag(freq=False) forward_kernel = psf2otf(kernel, (5, ), 1) self.assertItemsAlmostEqual(fn.get_diag(freq=True)[x], forward_kernel)
def test_multiple_vars(self): """Test problems with multiple variables.""" x = Variable(3) y = Variable(6) rhs = np.array([1, 2, 3]) prob = Problem( [sum_squares(x - rhs), sum_squares(subsample(y, [2]) - x)]) prob.solve(solver="admm", eps_rel=1e-6, eps_abs=1e-6) self.assertItemsAlmostEqual(x.value, [1, 2, 3], places=3) self.assertItemsAlmostEqual(y.value, [1, 0, 2, 0, 3, 0], places=3)
def vstack(self): """Test vstack operator. """ # diagonals. x = Variable(1) y = Variable(1) fn = vstack([x, y]) assert fn.is_gram_diag(freq=False) assert fn.is_gram_diag(freq=True) fn = vstack([fn]) assert fn.is_gram_diag(freq=False) assert fn.is_gram_diag(freq=True)
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_diagonalization(self): """Test automatic diagonalization. """ var = Variable((2, 5)) K = np.array([[-1, 1]]) expr = 2 * vstack([conv(K, var), conv(K, var)]) assert expr.is_gram_diag(freq=True)
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_combo(self): """Test subsampling followed by convolution. """ # Forward. var = Variable((2, 3)) kernel = np.array([[1, 2, 3]]) # 2x3 fn = vstack([conv(kernel, subsample(var, (2, 1)))]) fn = CompGraph(fn) x = np.arange(6) * 1.0 x = np.reshape(x, (2, 3)) out = np.zeros(fn.output_size) fn.forward(x.flatten(), out) y = np.zeros((1, 3)) xsub = x[::2, ::1] y = ndimage.convolve(xsub, kernel, mode='wrap') self.assertItemsAlmostEqual(np.reshape(out, y.shape), y) # Adjoint. x = np.arange(3) * 1.0 x = np.reshape(x, (1, 3)) out = np.zeros(var.size) fn.adjoint(x.flatten(), out) y = ndimage.correlate(x, kernel, mode='wrap') y2 = np.zeros((2, 3)) y2[::2, :] = y self.assertItemsAlmostEqual(np.reshape(out, y2.shape), y2) out = np.zeros(var.size) fn.adjoint(x.flatten(), out) self.assertItemsAlmostEqual(np.reshape(out, y2.shape), y2)
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_sum_entries(self): """Sum of entries of lin op. """ tmp = Variable(10) v = np.arange(10) * 1.0 - 5.0 fn = sum_entries(tmp) x = fn.prox(1.0, v.copy()) self.assertItemsAlmostEqual(x, v - 1)
def test_single_func(self): """Test problems with only a single function to minimize. """ X = Variable((4, 2)) B = np.reshape(np.arange(8), (4, 2)) * 1. prox_fns = [sum_squares(X - B)] prob = Problem(prox_fns[0]) prob.solve(solver="admm", eps_rel=1e-6, eps_abs=1e-6) self.assertItemsAlmostEqual(X.value, B, places=2)
def test_nonneg(self): """Test I(x >= 0) prox fn. """ # No modifiers. tmp = Variable(10) fn = nonneg(tmp) rho = 1 v = np.arange(10) * 1.0 - 5.0 x = fn.prox(rho, v.copy()) self.assertItemsAlmostEqual(x, np.maximum(v, 0)) rho = 2 x = fn.prox(rho, v.copy()) self.assertItemsAlmostEqual(x, np.maximum(v, 0)) # With modifiers. mod_fn = nonneg(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 * np.sqrt(np.abs(mod_fn.beta))) xhat = fn.prox(rho_hat, vhat) self.assertItemsAlmostEqual(x, (xhat + mod_fn.b) / mod_fn.beta) # With weights. tmp = Variable(10) v = np.arange(10) * 1.0 - 5.0 fn = weighted_nonneg(tmp, -v - 4) rho = 2 new_v = v.copy() idxs = (-v - 4 != 0) new_v[idxs] = np.maximum((-v - 4)[idxs] * v[idxs], 0.) / (-v - 4)[idxs] x = fn.prox(rho, v.copy()) self.assertItemsAlmostEqual(x, new_v)
def test_const_val(self): """Test obtaining the constant offset. """ x = Variable(10) b = np.arange(10) expr = x - b self.assertItemsAlmostEqual(-b, expr.get_offset()) fn = sum_squares(expr) new_fn = absorb_offset(fn) self.assertItemsAlmostEqual(b, new_fn.b)
def test_black_box(self): """Test custom linear operators. """ scale = 2 def op(input, output): output[:] = 2 * input my_op = LinOpFactory((2, 2), (2, 2), op, op, scale) x = Variable((2, 2)) expr = my_op(x) val = np.reshape(np.arange(4), (2, 2)) x.value = val self.assertItemsAlmostEqual(expr.value, 2 * val) output = np.zeros((2, 2)) expr.forward([val], [output]) self.assertItemsAlmostEqual(output, 2 * val) expr.adjoint([val], [output]) self.assertItemsAlmostEqual(output, 2 * val)
def test_diff_fn(self): """Test generic differentiable function operator. """ # Least squares. tmp = Variable(10) fn = diff_fn(tmp, lambda x: np.square(x).sum(), lambda x: 2 * x) rho = 1 v = np.arange(10) * 1.0 - 5.0 x = fn.prox(rho, v.copy()) self.assertItemsAlmostEqual(x, v / (2 + rho)) # -log n = 5 tmp = Variable(n) fn = diff_fn(tmp, lambda x: -np.log(x).sum(), lambda x: -1.0 / x) rho = 2 v = np.arange(n) * 2.0 + 1 x = fn.prox(rho, v.copy()) val = (v + np.sqrt(v**2 + 4 / rho)) / 2 self.assertItemsAlmostEqual(x, val)
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_subsample(self): """Test subsample lin op. """ # Forward. var = Variable((10, 5)) fn = subsample(var, (2, 1)) x = np.arange(50) * 1.0 x = np.reshape(x, (10, 5)) out = np.zeros(fn.shape) fn.forward([x], [out]) self.assertItemsAlmostEqual(out, x[0::2, :]) # Adjoint. x = np.arange(25) * 1.0 x = np.reshape(x, (5, 5)) out = np.zeros(var.shape) fn.adjoint([x], [out]) zeroed_x = np.zeros((10, 5)) * 1.0 zeroed_x[0::2, :] = x self.assertItemsAlmostEqual(out, zeroed_x) # Constant arg. val = np.arange(50) * 1.0 val = np.reshape(val, (10, 5)) fn = subsample(val, (2, 1)) self.assertItemsAlmostEqual(fn.value, val[0::2, :]) # Diagonal form. var = Variable((5, 1)) fn = subsample(var, (2, 1)) assert not fn.is_gram_diag(freq=True) assert fn.is_gram_diag(freq=False) self.assertItemsAlmostEqual( fn.get_diag(freq=False)[var], [1, 0, 1, 0, 1]) # 1D x = Variable(5) expr = subsample(x, 2) self.assertEqual(expr.shape, (3, ))
def test_merge_all(self): """Test function to merge all prox operators possible. """ # merge all x = Variable(10) lin_op = grad(x) fns = [sum_squares(lin_op), sum_entries(lin_op), nonneg(lin_op)] merged = merge_all(fns) assert len(merged) == 1 v = np.reshape(np.arange(10) * 1.0 - 5.0, (10, 1)) prox_val1 = merged[0].prox(1.0, v.copy()) tmp = nonneg(lin_op, c=np.ones((10, 1)), gamma=1.0) prox_val2 = tmp.prox(1.0, v.copy()) self.assertItemsAlmostEqual(prox_val1, prox_val2)
def test_sum_squares(self): """Test sum squares prox fn. """ # No modifiers. tmp = Variable(10) fn = sum_squares(tmp) rho = 1 v = np.arange(10) * 1.0 x = fn.prox(rho, v.copy()) self.assertItemsAlmostEqual(x, v * rho / (2 + rho)) rho = 2 x = fn.prox(rho, v.copy()) self.assertItemsAlmostEqual(x, v * rho / (2 + rho)) # With modifiers. mod_fn = sum_squares(tmp, alpha=2, beta=-1, c=np.ones(10) * 1.0, b=np.ones(10) * 1.0, gamma=1) 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*np.sqrt(np.abs(mod_fn.beta))) # xhat = fn.prox(rho_hat, vhat) x_var = cvx.Variable(10) cost = 2 * cvx.sum_squares(-x_var - np.ones(10)) + \ np.ones(10).T * x_var + 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)
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_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)
hl = Halide('prox_L1') tic() hl.prox_L1(v, theta, output) print('Running Halide (first) took: {0:.1f}ms'.format(toc())) tic() hl.prox_L1(v, theta, output) print('Running Halide (second) took: {0:.1f}ms'.format(toc())) # Reference #output_ref = np.maximum( 0.0, v - theta ) - np.maximum( 0.0, -v - theta ) # No modifiers. tmp = Variable(v.shape) tic() fn = norm1(tmp, implem='halide') # group over all but first two dims print('Prox Norm1 running took: {0:.1f}ms'.format(toc())) output_ref = fn.prox(1.0 / theta, v.copy()) # Error print('Maximum error L1 {0}'.format(np.amax(np.abs(output_ref - output)))) ############################################################################ # Test the Iso L1 prox ############################################################################ # Compute gradient for fun f = np_img if len(np_img.shape) == 2:
def test_op_overloading(self): """Test operator overloading. """ # Multiplying by a scalar. # Forward. var = Variable((2, 5)) W = np.arange(10) W = np.reshape(W, (2, 5)) fn = -2 * mul_elemwise(W, var) fn = CompGraph(fn) x = W.copy() out = np.zeros(x.shape) fn.forward(x.flatten(), out) self.assertItemsAlmostEqual(out, -2 * W * W) # Adjoint. x = W.copy() out = np.zeros(x.shape).flatten() fn.adjoint(x, out) self.assertItemsAlmostEqual(out, -2 * W * W) # Forward. var = Variable((2, 5)) W = np.arange(10) W = np.reshape(W, (2, 5)) fn = mul_elemwise(W, var) * 0.5 fn = CompGraph(fn) x = W.copy() out = np.zeros(x.shape) fn.forward(x.flatten(), out) self.assertItemsAlmostEqual(out, W * W / 2.) # Adjoint. x = W.copy() out = np.zeros(x.shape).flatten() fn.adjoint(x, out) self.assertItemsAlmostEqual(out, W * W / 2.) # Dividing by a scalar. # Forward. var = Variable((2, 5)) W = np.arange(10) W = np.reshape(W, (2, 5)) fn = mul_elemwise(W, var) / 2 fn = CompGraph(fn) x = W.copy() out = np.zeros(x.shape) fn.forward(x, out) self.assertItemsAlmostEqual(out, W * W / 2.) # Adding lin ops. # Forward. x = Variable((2, 5)) W = np.arange(10) W = np.reshape(W, (2, 5)) fn = mul_elemwise(W, x) fn = fn + x + x self.assertEqual(len(fn.input_nodes), 3) fn = CompGraph(fn) x = W.copy() out = np.zeros(fn.shape) fn.forward(x, out) self.assertItemsAlmostEqual(out, W * W + 2 * W) # Adjoint. x = W.copy() out = np.zeros(x.shape).flatten() fn.adjoint(x, out) self.assertItemsAlmostEqual(out, W * W + 2 * W) # Adding in a constant. # CompGraph should ignore the constant. x = Variable((2, 5)) W = np.arange(10) W = np.reshape(W, (2, 5)) fn = mul_elemwise(W, x) fn = fn + x + W self.assertEqual(len(fn.input_nodes), 3) fn = CompGraph(fn) x = W.copy() out = np.zeros(fn.shape) fn.forward(x, out) self.assertItemsAlmostEqual(out, W * W + W) # Subtracting lin ops. # Forward. x = Variable((2, 5)) W = np.arange(10) W = np.reshape(W, (2, 5)) fn = -mul_elemwise(W, x) fn = x + x - fn self.assertEqual(len(fn.input_nodes), 3) fn = CompGraph(fn) x = W.copy() out = np.zeros(fn.shape) fn.forward(x, out) self.assertItemsAlmostEqual(out, W * W + 2 * W) # Adjoint. x = W.copy() out = np.zeros(x.shape).flatten() fn.adjoint(x, out) self.assertItemsAlmostEqual(out, W * W + 2 * W)