def test_GradientOperator_in_place_vs_allocate_direct(self): for geom in self.list_geometries: for bnd in self.bconditions: for backend in self.backend: for corr in self.correlation: for method in self.method: Grad = GradientOperator(geom, bnd_cond=bnd, backend=backend, correlation=corr, method=method) tmp_x = Grad.domain.allocate('random') res_in_place = Grad.direct(tmp_x) res_allocate = Grad.range.allocate() Grad.direct(tmp_x, out=res_allocate) for m in range(len(Grad.range.geometries)): try: numpy.testing.assert_array_almost_equal( res_in_place[m].array, res_allocate[m].array) except: self.print_assertion_info( geom, bnd, backend, corr, method, None) raise
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_SymmetrisedGradientOperator3b(self): ########################################################################### # 3D geometry no channels #ig3 = ImageGeometry(N, M, K) Grad3 = GradientOperator(self.ig3, correlation='Space') E3 = SymmetrisedGradientOperator(Grad3.range_geometry()) numpy.random.seed(1) u3 = E3.domain_geometry().allocate('random') w3 = E3.range_geometry().allocate('random', symmetry=True) # lhs3 = E3.direct(u3).dot(w3) rhs3 = u3.dot(E3.adjoint(w3)) # with numpy 1.11 and py 3.5 decimal = 3 decimal = 4 npv = version.parse(numpy.version.version) if npv.major == 1 and npv.minor == 11: print("########## SETTING decimal to 3 ###########") decimal = 3 numpy.testing.assert_almost_equal(lhs3, rhs3, decimal=decimal) # self.assertAlmostEqual(lhs3, rhs3, ) print("*******", lhs3, rhs3, abs((rhs3 - lhs3) / rhs3), 1.5 * 10**(-4), abs((rhs3 - lhs3) / rhs3) < 1.5 * 10**(-4)) self.assertTrue( LinearOperator.dot_test(E3, range_init=w3, domain_init=u3, decimal=decimal))
def test_CompositionOperator_direct3(self): ig = self.ig data = self.data G = GradientOperator(domain_geometry=ig) Id1 = 2 * IdentityOperator(ig) Id2 = IdentityOperator(ig) d = CompositionOperator(G, Id2) out1 = G.direct(data) d_out = d.direct(data) d1 = Id2.direct(data) d2 = G.direct(d1) numpy.testing.assert_array_almost_equal( d2.get_item(0).as_array(), d_out.get_item(0).as_array()) numpy.testing.assert_array_almost_equal( d2.get_item(1).as_array(), d_out.get_item(1).as_array()) G2Id = G.compose(2 * Id2) d2g = G2Id.direct(data) numpy.testing.assert_array_almost_equal( d2g.get_item(0).as_array(), 2 * d_out.get_item(0).as_array()) numpy.testing.assert_array_almost_equal( d2g.get_item(1).as_array(), 2 * d_out.get_item(1).as_array())
def test_NestedBlockDataContainer2(self): M, N = 2, 3 ig = ImageGeometry(voxel_num_x=M, voxel_num_y=N) ag = ig u = ig.allocate(1) op1 = GradientOperator(ig) op2 = IdentityOperator(ig, ag) operator = BlockOperator(op1, op2, shape=(2, 1)) d1 = op1.direct(u) d2 = op2.direct(u) d = operator.direct(u) dd = operator.domain_geometry() ww = operator.range_geometry() c1 = d + d c2 = 2 * d c3 = d / (d + 0.0001) c5 = d.get_item(0).power(2).sum()
def test_GradientOperator_norm(self): for geom in self.list_geometries: for bnd in self.bconditions: for backend in self.backend: for corr in self.correlation: for method in self.method: if geom.channels == 1: if geom.length == 2: norm = numpy.sqrt( (2 / geom.voxel_size_y)**2 + (2 / geom.voxel_size_x)**2) elif geom.length == 3: norm = numpy.sqrt( (2 / geom.voxel_size_z)**2 + (2 / geom.voxel_size_y)**2 + (2 / geom.voxel_size_x)**2) else: if corr == 'Space': if geom.length == 3: norm = numpy.sqrt( (2 / geom.voxel_size_y)**2 + (2 / geom.voxel_size_x)**2) else: norm = numpy.sqrt( 4 + (2 / geom.voxel_size_z)**2 + (2 / geom.voxel_size_y)**2 + (2 / geom.voxel_size_x)**2) else: if geom.length == 3: norm = numpy.sqrt( 4 + (2 / geom.voxel_size_y)**2 + (2 / geom.voxel_size_x)**2) else: norm = numpy.sqrt( 4 + (2 / geom.voxel_size_z)**2 + (2 / geom.voxel_size_y)**2 + (2 / geom.voxel_size_x)**2) Grad = GradientOperator(geom, bnd_cond=bnd, backend=backend, correlation=corr, method=method) try: numpy.testing.assert_approx_equal( Grad.norm(), norm, significant=1) except AssertionError: self.print_assertion_info( geom, bnd, backend, corr, method, None) raise
def test_SymmetrisedGradientOperator2a(self): ########################################################################### # 2D geometry with channels # ig2 = ImageGeometry(N, M, channels = C) Grad2 = GradientOperator(self.ig2, correlation='Space') E2 = SymmetrisedGradientOperator(Grad2.range_geometry()) numpy.testing.assert_almost_equal(E2.norm(iterations=self.iterations), numpy.sqrt(8), decimal=self.decimal)
def test_SymmetrisedGradientOperator3a(self): ########################################################################### # 3D geometry no channels #ig3 = ImageGeometry(N, M, K) Grad3 = GradientOperator(self.ig3, correlation='Space') E3 = SymmetrisedGradientOperator(Grad3.range_geometry()) norm = LinearOperator.PowerMethod(E3, max_iteration=100, tolerance=0) numpy.testing.assert_almost_equal(norm, numpy.sqrt(12), decimal=self.decimal)
def test_SymmetrisedGradientOperator1a(self): ########################################################################### ## Symmetrized Gradient Tests print("Test SymmetrisedGradientOperator") ########################################################################### # 2D geometry no channels # ig = ImageGeometry(N, M) Grad = GradientOperator(self.ig) E1 = SymmetrisedGradientOperator(Grad.range_geometry()) numpy.testing.assert_almost_equal(E1.norm(iterations=self.iterations), numpy.sqrt(8), decimal=self.decimal)
def test_SymmetrisedGradientOperator3a(self): ########################################################################### # 3D geometry no channels #ig3 = ImageGeometry(N, M, K) Grad3 = GradientOperator(self.ig3, correlation='Space') E3 = SymmetrisedGradientOperator(Grad3.range_geometry()) norm1 = E3.norm() norm2 = E3.calculate_norm(iterations=100) print(norm1, norm2) numpy.testing.assert_almost_equal(norm2, numpy.sqrt(12), decimal=self.decimal)
def test_CompositionOperator_adjoint6(self): ig = self.ig data = self.data G = GradientOperator(domain_geometry=ig) Id1 = 3 * IdentityOperator(ig) Id = ZeroOperator(ig) d = G.compose(Id) da = d.direct(data) out1 = G.adjoint(da) out2 = d.adjoint(da) numpy.testing.assert_array_almost_equal(out2.as_array(), 0 * out1.as_array())
def test_SymmetrisedGradientOperator2(self): ########################################################################### # 2D geometry with channels # ig2 = ImageGeometry(N, M, channels = C) Grad2 = GradientOperator(self.ig2, correlation='Space') E2 = SymmetrisedGradientOperator(Grad2.range_geometry()) numpy.random.seed(1) u2 = E2.domain_geometry().allocate('random') w2 = E2.range_geometry().allocate('random', symmetry=True) # lhs2 = E2.direct(u2).dot(w2) rhs2 = u2.dot(E2.adjoint(w2)) numpy.testing.assert_allclose(lhs2, rhs2, rtol=1e-3)
def test_GradientOperator_linearity(self): nc, nz, ny, nx = 3, 4, 5, 6 ig = ImageGeometry(voxel_num_x=nx, voxel_num_y=ny, voxel_num_z=nz, channels=nc) grad = GradientOperator(ig, bnd_cond='Neumann', correlation='SpaceChannels', backend='c') self.assertTrue(LinearOperator.dot_test(grad)) grad = GradientOperator(ig, bnd_cond='Periodic', correlation='SpaceChannels', backend='c') self.assertTrue(LinearOperator.dot_test(grad)) grad = GradientOperator(ig, bnd_cond='Neumann', correlation='SpaceChannels', backend='numpy') self.assertTrue(LinearOperator.dot_test(grad)) grad = GradientOperator(ig, bnd_cond='Periodic', correlation='SpaceChannels', backend='numpy') self.assertTrue(LinearOperator.dot_test(grad))
def test_PowerMethod(self): print("test_BlockOperator") N, M = 200, 300 niter = 10 ig = ImageGeometry(N, M) Id = IdentityOperator(ig) G = GradientOperator(ig) uid = Id.domain_geometry().allocate(ImageGeometry.RANDOM, seed=1) a = LinearOperator.PowerMethod(Id, niter, uid) #b = LinearOperator.PowerMethodNonsquare(Id, niter, uid) b = LinearOperator.PowerMethod(Id, niter) print("Edo impl", a[0]) print("None impl", b[0]) #self.assertAlmostEqual(a[0], b[0]) self.assertNumpyArrayAlmostEqual(a[0], b[0], decimal=6) a = LinearOperator.PowerMethod(G, niter, uid) b = LinearOperator.PowerMethod(G, niter) #b = LinearOperator.PowerMethodNonsquare(G, niter, uid) print("Edo impl", a[0]) #print ("old impl", b[0]) self.assertNumpyArrayAlmostEqual(a[0], b[0], decimal=2)
def test_GradientOperator_split_shape(self): for geom in [self.ig_2D, self.ig_2D_chan, self.ig_3D, self.ig_3D_chan]: for split in [True, False]: Grad = GradientOperator(geom, split=split, correlation="SpaceChannels") if geom == self.ig_2D: shape = (2, 1) elif geom == self.ig_3D: shape = (3, 1) elif geom == self.ig_2D_chan: if split: shape = (2, 1) else: shape = (3, 1) elif geom == self.ig_3D_chan: if split: shape = (2, 1) else: shape = (4, 1) try: numpy.testing.assert_equal(Grad.range.shape, shape) except: self.print_assertion_info(geom, None, None, None, split=split) raise
def test_CompositionOperator_adjoint2(self): ig = self.ig data = self.data G = GradientOperator(domain_geometry=ig) Id1 = 2 * IdentityOperator(ig) Id2 = IdentityOperator(ig) d = CompositionOperator(G, Id1) da = d.direct(data) out1 = G.adjoint(da) out2 = d.adjoint(da) numpy.testing.assert_array_almost_equal(out2.as_array(), 2 * out1.as_array())
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 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 gradient(self): '''creates a gradient operator if not instantiated yet There is no check that the variable _domain is changed after instantiation (should not be the case)''' if self._gradient is None: if self._domain is not None: self._gradient = GradientOperator(self._domain, correlation = self.correlation, backend = self.backend) return self._gradient
def test_Norm(self): print("test_BlockOperator") ## numpy.random.seed(1) N, M = 200, 300 ig = ImageGeometry(N, M) G = GradientOperator(ig) t0 = timer() norm = G.norm() t1 = timer() norm2 = G.norm() t2 = timer() norm3 = G.norm(force=True) t3 = timer() print("Norm dT1 {} dT2 {} dT3 {}".format(t1 - t0, t2 - t1, t3 - t2)) self.assertLess(t2 - t1, t1 - t0) self.assertLess(t2 - t1, t3 - t2) numpy.random.seed(1) t4 = timer() norm4 = G.norm(iterations=50, force=True) t5 = timer() self.assertLess(t2 - t1, t5 - t4) numpy.random.seed(1) t4 = timer() norm5 = G.norm(x_init=ig.allocate('random'), iterations=50, force=True) t5 = timer() self.assertLess(t2 - t1, t5 - t4) for n in [norm, norm2, norm3, norm4, norm5]: print("norm {}", format(n))
def test_dot_test2(self): Grad3 = GradientOperator(self.ig3, correlation='SpaceChannel', backend='c') # self.assertAlmostEqual(lhs3, rhs3) # self.assertTrue( LinearOperator.dot_test(Grad3 , verbose=True)) self.assertTrue(LinearOperator.dot_test(Grad3, decimal=4, verbose=True))
def test_CompositionOperator_direct1(self): ig = self.ig data = self.data G = GradientOperator(domain_geometry=ig) Id1 = 2 * IdentityOperator(ig) Id2 = IdentityOperator(ig) d = CompositionOperator(G, Id2) out1 = G.direct(data) out2 = d.direct(data) numpy.testing.assert_array_almost_equal( out2.get_item(0).as_array(), out1.get_item(0).as_array()) numpy.testing.assert_array_almost_equal( out2.get_item(1).as_array(), out1.get_item(1).as_array())
def test_SymmetrisedGradientOperator1b(self): ########################################################################### ## Symmetrized GradientOperator Tests print("Test SymmetrisedGradientOperator") ########################################################################### # 2D geometry no channels # ig = ImageGeometry(N, M) Grad = GradientOperator(self.ig) E1 = SymmetrisedGradientOperator(Grad.range_geometry()) numpy.random.seed(1) u1 = E1.domain_geometry().allocate('random') w1 = E1.range_geometry().allocate('random', symmetry=True) lhs = E1.direct(u1).dot(w1) rhs = u1.dot(E1.adjoint(w1)) print("lhs {} rhs {}".format(lhs, rhs)) # self.assertAlmostEqual(lhs, rhs) numpy.testing.assert_allclose(lhs, rhs, rtol=1e-3)
def test_dot_test(self): Grad3 = GradientOperator(self.ig3, correlation='Space', backend='numpy') # self.assertAlmostEqual(lhs3, rhs3) self.assertTrue(LinearOperator.dot_test(Grad3, verbose=True, decimal=4)) self.assertTrue(LinearOperator.dot_test(Grad3, verbose=True, decimal=4))
def test_GradientOperator_complex_data(self): # make complex dtype self.ig_2D.dtype = numpy.complex x = self.ig_2D.allocate('random') Grad = GradientOperator(domain_geometry=self.ig_2D) res1 = Grad.direct(x) res2 = Grad.range.allocate() Grad.direct(x, out=res2) numpy.testing.assert_array_almost_equal(res1[0].as_array(), res2[0].as_array()) numpy.testing.assert_array_almost_equal(res1[1].as_array(), res2[1].as_array()) # check dot_test for sd in [5, 10, 15]: self.assertTrue(LinearOperator.dot_test(Grad, seed=sd))
def test_compare_with_PDHG(self): # Load an image from the CIL gallery. data = dataexample.SHAPES.get() ig = data.geometry # Add gaussian noise noisy_data = applynoise.gaussian(data, seed=10, var=0.005) # TV regularisation parameter alpha = 1 # fidelity = 0.5 * L2NormSquared(b=noisy_data) # fidelity = L1Norm(b=noisy_data) fidelity = KullbackLeibler(b=noisy_data, use_numba=False) # Setup and run the PDHG algorithm F = BlockFunction(alpha * MixedL21Norm(), fidelity) G = ZeroFunction() K = BlockOperator(GradientOperator(ig), IdentityOperator(ig)) # Compute operator Norm normK = K.norm() # Primal & dual stepsizes sigma = 1. / normK tau = 1. / normK pdhg = PDHG(f=F, g=G, operator=K, tau=tau, sigma=sigma, max_iteration=100, update_objective_interval=10) pdhg.run(verbose=0) sigma = 1 tau = sigma / normK**2 admm = LADMM(f=G, g=F, operator=K, tau=tau, sigma=sigma, max_iteration=100, update_objective_interval=10) admm.run(verbose=0) from cil.utilities.quality_measures import psnr if debug_print: print("PSNR", psnr(admm.solution, pdhg.solution)) np.testing.assert_almost_equal(psnr(admm.solution, pdhg.solution), 84.46678222768597, decimal=4)
def test_SymmetrisedGradientOperator3b(self): ########################################################################### # 3D geometry no channels #ig3 = ImageGeometry(N, M, K) Grad3 = GradientOperator(self.ig3, correlation='Space') E3 = SymmetrisedGradientOperator(Grad3.range_geometry()) numpy.random.seed(1) u3 = E3.domain_geometry().allocate('random') w3 = E3.range_geometry().allocate('random', symmetry=True) # lhs3 = E3.direct(u3).dot(w3) rhs3 = u3.dot(E3.adjoint(w3)) numpy.testing.assert_almost_equal(lhs3, rhs3, decimal=3) print("*******", lhs3, rhs3, abs((rhs3 - lhs3) / rhs3), 1.5 * 10**(-4), abs((rhs3 - lhs3) / rhs3) < 1.5 * 10**(-4)) self.assertTrue( LinearOperator.dot_test(E3, range_init=w3, domain_init=u3, decimal=3))
def test_TranslateFunction_MixedL21Norm(self): print("Test for TranslateFunction for MixedL21Norm") ig = ImageGeometry(4, 4) Grad = GradientOperator(ig) b = Grad.range_geometry().allocate('random', seed=10) alpha = 0.4 f1 = alpha * MixedL21Norm() fun = TranslateFunction(f1, b) tmp_x = Grad.range_geometry().allocate('random', seed=10) res1 = fun(tmp_x) res2 = f1(tmp_x - b) self.assertAlmostEqual(res1, res2) print("Check call...OK") res1 = f1.convex_conjugate(tmp_x) - b.dot(tmp_x) res2 = fun.convex_conjugate(tmp_x) self.assertAlmostEqual(res1, res2) print("Check convex conjugate...OK (maybe inf=inf)") tau = 0.4 res1 = fun.proximal(tmp_x, tau) res2 = f1.proximal(tmp_x - b, tau) + b self.assertNumpyArrayAlmostEqual( res1.get_item(0).as_array(), res2.get_item(0).as_array()) self.assertNumpyArrayAlmostEqual( res1.get_item(1).as_array(), res2.get_item(1).as_array()) print("Check prox...OK ")
def test_BlockOperatorLinearValidity(self): print("test_BlockOperatorLinearValidity") M, N = 3, 4 ig = ImageGeometry(M, N) arr = ig.allocate('random', seed=1) G = GradientOperator(ig) Id = IdentityOperator(ig) B = BlockOperator(G, Id) # Nx1 case u = ig.allocate('random', seed=2) w = B.range_geometry().allocate(ImageGeometry.RANDOM, seed=3) w1 = B.direct(u) u1 = B.adjoint(w) self.assertAlmostEqual((w * w1).sum(), (u1 * u).sum(), places=5)
def test_Norm(self): numpy.random.seed(1) N, M = 200, 300 ig = ImageGeometry(N, M) G = GradientOperator(ig) self.assertIsNone(G._norm) #calculates norm self.assertAlmostEqual(G.norm(), 2.754, 2) #sets_norm G.set_norm(4) self.assertEqual(G._norm, 4) #gets chached norm self.assertEqual(G.norm(), 4) #sets cache to None G.set_norm(None) #recalculates norm self.assertAlmostEqual(G.norm(), 2.754, 2)