def test_ConstantFunction(self): k = ConstantFunction(constant=1) ig = ImageGeometry(1,2,3) x = ig.allocate(2) grad = k.gradient(x) out = ig.allocate(-1) k.gradient(x, out=out) #out.fill(-3) self.assertNumpyArrayEqual(numpy.zeros(x.shape), grad.as_array()) self.assertNumpyArrayEqual(out.as_array(), grad.as_array())
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_ConstantFunction(self): M, N, K = 3,4,5 ig = ImageGeometry(M, N, K) tmp = ig.allocate('random_int') constant = 10 f = ConstantFunction(constant) # check call res1 = f(tmp) self.assertAlmostEqual(res1, constant) # check gradient with and without out res1 = f.gradient(tmp) out = ig.allocate() self.assertNumpyArrayAlmostEqual(res1.as_array(), out) out1 = ig.allocate() f.gradient(tmp, out=out1) self.assertNumpyArrayAlmostEqual(res1.as_array(), out1) # check convex conjugate res1 = f.convex_conjugate(tmp) res2 = tmp.maximum(0).sum() self.assertNumpyArrayAlmostEqual(res1.as_array(), res2.as_array()) # check proximal tau = 0.4 res1 = f.proximal(tmp, tau) self.assertNumpyArrayAlmostEqual(res1.as_array(), tmp.as_array())
def test_Lipschitz4(self): print('Test for test_Lipschitz4') M, N = 50, 50 ig = ImageGeometry(voxel_num_x=M, voxel_num_y=N) b = ig.allocate('random', seed=1) print('Check call with IdentityOperator operator... OK\n') operator = 3 * IdentityOperator(ig) u = ig.allocate('random_int', seed=50) # func2 = LeastSquares(operator, b, 0.5) func1 = ConstantFunction(0.3) f3 = func1 + 3 assert f3.L == 0 print("OK") print(f3.L) f3.L = 2 assert f3.L == 2 print("OK") assert func1.L == 0 print("OK") try: func1.L = 2 assert False except AttributeError as ve: assert True print("OK") f2 = LeastSquares(operator, b, 0.5) f4 = 2 * f2 assert f4.L == 2 * f2.L print("OK") f4.L = 10 assert f4.L != 2 * f2.L print("OK") f4 = -2 * f2 assert f4.L == 2 * f2.L
def test_Lipschitz3(self): print('Test for test_Lipschitz3') M, N = 50, 50 ig = ImageGeometry(voxel_num_x=M, voxel_num_y=N) b = ig.allocate('random', seed=1) print('Check call with IdentityOperator operator... OK\n') operator = 3 * IdentityOperator(ig) u = ig.allocate('random_int', seed=50) # func2 = LeastSquares(operator, b, 0.5) func1 = ConstantFunction(0.3) f3 = TranslateFunction(func1, 3) assert f3.L != 2 print(f3.L) f3.L = 2 assert f3.L == 2
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))
def test_SumFunction_more_inputs(self): # Test Lipshchitz value with more than 2 functions list2 = [ LeastSquares(self.operator, self.b, c=0.25), LeastSquares(self.operator, self.b, c=4), LeastSquares(self.operator, self.b, c=5) ] F = SumFunction(*list2) L = 0. for f in list2: L += f.L self.assertAlmostEqual(L, F.L) # assert Lmax property self.assertAlmostEqual(max(f.L for f in list2), F.Lmax) ## test value of the gradient out = list2[0].gradient(self.x) out += list2[1].gradient(self.x) out += list2[2].gradient(self.x) # gradient without out out2 = F.gradient(self.x) np.testing.assert_allclose(out.as_array(), out2.as_array()) # gradient with out out3 = self.x * 0. F.gradient(self.x, out=out3) np.testing.assert_allclose(out.as_array(), out3.as_array()) # check call method val = F(self.x) val2 = 0. for f in F.functions: val2 += f(self.x) np.testing.assert_almost_equal(val, val2) # adding one more function (3 in total) scalar = 2.5 F2 = F + ConstantFunction(scalar) # test __add__ method assert len(F2.functions) == len(F.functions) + 1 # test if the sum remains a SumFunction self.assertIsInstance(F2, SumFunction) # check call np.testing.assert_almost_equal(F2(self.x), F(self.x) + scalar) # adding one more function (4 in total) F3 = F + F2 np.testing.assert_almost_equal(F2(self.x) + F(self.x), F3(self.x)) self.assertEqual(len(F3.functions), len(F2.functions) + len(F.functions)) # test if the sum remains a SumFunction self.assertIsInstance(F3, SumFunction)