def setUp(self, *args, **kwargs): M, N, K = 3, 4, 5 self.ig = ImageGeometry(M, N, K) self.x = self.ig.allocate('random', seed=1) self.b = self.ig.allocate('random', seed=2) self.eta = self.ig.allocate(0.1) self.operator = IdentityOperator(self.ig) scalar = 0.25 self.f1 = L2NormSquared() self.f2 = L1Norm() self.f3 = scalar * L2NormSquared() self.f4 = scalar * L1Norm() self.f5 = scalar * L2NormSquared(b=self.b) self.f6 = scalar * L1Norm(b=self.b) self.f7 = ZeroFunction() self.f8 = 5 * ConstantFunction(10) self.f9 = LeastSquares(self.operator, self.b, c=scalar) self.f10 = 0.5 * KullbackLeibler(b=self.b, eta=self.eta) self.f11 = KullbackLeibler(b=self.b, eta=self.eta) self.f12 = 10 self.list1 = [self.f1, self.f2, self.f3, self.f4, self.f5, \ self.f6, self.f7, self.f8, self.f9, self.f10, self.f11, self.f12]
def test_PDHG_strongly_convex_gamma_g(self): ig = ImageGeometry(3,3) data = ig.allocate('random') f = L2NormSquared(b=data) g = L2NormSquared() operator = IdentityOperator(ig) # sigma, tau sigma = 1.0 tau = 1.0 pdhg = PDHG(f=f, g=g, operator=operator, sigma = sigma, tau=tau, max_iteration=5, gamma_g=0.5) pdhg.run(1, verbose=0) self.assertAlmostEquals(pdhg.theta, 1.0/ np.sqrt(1 + 2 * pdhg.gamma_g * tau)) self.assertAlmostEquals(pdhg.tau, tau * pdhg.theta) self.assertAlmostEquals(pdhg.sigma, sigma / pdhg.theta) pdhg.run(4, verbose=0) self.assertNotEqual(pdhg.sigma, sigma) self.assertNotEqual(pdhg.tau, tau) # check negative strongly convex constant with self.assertRaises(ValueError): pdhg = PDHG(f=f, g=g, operator=operator, sigma = sigma, tau=tau, max_iteration=5, gamma_g=-0.5) # check strongly convex constant not a number with self.assertRaises(ValueError): pdhg = PDHG(f=f, g=g, operator=operator, sigma = sigma, tau=tau, max_iteration=5, gamma_g="-0.5")
def test_Norm2sq_as_OperatorCompositionFunction(self): print('Test for OperatorCompositionFunction') M, N = 50, 50 ig = ImageGeometry(voxel_num_x=M, voxel_num_y=N) #numpy.random.seed(1) b = ig.allocate('random', seed=1) print('Check call with IdentityOperator operator... OK\n') operator = 3 * IdentityOperator(ig) u = ig.allocate('random', seed=50) f = 0.5 * L2NormSquared(b=b) func1 = OperatorCompositionFunction(f, operator) func2 = LeastSquares(operator, b, 0.5) print("f.L {}".format(f.L)) print("0.5*f.L {}".format((0.5 * f).L)) print("type func1 {}".format(type(func1))) print("func1.L {}".format(func1.L)) print("func2.L {}".format(func2.L)) print("operator.norm() {}".format(operator.norm())) numpy.testing.assert_almost_equal(func1(u), func2(u)) print('Check gradient with IdentityOperator operator... OK\n') tmp1 = ig.allocate() tmp2 = ig.allocate() res_gradient1 = func1.gradient(u) res_gradient2 = func2.gradient(u) func1.gradient(u, out=tmp1) func2.gradient(u, out=tmp2) self.assertNumpyArrayAlmostEqual(res_gradient1.as_array(), res_gradient2.as_array()) self.assertNumpyArrayAlmostEqual(tmp1.as_array(), tmp2.as_array()) print('Check call with MatrixOperator... OK\n') mat = np.random.randn(M, N) operator = MatrixOperator(mat) vg = VectorGeometry(N) b = vg.allocate('random') u = vg.allocate('random') func1 = OperatorCompositionFunction(0.5 * L2NormSquared(b=b), operator) func2 = LeastSquares(operator, b, 0.5) self.assertNumpyArrayAlmostEqual(func1(u), func2(u)) numpy.testing.assert_almost_equal(func1.L, func2.L)
def test_PDHG_strongly_convex_both_fconj_and_g(self): ig = ImageGeometry(3,3) data = ig.allocate('random') f = L2NormSquared(b=data) g = L2NormSquared() operator = IdentityOperator(ig) try: pdhg = PDHG(f=f, g=g, operator=operator, max_iteration=10, gamma_g = 0.5, gamma_fconj=0.5) pdhg.run(verbose=0) except ValueError as err: print(err)
def test_Function(self): numpy.random.seed(10) N = 3 ig = ImageGeometry(N, N) ag = ig op1 = GradientOperator(ig) op2 = IdentityOperator(ig, ag) # Form Composite Operator operator = BlockOperator(op1, op2, shape=(2, 1)) # Create functions noisy_data = ag.allocate(ImageGeometry.RANDOM) d = ag.allocate(ImageGeometry.RANDOM) alpha = 0.5 # scaled function g = alpha * L2NormSquared(b=noisy_data) # Compare call of g a2 = alpha * (d - noisy_data).power(2).sum() #print(a2, g(d)) self.assertEqual(a2, g(d)) # Compare convex conjugate of g a3 = 0.5 * d.squared_norm() + d.dot(noisy_data) self.assertAlmostEqual(a3, g.convex_conjugate(d), places=7)
def setup(data, dnoise): if dnoise == 's&p': n1 = applynoise.saltnpepper(data, salt_vs_pepper=0.9, amount=0.2, seed=10) elif dnoise == 'poisson': scale = 5 n1 = applynoise.poisson(data.as_array() / scale, seed=10) * scale elif dnoise == 'gaussian': n1 = applynoise.gaussian(data.as_array(), seed=10) else: raise ValueError('Unsupported Noise ', noise) noisy_data = ig.allocate() noisy_data.fill(n1) # Regularisation Parameter depending on the noise distribution if dnoise == 's&p': alpha = 0.8 elif dnoise == 'poisson': alpha = 1 elif dnoise == 'gaussian': alpha = .3 # fidelity if dnoise == 's&p': g = L1Norm(b=noisy_data) elif dnoise == 'poisson': g = KullbackLeibler(b=noisy_data) elif dnoise == 'gaussian': g = 0.5 * L2NormSquared(b=noisy_data) return noisy_data, alpha, g
def test_cil_vs_cvxpy_totalvariation_anisotropic(self): # solution u_cvx = cvxpy.Variable(self.data.shape) # regularisation parameter alpha = 0.1 # fidelity term fidelity = 0.5 * cvxpy.sum_squares(u_cvx - self.data.array) regulariser = alpha * self.tv_cvxpy_regulariser(u_cvx, isotropic=False) # objective obj = cvxpy.Minimize( regulariser + fidelity) prob = cvxpy.Problem(obj, constraints = []) # Choose solver ( SCS, MOSEK(license needed) ) tv_cvxpy = prob.solve(verbose = True, solver = cvxpy.SCS) # use TotalVariation from CIL (with Fast Gradient Projection algorithm) TV = (alpha/3.0)*TotalVariation(max_iteration=200, isotropic=False) tv_cil = TV.proximal(self.data, tau=3.0) # compare solution np.testing.assert_allclose(tv_cil.array, u_cvx.value, atol=1e-3) # compare objectives f = 0.5*L2NormSquared(b=self.data) cil_objective = f(tv_cil) + TV(tv_cil)*(3) np.testing.assert_allclose(cil_objective, obj.value, atol=1e-3)
def setUp(self): ig = ImageGeometry(2, 3, 2) data = ig.allocate(1, dtype=np.float32) noisy_data = data + 1 # TV regularisation parameter self.alpha = 1 self.fidelities = [ 0.5 * L2NormSquared(b=noisy_data), L1Norm(b=noisy_data), KullbackLeibler(b=noisy_data, use_numba=False) ] F = self.alpha * MixedL21Norm() K = GradientOperator(ig) # Compute operator Norm normK = K.norm() # Primal & dual stepsizes self.sigma = 1. / normK self.tau = 1. / normK self.F = F self.K = K
def test_FISTA(self): print("Test FISTA") ig = ImageGeometry(127, 139, 149) initial = ig.allocate() b = initial.copy() # fill with random numbers b.fill(numpy.random.random(initial.shape)) initial = ig.allocate(ImageGeometry.RANDOM) identity = IdentityOperator(ig) #### it seems FISTA does not work with Nowm2Sq # norm2sq = Norm2Sq(identity, b) # norm2sq.L = 2 * norm2sq.c * identity.norm()**2 norm2sq = OperatorCompositionFunction(L2NormSquared(b=b), identity) opt = {'tol': 1e-4, 'memopt': False} if debug_print: print("initial objective", norm2sq(initial)) alg = FISTA(initial=initial, f=norm2sq, g=ZeroFunction()) alg.max_iteration = 2 alg.run(20, verbose=0) self.assertNumpyArrayAlmostEqual(alg.x.as_array(), b.as_array()) alg = FISTA(initial=initial, f=norm2sq, g=ZeroFunction(), max_iteration=2, update_objective_interval=2) self.assertTrue(alg.max_iteration == 2) self.assertTrue(alg.update_objective_interval == 2) alg.run(20, verbose=0) self.assertNumpyArrayAlmostEqual(alg.x.as_array(), b.as_array())
def test_FISTA_Denoising(self): if debug_print: print("FISTA Denoising Poisson Noise Tikhonov") # adapted from demo FISTA_Tikhonov_Poisson_Denoising.py in CIL-Demos repository data = dataexample.SHAPES.get() ig = data.geometry ag = ig N = 300 # Create Noisy data with Poisson noise scale = 5 noisy_data = applynoise.poisson(data / scale, seed=10) * scale # Regularisation Parameter alpha = 10 # Setup and run the FISTA algorithm operator = GradientOperator(ig) fid = KullbackLeibler(b=noisy_data) reg = OperatorCompositionFunction(alpha * L2NormSquared(), operator) initial = ig.allocate() fista = FISTA(initial=initial, f=reg, g=fid) fista.max_iteration = 3000 fista.update_objective_interval = 500 fista.run(verbose=0) rmse = (fista.get_output() - data).norm() / data.as_array().size if debug_print: print("RMSE", rmse) self.assertLess(rmse, 4.2e-4)
def test_PDHG_strongly_convex_gamma_fcong(self): ig = ImageGeometry(3,3) data = ig.allocate('random') f = L2NormSquared(b=data) g = L2NormSquared() operator = IdentityOperator(ig) # sigma, tau sigma = 1.0 tau = 1.0 pdhg = PDHG(f=f, g=g, operator=operator, sigma = sigma, tau=tau, max_iteration=5, gamma_fconj=0.5) pdhg.run(1, verbose=0) self.assertEquals(pdhg.theta, 1.0/ np.sqrt(1 + 2 * pdhg.gamma_fconj * sigma)) self.assertEquals(pdhg.tau, tau / pdhg.theta) self.assertEquals(pdhg.sigma, sigma * pdhg.theta) pdhg.run(4, verbose=0) self.assertNotEqual(pdhg.sigma, sigma) self.assertNotEqual(pdhg.tau, tau) # check negative strongly convex constant try: pdhg = PDHG(f=f, g=g, operator=operator, sigma = sigma, tau=tau, max_iteration=5, gamma_fconj=-0.5) except ValueError as ve: print(ve) # check strongly convex constant not a number try: pdhg = PDHG(f=f, g=g, operator=operator, sigma = sigma, tau=tau, max_iteration=5, gamma_fconj="-0.5") except ValueError as ve: print(ve)
def test_exception_initial_GD(self): print("Test FISTA") ig = ImageGeometry(127, 139, 149) initial = ig.allocate() b = initial.copy() # fill with random numbers b.fill(numpy.random.random(initial.shape)) initial = ig.allocate(ImageGeometry.RANDOM) identity = IdentityOperator(ig) norm2sq = OperatorCompositionFunction(L2NormSquared(b=b), identity) opt = {'tol': 1e-4, 'memopt': False} print("initial objective", norm2sq(initial)) try: alg = GD(initial=initial, objective_function=norm2sq, x_init=initial) assert False except ValueError as ve: assert True
def set_up_TV_regularisation(image_geometry: ImageGeometry, acquisition_data: AcquisitionData, alpha: float): # Forward operator A2d = ProjectionOperator(image_geometry, acquisition_data.geometry, 'gpu') # Set up TV regularisation # Define Gradient Operator and BlockOperator Grad = GradientOperator(image_geometry) K = BlockOperator(alpha * Grad, A2d) # Define BlockFunction F using the MixedL21Norm() and the L2NormSquared() # alpha = 1.0 # f1 = alpha * MixedL21Norm() f1 = MixedL21Norm() # f2 = 0.5 * L2NormSquared(b=ad2d) f2 = L2NormSquared(b=acquisition_data) # F = BlockFunction(f1,f2) # Define Function G simply as zero G = ZeroFunction() return (K, f1, f2, G)
def test_SumFunctionScalar(self): numpy.random.seed(1) M, N, K = 3,4,5 ig = ImageGeometry(M, N, K) tmp = ig.allocate('random') b = ig.allocate('random') scalar = 0.25 f1 = scalar * L2NormSquared(b=b) f2 = 5 f = f1 + f2 print(f) g = f2 + f1 print(g) tau = 0.03 # check call method res1 = f(tmp) res2 = f1(tmp) + f2 self.assertAlmostEqual(res1, res2) # check gradient res1 = f.gradient(tmp) res2 = f1.gradient(tmp) self.assertNumpyArrayAlmostEqual(res1.as_array(), res2.as_array()) # check gradient with out out1 = tmp*0 out2 = tmp*0 f.gradient(tmp, out=out1) f1.gradient(tmp, out=out2) self.assertNumpyArrayAlmostEqual(out1.as_array(), out2.as_array()) res1 = f.proximal(tmp, tau) res2 = f1.proximal(tmp, tau) # proximal of sum of function with scalar = proximal of function self.assertNumpyArrayAlmostEqual(res1.as_array(), res2.as_array()) # proximal with out of sum of function with scalar = proximal of function res1_out = ig.allocate() res2_out = ig.allocate() f.proximal(tmp, tau, out = res1_out) f1.proximal(tmp, tau, out = res2_out) self.assertNumpyArrayAlmostEqual(res1_out.as_array(), res2_out.as_array()) res1 = f.proximal_conjugate(tmp, tau) res2 = f1.proximal_conjugate(tmp, tau) # proximal of sum of function with scalar = proximal of function self.assertNumpyArrayAlmostEqual(res1.as_array(), res2.as_array()) # proximal with out of sum of function with scalar = proximal of function res1_out = ig.allocate() res2_out = ig.allocate() f.proximal_conjugate(tmp, tau, out = res1_out) f1.proximal_conjugate(tmp, tau, out = res2_out) self.assertNumpyArrayAlmostEqual(res1_out.as_array(), res2_out.as_array())
# Run dot test to check validity of adjoint. print(BOP.dot_test(BOP)) # Specify total variation regularised least squares # Create operators op1 = GradientOperator(ig_gray, correlation=GradientOperator.CORRELATION_SPACE) op2 = BOP # Set regularisation parameter. alpha = 0.02 # Create functions to be blocked with operators f1 = alpha * MixedL21Norm() f2 = 0.5 * L2NormSquared(b=blurredimage) # Create BlockOperator operator = BlockOperator(op1, op2, shape=(2,1) ) # Create functions f = BlockFunction(f1, f2) g = ZeroFunction() # Compute operator Norm normK = operator.norm() # Primal & dual stepsizes sigma = 1 tau = 1/(sigma*normK**2)
def test_TranslateFunction(self): # Test TranslationFunction ig = ImageGeometry(4, 4) tmp = ig.allocate('random', seed=10) b = ig.allocate('random', seed=10) scalar = 0.4 tau = 0.05 list1 = [ L2NormSquared(), scalar * L2NormSquared(), scalar * L2NormSquared(b=b), L1Norm(), scalar * L1Norm(), scalar * L1Norm(b=b) ] list1_shift = [ L2NormSquared().centered_at(ig.allocate()), scalar * L2NormSquared().centered_at(ig.allocate()), scalar * L2NormSquared().centered_at(b), L1Norm().centered_at(ig.allocate()), scalar * L1Norm().centered_at(ig.allocate()), scalar * L1Norm().centered_at(b) ] out_gradient1 = ig.allocate() out_gradient2 = ig.allocate() out_proximal1 = ig.allocate() out_proximal2 = ig.allocate() out_proximal_conj1 = ig.allocate() out_proximal_conj2 = ig.allocate() for func, func_shift in zip(list1, list1_shift): # check call res1 = func(tmp) res2 = func_shift(tmp) self.assertNumpyArrayAlmostEqual(res1, res2) try: # check gradient res1_gradient = func.gradient(tmp) res2_gradient = func_shift.gradient(tmp) self.assertNumpyArrayAlmostEqual(res1_gradient.as_array(), res2_gradient.as_array()) # check gradient out func.gradient(tmp, out=out_gradient1) func_shift.gradient(tmp, out=out_gradient2) self.assertNumpyArrayAlmostEqual(out_gradient1.as_array(), out_gradient2.as_array()) except NotImplementedError: print('Function is not differentiable') # check proximal func.proximal(tmp, tau, out=out_proximal1) func_shift.proximal(tmp, tau, out=out_proximal2) self.assertNumpyArrayAlmostEqual(out_proximal1.as_array(), out_proximal2.as_array()) # check proximal conjugate func.proximal_conjugate(tmp, tau, out=out_proximal_conj1) func_shift.proximal_conjugate(tmp, tau, out=out_proximal_conj2) self.assertNumpyArrayAlmostEqual(out_proximal_conj1.as_array(), out_proximal_conj1.as_array())
# Regularisation Parameter depending on the noise distribution if noise == 's&p': alpha = 0.8 elif noise == 'poisson': alpha = 1.0 elif noise == 'gaussian': alpha = .3 # Choose data fidelity dependent on noise type. if noise == 's&p': f2 = L1Norm(b=noisy_data) elif noise == 'poisson': f2 = KullbackLeibler(noisy_data) elif noise == 'gaussian': f2 = 0.5 * L2NormSquared(b=noisy_data) # Create operators op1 = GradientOperator(ig, correlation=GradientOperator.CORRELATION_SPACE) op2 = MO # Create BlockOperator operator = BlockOperator(op1, op2, shape=(2, 1)) # Create functions f = BlockFunction(alpha * MixedL21Norm(), f2) g = ZeroFunction() # Compute operator Norm normK = operator.norm()
def test_PDHG_step_sizes(self): ig = ImageGeometry(3,3) data = ig.allocate('random') f = L2NormSquared(b=data) g = L2NormSquared() operator = 3*IdentityOperator(ig) #check if sigma, tau are None pdhg = PDHG(f=f, g=g, operator=operator, max_iteration=10) self.assertAlmostEqual(pdhg.sigma, 1./operator.norm()) self.assertAlmostEqual(pdhg.tau, 1./operator.norm()) #check if sigma is negative with self.assertRaises(ValueError): pdhg = PDHG(f=f, g=g, operator=operator, max_iteration=10, sigma = -1) #check if tau is negative with self.assertRaises(ValueError): pdhg = PDHG(f=f, g=g, operator=operator, max_iteration=10, tau = -1) #check if tau is None sigma = 3.0 pdhg = PDHG(f=f, g=g, operator=operator, sigma = sigma, max_iteration=10) self.assertAlmostEqual(pdhg.sigma, sigma) self.assertAlmostEqual(pdhg.tau, 1./(sigma * operator.norm()**2)) #check if sigma is None tau = 3.0 pdhg = PDHG(f=f, g=g, operator=operator, tau = tau, max_iteration=10) self.assertAlmostEqual(pdhg.tau, tau) self.assertAlmostEqual(pdhg.sigma, 1./(tau * operator.norm()**2)) #check if sigma/tau are not None tau = 1.0 sigma = 1.0 pdhg = PDHG(f=f, g=g, operator=operator, tau = tau, sigma = sigma, max_iteration=10) self.assertAlmostEqual(pdhg.tau, tau) self.assertAlmostEqual(pdhg.sigma, sigma) #check sigma/tau as arrays, sigma wrong shape ig1 = ImageGeometry(2,2) sigma = ig1.allocate() with self.assertRaises(ValueError): pdhg = PDHG(f=f, g=g, operator=operator, sigma = sigma, max_iteration=10) #check sigma/tau as arrays, tau wrong shape tau = ig1.allocate() with self.assertRaises(ValueError): pdhg = PDHG(f=f, g=g, operator=operator, tau = tau, max_iteration=10) # check sigma not Number or object with correct shape with self.assertRaises(AttributeError): pdhg = PDHG(f=f, g=g, operator=operator, sigma = "sigma", max_iteration=10) # check tau not Number or object with correct shape with self.assertRaises(AttributeError): pdhg = PDHG(f=f, g=g, operator=operator, tau = "tau", max_iteration=10) # check warning message if condition is not satisfied sigma = 4 tau = 1/3 with warnings.catch_warnings(record=True) as wa: pdhg = PDHG(f=f, g=g, operator=operator, tau = tau, sigma = sigma, max_iteration=10) assert "Convergence criterion" in str(wa[0].message)
algo.update_objective_interval = 10 cProfile.run('algo.run(100, verbose=1)') #%% plotter2D(algo.solution, cmap='gist_earth') #%% cProfile.run('algo.run(1)') # %% from cil.optimisation.algorithms import PDHG from cil.optimisation.functions import MixedL21Norm, BlockFunction, L2NormSquared, IndicatorBox from cil.optimisation.operators import GradientOperator, BlockOperator nabla = GradientOperator(ig_cs, backend='c') F = BlockFunction(L2NormSquared(b=ldata), alpha * MixedL21Norm()) BK = BlockOperator(K, nabla) # normK = BK.norm() normK = 191.54791313753265 pdhg = PDHG(f=F, g=IndicatorBox(lower=0.), operator=BK, max_iteration=1000, update_objective_interval=100) #%% pdhg.run(100, verbose=2, print_interval=10) #%% plotter2D(pdhg.solution, cmap='gist_earth') # %%
def tests_for_L2NormSq_and_weighted(self): numpy.random.seed(1) M, N, K = 2, 3, 1 ig = ImageGeometry(voxel_num_x=M, voxel_num_y=N, voxel_num_z=K) u = ig.allocate('random') b = ig.allocate('random') # check grad/call no data f = L2NormSquared() a1 = f.gradient(u) a2 = 2 * u numpy.testing.assert_array_almost_equal(a1.as_array(), a2.as_array(), decimal=4) numpy.testing.assert_equal(f(u), u.squared_norm()) # check grad/call with data # igggg = ImageGeometry(4,4) f1 = L2NormSquared(b=b) b1 = f1.gradient(u) b2 = 2 * (u - b) numpy.testing.assert_array_almost_equal(b1.as_array(), b2.as_array(), decimal=4) numpy.testing.assert_equal(f1(u), ((u - b)).squared_norm()) #check convex conjuagate no data c1 = f.convex_conjugate(u) c2 = 1 / 4 * u.squared_norm() numpy.testing.assert_equal(c1, c2) #check convex conjuagate with data d1 = f1.convex_conjugate(u) d2 = (1 / 4) * u.squared_norm() + u.dot(b) numpy.testing.assert_equal(d1, d2) # check proximal no data tau = 5 e1 = f.proximal(u, tau) e2 = u / (1 + 2 * tau) numpy.testing.assert_array_almost_equal(e1.as_array(), e2.as_array(), decimal=4) # check proximal with data tau = 5 h1 = f1.proximal(u, tau) h2 = (u - b) / (1 + 2 * tau) + b numpy.testing.assert_array_almost_equal(h1.as_array(), h2.as_array(), decimal=4) # check proximal conjugate no data tau = 0.2 k1 = f.proximal_conjugate(u, tau) k2 = u / (1 + tau / 2) numpy.testing.assert_array_almost_equal(k1.as_array(), k2.as_array(), decimal=4) # check proximal conjugate with data l1 = f1.proximal_conjugate(u, tau) l2 = (u - tau * b) / (1 + tau / 2) numpy.testing.assert_array_almost_equal(l1.as_array(), l2.as_array(), decimal=4) # check scaled function properties # scalar scalar = 100 f_scaled_no_data = scalar * L2NormSquared() f_scaled_data = scalar * L2NormSquared(b=b) # call numpy.testing.assert_equal(f_scaled_no_data(u), scalar * f(u)) numpy.testing.assert_equal(f_scaled_data(u), scalar * f1(u)) # grad numpy.testing.assert_array_almost_equal( f_scaled_no_data.gradient(u).as_array(), scalar * f.gradient(u).as_array(), decimal=4) numpy.testing.assert_array_almost_equal( f_scaled_data.gradient(u).as_array(), scalar * f1.gradient(u).as_array(), decimal=4) # conj numpy.testing.assert_almost_equal(f_scaled_no_data.convex_conjugate(u), \ f.convex_conjugate(u/scalar) * scalar, decimal=4) numpy.testing.assert_almost_equal(f_scaled_data.convex_conjugate(u), \ scalar * f1.convex_conjugate(u/scalar), decimal=4) # proximal numpy.testing.assert_array_almost_equal(f_scaled_no_data.proximal(u, tau).as_array(), \ f.proximal(u, tau*scalar).as_array()) numpy.testing.assert_array_almost_equal(f_scaled_data.proximal(u, tau).as_array(), \ f1.proximal(u, tau*scalar).as_array()) # proximal conjugate numpy.testing.assert_array_almost_equal(f_scaled_no_data.proximal_conjugate(u, tau).as_array(), \ (u/(1 + tau/(2*scalar) )).as_array(), decimal=4) numpy.testing.assert_array_almost_equal(f_scaled_data.proximal_conjugate(u, tau).as_array(), \ ((u - tau * b)/(1 + tau/(2*scalar) )).as_array(), decimal=4) print(" ####### check without out ######### ") u_out_no_out = ig.allocate('random_int') res_no_out = f_scaled_data.proximal_conjugate(u_out_no_out, 0.5) print(res_no_out.as_array()) print(" ####### check with out ######### ") res_out = ig.allocate() f_scaled_data.proximal_conjugate(u_out_no_out, 0.5, out=res_out) print(res_out.as_array()) numpy.testing.assert_array_almost_equal(res_no_out.as_array(), \ res_out.as_array(), decimal=4) ig1 = ImageGeometry(2, 3) tau = 0.1 u = ig1.allocate('random') b = ig1.allocate('random') scalar = 0.5 f_scaled = scalar * L2NormSquared(b=b) f_noscaled = L2NormSquared(b=b) res1 = f_scaled.proximal(u, tau) res2 = f_noscaled.proximal(u, tau * scalar) # res2 = (u + tau*b)/(1+tau) numpy.testing.assert_array_almost_equal(res1.as_array(), \ res2.as_array(), decimal=4) print("Checks for WeightedL2NormSquared") # Tests for weighted L2NormSquared ig = ImageGeometry(voxel_num_x=3, voxel_num_y=3) weight = ig.allocate('random') f = WeightedL2NormSquared(weight=weight) x = ig.allocate(0.4) res1 = f(x) res2 = (weight * (x**2)).sum() numpy.testing.assert_almost_equal(res1, res2, decimal=4) print("Call of WeightedL2NormSquared is ... ok") # gradient for weighted L2NormSquared res1 = f.gradient(x) res2 = 2 * weight * x out = ig.allocate() f.gradient(x, out=out) numpy.testing.assert_array_almost_equal(res1.as_array(), \ out.as_array(), decimal=4) numpy.testing.assert_array_almost_equal(res2.as_array(), \ out.as_array(), decimal=4) print("GradientOperator of WeightedL2NormSquared is ... ok") # convex conjugate for weighted L2NormSquared res1 = f.convex_conjugate(x) res2 = 1 / 4 * (x / weight.sqrt()).squared_norm() numpy.testing.assert_array_almost_equal(res1, \ res2, decimal=4) print("Convex conjugate of WeightedL2NormSquared is ... ok") # proximal for weighted L2NormSquared tau = 0.3 out = ig.allocate() res1 = f.proximal(x, tau) f.proximal(x, tau, out=out) res2 = x / (1 + 2 * tau * weight) numpy.testing.assert_array_almost_equal(res1.as_array(), \ res2.as_array(), decimal=4) print("Proximal of WeightedL2NormSquared is ... ok") tau = 0.3 out = ig.allocate() res1 = f.proximal_conjugate(x, tau) res2 = x / (1 + tau / (2 * weight)) numpy.testing.assert_array_almost_equal(res1.as_array(), \ res2.as_array(), decimal=4) print("Proximal conjugate of WeightedL2NormSquared is ... ok") b = ig.allocate('random') f1 = TranslateFunction(WeightedL2NormSquared(weight=weight), b) f2 = WeightedL2NormSquared(weight=weight, b=b) res1 = f1(x) res2 = f2(x) numpy.testing.assert_almost_equal(res1, res2, decimal=4) print("Call of WeightedL2NormSquared vs TranslateFunction is ... ok") f1 = WeightedL2NormSquared(b=b) f2 = L2NormSquared(b=b) numpy.testing.assert_almost_equal(f1.L, f2.L, decimal=4) numpy.testing.assert_almost_equal(f1.L, 2, decimal=4) numpy.testing.assert_almost_equal(f2.L, 2, decimal=4) print("Check Lip constants ... ok")
def mse(dc1, dc2): ''' Returns the Mean Squared error of two DataContainers ''' diff = dc1 - dc2 return L2NormSquared().__call__(diff) / dc1.size
def test_L2NormSquaredOut(self): # TESTS for L2 and scalar * L2 M, N, K = 2, 3, 5 ig = ImageGeometry(voxel_num_x=M, voxel_num_y=N, voxel_num_z=K) u = ig.allocate(ImageGeometry.RANDOM, seed=1) b = ig.allocate(ImageGeometry.RANDOM, seed=2) # check grad/call no data f = L2NormSquared() a1 = f.gradient(u) a2 = a1 * 0. f.gradient(u, out=a2) numpy.testing.assert_array_almost_equal(a1.as_array(), a2.as_array(), decimal=4) #numpy.testing.assert_equal(f(u), u.squared_norm()) # check grad/call with data f1 = L2NormSquared(b=b) b1 = f1.gradient(u) b2 = b1 * 0. f1.gradient(u, out=b2) numpy.testing.assert_array_almost_equal(b1.as_array(), b2.as_array(), decimal=4) #numpy.testing.assert_equal(f1(u), (u-b).squared_norm()) # check proximal no data tau = 5 e1 = f.proximal(u, tau) e2 = e1 * 0. f.proximal(u, tau, out=e2) numpy.testing.assert_array_almost_equal(e1.as_array(), e2.as_array(), decimal=4) # check proximal with data tau = 5 h1 = f1.proximal(u, tau) h2 = h1 * 0. f1.proximal(u, tau, out=h2) numpy.testing.assert_array_almost_equal(h1.as_array(), h2.as_array(), decimal=4) # check proximal conjugate no data tau = 0.2 k1 = f.proximal_conjugate(u, tau) k2 = k1 * 0. f.proximal_conjugate(u, tau, out=k2) numpy.testing.assert_array_almost_equal(k1.as_array(), k2.as_array(), decimal=4) # check proximal conjugate with data l1 = f1.proximal_conjugate(u, tau) l2 = l1 * 0. f1.proximal_conjugate(u, tau, out=l2) numpy.testing.assert_array_almost_equal(l1.as_array(), l2.as_array(), decimal=4) # check scaled function properties # scalar scalar = 100 f_scaled_no_data = scalar * L2NormSquared() f_scaled_data = scalar * L2NormSquared(b=b) # grad w = f_scaled_no_data.gradient(u) ww = w * 0 f_scaled_no_data.gradient(u, out=ww) numpy.testing.assert_array_almost_equal(w.as_array(), ww.as_array(), decimal=4) # numpy.testing.assert_array_almost_equal(f_scaled_data.gradient(u).as_array(), scalar*f1.gradient(u).as_array(), decimal=4) # # conj # numpy.testing.assert_almost_equal(f_scaled_no_data.convex_conjugate(u), \ # f.convex_conjugate(u/scalar) * scalar, decimal=4) # numpy.testing.assert_almost_equal(f_scaled_data.convex_conjugate(u), \ # scalar * f1.convex_conjugate(u/scalar), decimal=4) # # proximal w = f_scaled_no_data.proximal(u, tau) ww = w * 0 f_scaled_no_data.proximal(u, tau, out=ww) numpy.testing.assert_array_almost_equal(w.as_array(), \ ww.as_array()) # numpy.testing.assert_array_almost_equal(f_scaled_data.proximal(u, tau).as_array(), \ # f1.proximal(u, tau*scalar).as_array()) # proximal conjugate w = f_scaled_no_data.proximal_conjugate(u, tau) ww = w * 0 f_scaled_no_data.proximal_conjugate(u, tau, out=ww) numpy.testing.assert_array_almost_equal(w.as_array(), \ ww.as_array(), decimal=4)
def test_L2NormSquared(self): # TESTS for L2 and scalar * L2 print("Test L2NormSquared") numpy.random.seed(1) M, N, K = 2, 3, 5 ig = ImageGeometry(voxel_num_x=M, voxel_num_y=N, voxel_num_z=K) u = ig.allocate(ImageGeometry.RANDOM) b = ig.allocate(ImageGeometry.RANDOM) # check grad/call no data f = L2NormSquared() a1 = f.gradient(u) a2 = 2 * u numpy.testing.assert_array_almost_equal(a1.as_array(), a2.as_array(), decimal=4) numpy.testing.assert_equal(f(u), u.squared_norm()) # check grad/call with data f1 = L2NormSquared(b=b) b1 = f1.gradient(u) b2 = 2 * (u - b) numpy.testing.assert_array_almost_equal(b1.as_array(), b2.as_array(), decimal=4) numpy.testing.assert_equal(f1(u), (u - b).squared_norm()) #check convex conjuagate no data c1 = f.convex_conjugate(u) c2 = 1 / 4. * u.squared_norm() numpy.testing.assert_equal(c1, c2) #check convex conjugate with data d1 = f1.convex_conjugate(u) d2 = (1. / 4.) * u.squared_norm() + (u * b).sum() numpy.testing.assert_almost_equal(d1, d2, decimal=6) # check proximal no data tau = 5 e1 = f.proximal(u, tau) e2 = u / (1 + 2 * tau) numpy.testing.assert_array_almost_equal(e1.as_array(), e2.as_array(), decimal=4) # check proximal with data tau = 5 h1 = f1.proximal(u, tau) h2 = (u - b) / (1 + 2 * tau) + b numpy.testing.assert_array_almost_equal(h1.as_array(), h2.as_array(), decimal=4) # check proximal conjugate no data tau = 0.2 k1 = f.proximal_conjugate(u, tau) k2 = u / (1 + tau / 2) numpy.testing.assert_array_almost_equal(k1.as_array(), k2.as_array(), decimal=4) # check proximal conjugate with data l1 = f1.proximal_conjugate(u, tau) l2 = (u - tau * b) / (1 + tau / 2) numpy.testing.assert_array_almost_equal(l1.as_array(), l2.as_array(), decimal=4) # check scaled function properties # scalar scalar = 100 f_scaled_no_data = scalar * L2NormSquared() f_scaled_data = scalar * L2NormSquared(b=b) # call numpy.testing.assert_equal(f_scaled_no_data(u), scalar * f(u)) numpy.testing.assert_equal(f_scaled_data(u), scalar * f1(u)) # grad numpy.testing.assert_array_almost_equal( f_scaled_no_data.gradient(u).as_array(), scalar * f.gradient(u).as_array(), decimal=4) numpy.testing.assert_array_almost_equal( f_scaled_data.gradient(u).as_array(), scalar * f1.gradient(u).as_array(), decimal=4) # conj numpy.testing.assert_almost_equal(f_scaled_no_data.convex_conjugate(u), \ f.convex_conjugate(u/scalar) * scalar, decimal=4) numpy.testing.assert_almost_equal(f_scaled_data.convex_conjugate(u), \ scalar * f1.convex_conjugate(u/scalar), decimal=4) # proximal numpy.testing.assert_array_almost_equal(f_scaled_no_data.proximal(u, tau).as_array(), \ f.proximal(u, tau*scalar).as_array()) numpy.testing.assert_array_almost_equal(f_scaled_data.proximal(u, tau).as_array(), \ f1.proximal(u, tau*scalar).as_array()) # proximal conjugate numpy.testing.assert_array_almost_equal(f_scaled_no_data.proximal_conjugate(u, tau).as_array(), \ (u/(1 + tau/(2*scalar) )).as_array(), decimal=4) numpy.testing.assert_array_almost_equal(f_scaled_data.proximal_conjugate(u, tau).as_array(), \ ((u - tau * b)/(1 + tau/(2*scalar) )).as_array(), decimal=4)
from cil.optimisation.operators import GradientOperator, IdentityOperator, BlockOperator import numpy import numpy as np ig = ImageGeometry(M, N) BG = BlockGeometry(ig, ig) u = ig.allocate('random_int') B = BlockOperator( GradientOperator(ig), IdentityOperator(ig) ) U = B.direct(u) b = ig.allocate('random_int') f1 = 10 * MixedL21Norm() f2 = 5 * L2NormSquared(b=b) f = BlockFunction(f1, f2) print(f.L) f = BlockFunction(f2, f2) print(f.L) # tau = 0.3 # # print( " without out " ) # res_no_out = f.proximal_conjugate( U, tau) # res_out = B.range_geometry().allocate() # f.proximal_conjugate( U, tau, out = res_out) # # numpy.testing.assert_array_almost_equal(res_no_out[0][0].as_array(), \ # res_out[0][0].as_array(), decimal=4)
def test_SumFunction(self): M, N, K = 3,4,5 ig = ImageGeometry(M, N, K) tmp = ig.allocate('random', seed=1) b = ig.allocate('random', seed=2) eta = ig.allocate(0.1) operator = IdentityOperator(ig) scalar = 0.25 f1 = L2NormSquared() f2 = L1Norm() f3 = scalar * L2NormSquared() f4 = scalar * L1Norm() f5 = scalar * L2NormSquared(b=b) f6 = scalar * L1Norm(b=b) f7 = ZeroFunction() f8 = 5 * ConstantFunction(10) f9 = LeastSquares(operator, b, c=scalar) f10 = 0.5*KullbackLeibler(b=b,eta = eta) f11 = KullbackLeibler(b=b, eta =eta) f12 = 10 # f10 = 0.5 * MixedL21Norm() # f11 = IndicatorBox(lower=0) list1 = [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12] print('################### Check sum of two functions ################## \n') for func in list1: # check sum of two functions if isinstance(func, ScaledFunction): type_fun = ' scalar * ' + type(func.function).__name__ else: type_fun = type(func).__name__ if isinstance(func, Number): tmp_fun_eval = func else: tmp_fun_eval = func(tmp) sumf = f1 + func self.assertNumpyArrayAlmostEqual(sumf(tmp), f1(tmp) + tmp_fun_eval ) print('{} = ( {} + {} ) is OK'.format(type(sumf).__name__, type(f1).__name__, type_fun)) sumf1 = func + f1 self.assertNumpyArrayAlmostEqual(sumf1(tmp), tmp_fun_eval + f1(tmp)) print('Checking commutative') print('{} + ( {} + {} ) is OK\n'.format(type(sumf1).__name__, type_fun, type(f1).__name__)) print('################### Check Lispchitz constant ################## \n') for i,func in enumerate(list1): if isinstance(func, ScaledFunction): type_fun = ' scalar * ' + type(func.function).__name__ else: type_fun = type(func).__name__ try: # check Lispchitz sum of two functions print ("i", i,func.__class__.__name__) if isinstance(func, Number): tmp_fun_L = 0 else: tmp_fun_L = func.L sumf = f1 + func try: sumf.L==f1.L + tmp_fun_L except TypeError: print('Function {} has L = None'.format(type_fun)) except ValueError as nie: print (func.__class__.__name__, nie) print('\n################### Check Gradient ################## \n') for func in list1: if isinstance(func, ScaledFunction): type_fun = ' scalar * ' + type(func.function).__name__ else: type_fun = type(func).__name__ sumf = f1 + func # check gradient try: if isinstance(func, Number): tmp_fun_gradient = 0 else: tmp_fun_gradient = func.gradient(tmp) self.assertNumpyArrayAlmostEqual(sumf.gradient(tmp).as_array(), (f1.gradient(tmp) + tmp_fun_gradient).as_array()) except NotImplementedError: print("{} is not differentiable".format(type_fun)) print('\n################### Check Gradient Out ################## \n') out_left = ig.allocate() out_right1 = ig.allocate() out_right2 = ig.allocate() for i, func in enumerate(list1): if isinstance(func, ScaledFunction): type_fun = ' scalar * ' + type(func.function).__name__ else: type_fun = type(func).__name__ sumf = f1 + func # check gradient out try: if isinstance(func, Number): tmp_fun_gradient_out = 0 else: func.gradient(tmp, out = out_right2) tmp_fun_gradient_out = out_right2.as_array() #print('Check {} + {}\n'.format(type(f1).__name__, type_fun)) sumf.gradient(tmp, out = out_left) f1.gradient(tmp, out = out_right1) self.assertNumpyArrayAlmostEqual(out_left.as_array(), out_right1.as_array() + tmp_fun_gradient_out) except NotImplementedError: print("{} is not differentiable".format(type_fun))