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 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_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_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)
def test_GradientOperator(self): N, M, K = 20, 30, 40 channels = 10 numpy.random.seed(1) # check range geometry, examples ig1 = ImageGeometry(voxel_num_x = M, voxel_num_y = N) ig3 = ImageGeometry(voxel_num_x = M, voxel_num_y = N, channels = channels) ig4 = ImageGeometry(voxel_num_x = M, voxel_num_y = N, channels = channels, voxel_num_z= K) G1 = GradientOperator(ig1, correlation = 'Space', backend='numpy') print(G1.range_geometry().shape, '2D no channels') G4 = GradientOperator(ig3, correlation = 'SpaceChannels', backend='numpy') print(G4.range_geometry().shape, '2D with channels corr') G5 = GradientOperator(ig3, correlation = 'Space', backend='numpy') print(G5.range_geometry().shape, '2D with channels no corr') G6 = GradientOperator(ig4, correlation = 'Space', backend='numpy') print(G6.range_geometry().shape, '3D with channels no corr') G7 = GradientOperator(ig4, correlation = 'SpaceChannels', backend='numpy') print(G7.range_geometry().shape, '3D with channels with corr') u = ig1.allocate(ImageGeometry.RANDOM) w = G1.range_geometry().allocate(ImageGeometry.RANDOM) LHS = (G1.direct(u)*w).sum() RHS = (u * G1.adjoint(w)).sum() numpy.testing.assert_approx_equal(LHS, RHS, significant = 1) numpy.testing.assert_approx_equal(G1.norm(), numpy.sqrt(2*4), significant = 1) u1 = ig3.allocate('random') w1 = G4.range_geometry().allocate('random') LHS1 = (G4.direct(u1) * w1).sum() RHS1 = (u1 * G4.adjoint(w1)).sum() numpy.testing.assert_approx_equal(LHS1, RHS1, significant=1) numpy.testing.assert_almost_equal(G4.norm(), numpy.sqrt(3*4), decimal = 0) u2 = ig4.allocate('random') w2 = G7.range_geometry().allocate('random') LHS2 = (G7.direct(u2) * w2).sum() RHS2 = (u2 * G7.adjoint(w2)).sum() numpy.testing.assert_approx_equal(LHS2, RHS2, significant = 3) numpy.testing.assert_approx_equal(G7.norm(), numpy.sqrt(3*4), significant = 1) #check direct/adjoint for space/channels correlation ig_channel = ImageGeometry(voxel_num_x = 2, voxel_num_y = 3, channels = 2) G_no_channel = GradientOperator(ig_channel, correlation = 'Space', backend='numpy') G_channel = GradientOperator(ig_channel, correlation = 'SpaceChannels', backend='numpy') u3 = ig_channel.allocate('random_int') res_no_channel = G_no_channel.direct(u3) res_channel = G_channel.direct(u3) print(" Derivative for 3 directions, first is wrt Channel direction\n") print(res_channel[0].as_array()) print(res_channel[1].as_array()) print(res_channel[2].as_array()) print(" Derivative for 2 directions, no Channel direction\n") print(res_no_channel[0].as_array()) print(res_no_channel[1].as_array()) ig2D = ImageGeometry(voxel_num_x = 2, voxel_num_y = 3) u4 = ig2D.allocate('random_int') G2D = GradientOperator(ig2D, backend='numpy') res = G2D.direct(u4) print(res[0].as_array()) print(res[1].as_array()) M, N = 20, 30 ig = ImageGeometry(M, N) # check direct of GradientOperator and sparse matrix G = GradientOperator(ig, backend='numpy') norm1 = G.norm(iterations=300) print ("should be sqrt(8) {} {}".format(numpy.sqrt(8), norm1)) numpy.testing.assert_almost_equal(norm1, numpy.sqrt(8), decimal=1) ig4 = ImageGeometry(M,N, channels=3) G4 = GradientOperator(ig4, correlation="SpaceChannels", backend='numpy') norm4 = G4.norm(iterations=300) print("should be sqrt(12) {} {}".format(numpy.sqrt(12), norm4)) self.assertTrue((norm4 - numpy.sqrt(12))/norm4 < 0.2)
def test_Gradient_c_numpy_voxel(self): numpy.random.seed(5) print("Test GradientOperator for 2D Geometry, ") ny, nx, nz = 3, 4, 5 ig = ImageGeometry(voxel_num_y = ny, voxel_num_x = nx, voxel_size_x=0.1, voxel_size_y=0.5) GD_C = GradientOperator(ig, backend = 'c') GD_numpy = GradientOperator(ig, backend = 'numpy') id = ig.allocate('random') direct_c = GD_C.direct(id) direct_numpy = GD_numpy.direct(id) numpy.testing.assert_allclose(direct_c[0].array, direct_numpy[0].array, atol=0.1) numpy.testing.assert_allclose(direct_c[1].array, direct_numpy[1].array, atol=0.1) direct_c *=0 direct_numpy *=0 GD_C.direct(id, out=direct_c) GD_numpy.direct(id, out=direct_numpy) numpy.testing.assert_allclose(direct_c[0].array, direct_numpy[0].array, atol=0.1) numpy.testing.assert_allclose(direct_c[1].array, direct_numpy[1].array, atol=0.1) adjoint_c = GD_C.adjoint(direct_c) adjoint_numpy = GD_numpy.adjoint(direct_numpy) numpy.testing.assert_allclose(adjoint_c.array, adjoint_numpy.array, atol=0.1) numpy.testing.assert_allclose(adjoint_c.array, adjoint_numpy.array, atol=0.1) adjoint_c *=0 adjoint_numpy *=0 GD_C.adjoint(direct_c, out=adjoint_c) GD_numpy.adjoint(direct_numpy, out=adjoint_numpy) numpy.testing.assert_allclose(adjoint_c.array, adjoint_numpy.array, atol=0.1) numpy.testing.assert_allclose(adjoint_c.array, adjoint_numpy.array, atol=0.1) print("Check Gradient_C, Gradient_numpy norms") Gradient_C_norm = GD_C.norm() Gradient_numpy_norm = GD_numpy.norm() print(Gradient_C_norm, Gradient_numpy_norm) numpy.testing.assert_allclose(Gradient_C_norm, Gradient_numpy_norm, rtol=0.1) numpy.testing.assert_allclose(numpy.sqrt((2/ig.voxel_size_x)**2 + (2/ig.voxel_size_y)**2), Gradient_numpy_norm, rtol=0.1) numpy.testing.assert_allclose(numpy.sqrt((2/ig.voxel_size_x)**2 + (2/ig.voxel_size_y)**2), Gradient_C_norm, rtol=0.1) print("Test passed\n") print("Check dot test") self.assertTrue(GD_C.dot_test(GD_C)) self.assertTrue(GD_numpy.dot_test(GD_numpy)) print("Test passed\n") print("Check dot test for Gradient Numpy with different method/bdn_cond") G_numpy1 = GradientOperator(ig, method = 'forward', bnd_cond = 'Neumann') self.assertTrue(G_numpy1.dot_test(G_numpy1)) G_numpy1 = GradientOperator(ig, method = 'backward', bnd_cond = 'Neumann') self.assertTrue(G_numpy1.dot_test(G_numpy1)) G_numpy1 = GradientOperator(ig, method = 'centered', bnd_cond = 'Neumann') self.assertTrue(G_numpy1.dot_test(G_numpy1)) G_numpy1 = GradientOperator(ig, method = 'forward', bnd_cond = 'Periodic') self.assertTrue(G_numpy1.dot_test(G_numpy1)) G_numpy1 = GradientOperator(ig, method = 'backward', bnd_cond = 'Periodic') self.assertTrue(G_numpy1.dot_test(G_numpy1)) G_numpy1 = GradientOperator(ig, method = 'centered', bnd_cond = 'Periodic') self.assertTrue(G_numpy1.dot_test(G_numpy1)) print("Test passed\n") print("Test GradientOperator for 2D Geometry passed\n") ########################################################################### ########################################################################### ########################################################################### ########################################################################### print("Test GradientOperator for 3D Geometry, ") ig = ImageGeometry(voxel_num_y = ny, voxel_num_x = nx, voxel_num_z = nz, voxel_size_x=0.1, voxel_size_y=0.5, voxel_size_z = 0.4) GD_C = GradientOperator(ig, backend = 'c') GD_numpy = GradientOperator(ig, backend = 'numpy') numpy.random.seed(5) print("Check Gradient_C, Gradient_numpy norms") Gradient_C_norm = GD_C.norm() Gradient_numpy_norm = GD_numpy.norm() numpy.testing.assert_allclose(Gradient_C_norm, Gradient_numpy_norm, rtol=0.1) numpy.testing.assert_allclose(numpy.sqrt((2/ig.voxel_size_z)**2 + (2/ig.voxel_size_x)**2 + (2/ig.voxel_size_y)**2), Gradient_numpy_norm, rtol=0.1) numpy.testing.assert_allclose(numpy.sqrt((2/ig.voxel_size_z)**2 + (2/ig.voxel_size_x)**2 + (2/ig.voxel_size_y)**2), Gradient_C_norm, rtol=0.1) print("Test passed\n") print("Check dot test") self.assertTrue(GD_C.dot_test(GD_C)) self.assertTrue(GD_numpy.dot_test(GD_numpy)) print("Test passed\n") print("Check dot test for GradientOperator Numpy with different method/bdn_cond") G_numpy1 = GradientOperator(ig, method = 'forward', bnd_cond = 'Neumann') self.assertTrue(G_numpy1.dot_test(G_numpy1)) G_numpy1 = GradientOperator(ig, method = 'backward', bnd_cond = 'Neumann') self.assertTrue(G_numpy1.dot_test(G_numpy1)) G_numpy1 = GradientOperator(ig, method = 'centered', bnd_cond = 'Neumann') self.assertTrue(G_numpy1.dot_test(G_numpy1)) G_numpy1 = GradientOperator(ig, method = 'forward', bnd_cond = 'Periodic') self.assertTrue(G_numpy1.dot_test(G_numpy1)) G_numpy1 = GradientOperator(ig, method = 'backward', bnd_cond = 'Periodic') self.assertTrue(G_numpy1.dot_test(G_numpy1)) G_numpy1 = GradientOperator(ig, method = 'centered', bnd_cond = 'Periodic') self.assertTrue(G_numpy1.dot_test(G_numpy1)) print("Test passed\n") print("Test GradientOperator for 3D Geometry passed\n") ########################################################################### ########################################################################### ########################################################################### ########################################################################### print("Test GradientOperator for 2D Geometry + channels, ") ig = ImageGeometry(5,10, voxel_size_x=0.1, voxel_size_y=0.5, channels = 10) GD_C = GradientOperator(ig, backend = 'c') GD_numpy = GradientOperator(ig, backend = 'numpy') print("Check Gradient_C, Gradient_numpy norms") Gradient_C_norm = GD_C.norm() Gradient_numpy_norm = GD_numpy.norm() numpy.testing.assert_allclose(Gradient_C_norm, Gradient_numpy_norm, rtol=0.1) print("Test passed\n") print("Check dot test") self.assertTrue(GD_C.dot_test(GD_C)) self.assertTrue(GD_numpy.dot_test(GD_numpy)) print("Test passed\n") print("Check dot test for GradientOperator Numpy with different method/bdn_cond") G_numpy1 = GradientOperator(ig, method = 'forward', bnd_cond = 'Neumann') self.assertTrue(G_numpy1.dot_test(G_numpy1)) G_numpy1 = GradientOperator(ig, method = 'backward', bnd_cond = 'Neumann') self.assertTrue(G_numpy1.dot_test(G_numpy1)) G_numpy1 = GradientOperator(ig, method = 'centered', bnd_cond = 'Neumann') self.assertTrue(G_numpy1.dot_test(G_numpy1)) G_numpy1 = GradientOperator(ig, method = 'forward', bnd_cond = 'Periodic') self.assertTrue(G_numpy1.dot_test(G_numpy1)) G_numpy1 = GradientOperator(ig, method = 'backward', bnd_cond = 'Periodic') self.assertTrue(G_numpy1.dot_test(G_numpy1)) G_numpy1 = GradientOperator(ig, method = 'centered', bnd_cond = 'Periodic') self.assertTrue(G_numpy1.dot_test(G_numpy1)) print("Test passed\n") print("Test GradientOperator for 2D Geometry + channels passed\n") ########################################################################### ########################################################################### ########################################################################### ########################################################################### print("Test GradientOperator for 3D Geometry + channels, ") ig = ImageGeometry(voxel_num_x = nx, voxel_num_y = ny, voxel_num_z=nz, voxel_size_x=0.1, voxel_size_y=0.5, voxel_size_z = 0.3, channels = 10) GD_C = GradientOperator(ig, backend = 'c') GD_numpy = GradientOperator(ig, backend = 'numpy') print("Check Gradient_C, Gradient_numpy norms") Gradient_C_norm = GD_C.norm() Gradient_numpy_norm = GD_numpy.norm() numpy.testing.assert_allclose(Gradient_C_norm, Gradient_numpy_norm, rtol=0.1) print("Test passed\n") print("Check dot test") self.assertTrue(GD_C.dot_test(GD_C)) self.assertTrue(GD_numpy.dot_test(GD_numpy)) print("Test passed\n") print("Check dot test for Gradient Numpy with different method/bdn_cond") G_numpy1 = GradientOperator(ig, method = 'forward', bnd_cond = 'Neumann') self.assertTrue(G_numpy1.dot_test(G_numpy1)) G_numpy1 = GradientOperator(ig, method = 'backward', bnd_cond = 'Neumann') self.assertTrue(G_numpy1.dot_test(G_numpy1)) G_numpy1 = GradientOperator(ig, method = 'centered', bnd_cond = 'Neumann') self.assertTrue(G_numpy1.dot_test(G_numpy1)) G_numpy1 = GradientOperator(ig, method = 'forward', bnd_cond = 'Periodic') self.assertTrue(G_numpy1.dot_test(G_numpy1)) G_numpy1 = GradientOperator(ig, method = 'backward', bnd_cond = 'Periodic') self.assertTrue(G_numpy1.dot_test(G_numpy1)) G_numpy1 = GradientOperator(ig, method = 'centered', bnd_cond = 'Periodic') self.assertTrue(G_numpy1.dot_test(G_numpy1)) print("Test passed\n") print("Test GradientOperator for 3D Geometry + channels passed\n")
def test_PDHG_Denoising(self): print("PDHG Denoising with 3 noises") # adapted from demo PDHG_TV_Color_Denoising.py in CIL-Demos repository data = dataexample.PEPPERS.get(size=(256, 256)) ig = data.geometry ag = ig which_noise = 0 # Create noisy data. noises = ['gaussian', 'poisson', 's&p'] dnoise = noises[which_noise] 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 noisy_data, alpha, g = setup(data, dnoise) operator = GradientOperator( ig, correlation=GradientOperator.CORRELATION_SPACE) f1 = alpha * MixedL21Norm() # Compute operator Norm normK = operator.norm() # Primal & dual stepsizes sigma = 1 tau = 1 / (sigma * normK**2) # Setup and run the PDHG algorithm pdhg1 = PDHG(f=f1, g=g, operator=operator, tau=tau, sigma=sigma) pdhg1.max_iteration = 2000 pdhg1.update_objective_interval = 200 pdhg1.run(1000, verbose=0) rmse = (pdhg1.get_output() - data).norm() / data.as_array().size if debug_print: print("RMSE", rmse) self.assertLess(rmse, 2e-4) which_noise = 1 noise = noises[which_noise] noisy_data, alpha, g = setup(data, noise) operator = GradientOperator( ig, correlation=GradientOperator.CORRELATION_SPACE) f1 = alpha * MixedL21Norm() # Compute operator Norm normK = operator.norm() # Primal & dual stepsizes sigma = 1 tau = 1 / (sigma * normK**2) # Setup and run the PDHG algorithm pdhg1 = PDHG(f=f1, g=g, operator=operator, tau=tau, sigma=sigma, max_iteration=2000, update_objective_interval=200) pdhg1.run(1000, verbose=0) rmse = (pdhg1.get_output() - data).norm() / data.as_array().size if debug_print: print("RMSE", rmse) self.assertLess(rmse, 2e-4) which_noise = 2 noise = noises[which_noise] noisy_data, alpha, g = setup(data, noise) operator = GradientOperator( ig, correlation=GradientOperator.CORRELATION_SPACE) f1 = alpha * MixedL21Norm() # Compute operator Norm normK = operator.norm() # Primal & dual stepsizes sigma = 1 tau = 1 / (sigma * normK**2) # Setup and run the PDHG algorithm pdhg1 = PDHG(f=f1, g=g, operator=operator, tau=tau, sigma=sigma) pdhg1.max_iteration = 2000 pdhg1.update_objective_interval = 200 pdhg1.run(1000, verbose=0) rmse = (pdhg1.get_output() - data).norm() / data.as_array().size if debug_print: print("RMSE", rmse) self.assertLess(rmse, 2e-4)