def test_ScaledBlockOperatorScalarList(self): ig = [ ImageGeometry(2,3) , \ #ImageGeometry(10,20,30) , \ ImageGeometry(2,3 ) ] x = [g.allocate() for g in ig] ops = [IdentityOperator(g) for g in ig] # test limit as non Scaled scalar = numpy.asarray([1 for _ in x]) k = BlockOperator(*ops) K = scalar * k val = 1 X = BlockDataContainer(*x) + val Y = K.T.direct(X) self.assertTrue(Y.shape == (1, 1)) zero = numpy.zeros(X.get_item(0).shape) xx = numpy.asarray([val for _ in x]) numpy.testing.assert_array_equal( Y.get_item(0).as_array(), (scalar * xx).sum() + zero) scalar = numpy.asarray([i + 1 for i, el in enumerate(x)]) #scalar = numpy.asarray([6,0]) k = BlockOperator(*ops) K = scalar * k X = BlockDataContainer(*x) + val Y = K.T.direct(X) self.assertTrue(Y.shape == (1, 1)) zero = numpy.zeros(X.get_item(0).shape) xx = numpy.asarray([val for _ in x]) numpy.testing.assert_array_equal( Y.get_item(0).as_array(), (scalar * xx).sum() + zero)
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_ScaledBlockOperatorSingleScalar(self): ig = [ ImageGeometry(10,20,30) , \ ImageGeometry(10,20,30) , \ ImageGeometry(10,20,30) ] x = [g.allocate() for g in ig] ops = [IdentityOperator(g) for g in ig] val = 1 # test limit as non Scaled scalar = 1 k = BlockOperator(*ops) K = scalar * k X = BlockDataContainer(*x) + val Y = K.T.direct(X) self.assertTrue(Y.shape == (1, 1)) zero = numpy.zeros(X.get_item(0).shape) xx = numpy.asarray([val for _ in x]) numpy.testing.assert_array_equal( Y.get_item(0).as_array(), ((scalar * xx).sum() + zero)) scalar = 0.5 k = BlockOperator(*ops) K = scalar * k X = BlockDataContainer(*x) + 1 Y = K.T.direct(X) self.assertTrue(Y.shape == (1, 1)) zero = numpy.zeros(X.get_item(0).shape) numpy.testing.assert_array_equal( Y.get_item(0).as_array(), scalar * (len(x) + zero))
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_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_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 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_timedifference(self): print("test_timedifference") M, N, W = 100, 512, 512 ig = ImageGeometry(M, N, W) arr = ig.allocate('random') G = GradientOperator(ig, backend='numpy') Id = IdentityOperator(ig) B = BlockOperator(G, Id) # Nx1 case u = ig.allocate('random') steps = [timer()] i = 0 n = 10. t1 = t2 = 0 res = B.range_geometry().allocate() while (i < n): print("i ", i) steps.append(timer()) z1 = B.direct(u) steps.append(timer()) t = dt(steps) #print ("B.direct(u) " ,t) t1 += t / n steps.append(timer()) B.direct(u, out=res) steps.append(timer()) t = dt(steps) #print ("B.direct(u, out=res) " ,t) t2 += t / n i += 1 print("Time difference ", t1, t2) self.assertGreater(t1, t2) steps = [timer()] i = 0 #n = 50. t1 = t2 = 0 resd = B.domain_geometry().allocate() z1 = B.direct(u) #B.adjoint(z1, out=resd) print(type(res)) while (i < n): print("i ", i) steps.append(timer()) w1 = B.adjoint(z1) steps.append(timer()) t = dt(steps) #print ("B.adjoint(z1) " ,t) t1 += t / n steps.append(timer()) B.adjoint(z1, out=resd) steps.append(timer()) t = dt(steps) #print ("B.adjoint(z1, out=res) " ,t) t2 += t / n i += 1 print("Time difference ", t1, t2)
def test_BlockOperator(self): print("test_BlockOperator") M, N = 3, 4 ig = ImageGeometry(M, N) arr = ig.allocate('random') G = GradientOperator(ig) Id = IdentityOperator(ig) B = BlockOperator(G, Id) # Nx1 case u = ig.allocate('random') z1 = B.direct(u) res = B.range_geometry().allocate() #res = z1.copy() B.direct(u, out=res) print(type(z1), type(res)) print(z1.shape) print(z1[0][0].as_array()) print(res[0][0].as_array()) self.assertBlockDataContainerEqual(z1, res) # for col in range(z1.shape[0]): # a = z1.get_item(col) # b = res.get_item(col) # if isinstance(a, BlockDataContainer): # for col2 in range(a.shape[0]): # self.assertNumpyArrayEqual( # a.get_item(col2).as_array(), # b.get_item(col2).as_array() # ) # else: # self.assertNumpyArrayEqual( # a.as_array(), # b.as_array() # ) z1 = B.range_geometry().allocate(ImageGeometry.RANDOM) res1 = B.adjoint(z1) res2 = B.domain_geometry().allocate() B.adjoint(z1, out=res2) self.assertNumpyArrayEqual(res1.as_array(), res2.as_array()) BB = BlockOperator(Id, 2 * Id) B = BlockOperator(BB, Id) v = B.domain_geometry().allocate() B.adjoint(res, out=v) vv = B.adjoint(res) el1 = B.get_item(0,0).adjoint(z1.get_item(0)) +\ B.get_item(1,0).adjoint(z1.get_item(1)) print("el1", el1.as_array()) print("vv", vv.as_array()) print("v", v.as_array()) self.assertNumpyArrayEqual(v.as_array(), vv.as_array()) # test adjoint print("############ 2x1 #############") BB = BlockOperator(Id, 2 * Id) u = ig.allocate(1) z1 = BB.direct(u) print("z1 shape {} one\n{} two\n{}".format(z1.shape, z1.get_item(0).as_array(), z1.get_item(1).as_array())) res = BB.range_geometry().allocate(0) BB.direct(u, out=res) print("res shape {} one\n{} two\n{}".format( res.shape, res.get_item(0).as_array(), res.get_item(1).as_array())) self.assertNumpyArrayEqual(z1.get_item(0).as_array(), u.as_array()) self.assertNumpyArrayEqual(z1.get_item(1).as_array(), 2 * u.as_array()) self.assertNumpyArrayEqual(res.get_item(0).as_array(), u.as_array()) self.assertNumpyArrayEqual( res.get_item(1).as_array(), 2 * u.as_array()) x1 = BB.adjoint(z1) print("adjoint x1\n", x1.as_array()) res1 = BB.domain_geometry().allocate() BB.adjoint(z1, out=res1) print("res1\n", res1.as_array()) self.assertNumpyArrayEqual(x1.as_array(), res1.as_array()) self.assertNumpyArrayEqual(x1.as_array(), 5 * u.as_array()) self.assertNumpyArrayEqual(res1.as_array(), 5 * u.as_array()) ################################################# print("############ 2x2 #############") BB = BlockOperator(Id, 2 * Id, 3 * Id, Id, shape=(2, 2)) B = BB u = ig.allocate(1) U = BlockDataContainer(u, u) z1 = B.direct(U) print("z1 shape {} one\n{} two\n{}".format(z1.shape, z1.get_item(0).as_array(), z1.get_item(1).as_array())) self.assertNumpyArrayEqual(z1.get_item(0).as_array(), 3 * u.as_array()) self.assertNumpyArrayEqual(z1.get_item(1).as_array(), 4 * u.as_array()) res = B.range_geometry().allocate() B.direct(U, out=res) self.assertNumpyArrayEqual( res.get_item(0).as_array(), 3 * u.as_array()) self.assertNumpyArrayEqual( res.get_item(1).as_array(), 4 * u.as_array()) x1 = B.adjoint(z1) # this should be [15 u, 10 u] el1 = B.get_item(0, 0).adjoint(z1.get_item(0)) + B.get_item( 1, 0).adjoint(z1.get_item(1)) el2 = B.get_item(0, 1).adjoint(z1.get_item(0)) + B.get_item( 1, 1).adjoint(z1.get_item(1)) shape = B.get_output_shape(z1.shape, adjoint=True) print("shape ", shape) out = B.domain_geometry().allocate() for col in range(B.shape[1]): for row in range(B.shape[0]): if row == 0: el = B.get_item(row, col).adjoint(z1.get_item(row)) else: el += B.get_item(row, col).adjoint(z1.get_item(row)) out.get_item(col).fill(el) print("el1 ", el1.as_array()) print("el2 ", el2.as_array()) print("out shape {} one\n{} two\n{}".format( out.shape, out.get_item(0).as_array(), out.get_item(1).as_array())) self.assertNumpyArrayEqual( out.get_item(0).as_array(), 15 * u.as_array()) self.assertNumpyArrayEqual( out.get_item(1).as_array(), 10 * u.as_array()) res2 = B.domain_geometry().allocate() #print (res2, res2.as_array()) B.adjoint(z1, out=res2) #print ("adjoint",x1.as_array(),"\n",res2.as_array()) self.assertNumpyArrayEqual( out.get_item(0).as_array(), res2.get_item(0).as_array()) self.assertNumpyArrayEqual( out.get_item(1).as_array(), res2.get_item(1).as_array()) if True: #B1 = BlockOperator(Id, Id, Id, Id, shape=(2,2)) B1 = BlockOperator(G, Id) U = ig.allocate(ImageGeometry.RANDOM) #U = BlockDataContainer(u,u) RES1 = B1.range_geometry().allocate() Z1 = B1.direct(U) B1.direct(U, out=RES1) self.assertBlockDataContainerEqual(Z1, RES1) print("U", U.as_array()) print("Z1", Z1[0][0].as_array()) print("RES1", RES1[0][0].as_array()) print("Z1", Z1[0][1].as_array()) print("RES1", RES1[0][1].as_array())
def test_SPDHG_vs_SPDHG_explicit_axpby(self): data = dataexample.SIMPLE_PHANTOM_2D.get(size=(128, 128)) if debug_print: print("test_SPDHG_vs_SPDHG_explicit_axpby here") ig = data.geometry ig.voxel_size_x = 0.1 ig.voxel_size_y = 0.1 detectors = ig.shape[0] angles = np.linspace(0, np.pi, 180) ag = AcquisitionGeometry('parallel', '2D', angles, detectors, pixel_size_h=0.1, angle_unit='radian') # Select device # device = input('Available device: GPU==1 / CPU==0 ') # if device=='1': # dev = 'gpu' # else: # dev = 'cpu' dev = 'cpu' Aop = AstraProjectorSimple(ig, ag, dev) sin = Aop.direct(data) # Create noisy data. Apply Gaussian noise noises = ['gaussian', 'poisson'] noise = noises[1] if noise == 'poisson': np.random.seed(10) scale = 5 eta = 0 noisy_data = AcquisitionData( np.random.poisson(scale * (eta + sin.as_array())) / scale, geometry=ag) elif noise == 'gaussian': np.random.seed(10) n1 = np.random.normal(0, 0.1, size=ag.shape) noisy_data = AcquisitionData(n1 + sin.as_array(), geometry=ag) else: raise ValueError('Unsupported Noise ', noise) #%% 'explicit' SPDHG, scalar step-sizes subsets = 10 size_of_subsets = int(len(angles) / subsets) # create GradientOperator operator op1 = GradientOperator(ig) # take angles and create uniform subsets in uniform+sequential setting list_angles = [ angles[i:i + size_of_subsets] for i in range(0, len(angles), size_of_subsets) ] # create acquisitioin geometries for each the interval of splitting angles list_geoms = [ AcquisitionGeometry('parallel', '2D', list_angles[i], detectors, pixel_size_h=0.1, angle_unit='radian') for i in range(len(list_angles)) ] # create with operators as many as the subsets A = BlockOperator(*[ AstraProjectorSimple(ig, list_geoms[i], dev) for i in range(subsets) ] + [op1]) ## number of subsets #(sub2ind, ind2sub) = divide_1Darray_equally(range(len(A)), subsets) # ## acquisisiton data ## acquisisiton data AD_list = [] for sub_num in range(subsets): for i in range(0, len(angles), size_of_subsets): arr = noisy_data.as_array()[i:i + size_of_subsets, :] AD_list.append( AcquisitionData(arr, geometry=list_geoms[sub_num])) g = BlockDataContainer(*AD_list) alpha = 0.5 ## block function F = BlockFunction(*[ *[KullbackLeibler(b=g[i]) for i in range(subsets)] + [alpha * MixedL21Norm()] ]) G = IndicatorBox(lower=0) prob = [1 / (2 * subsets)] * (len(A) - 1) + [1 / 2] algos = [] algos.append( SPDHG(f=F, g=G, operator=A, max_iteration=1000, update_objective_interval=200, prob=prob.copy(), use_axpby=True)) algos[0].run(1000, verbose=0) algos.append( SPDHG(f=F, g=G, operator=A, max_iteration=1000, update_objective_interval=200, prob=prob.copy(), use_axpby=False)) algos[1].run(1000, verbose=0) # np.testing.assert_array_almost_equal(algos[0].get_output().as_array(), algos[1].get_output().as_array()) from cil.utilities.quality_measures import mae, mse, psnr qm = (mae(algos[0].get_output(), algos[1].get_output()), mse(algos[0].get_output(), algos[1].get_output()), psnr(algos[0].get_output(), algos[1].get_output())) if debug_print: print("Quality measures", qm) assert qm[0] < 0.005 assert qm[1] < 3.e-05
def test_SPDHG_vs_PDHG_explicit(self): data = dataexample.SIMPLE_PHANTOM_2D.get(size=(128, 128)) ig = data.geometry ig.voxel_size_x = 0.1 ig.voxel_size_y = 0.1 detectors = ig.shape[0] angles = np.linspace(0, np.pi, 180) ag = AcquisitionGeometry('parallel', '2D', angles, detectors, pixel_size_h=0.1, angle_unit='radian') # Select device dev = 'cpu' Aop = AstraProjectorSimple(ig, ag, dev) sin = Aop.direct(data) # Create noisy data. Apply Gaussian noise noises = ['gaussian', 'poisson'] noise = noises[1] if noise == 'poisson': scale = 5 noisy_data = scale * applynoise.poisson(sin / scale, seed=10) # np.random.seed(10) # scale = 5 # eta = 0 # noisy_data = AcquisitionData(np.random.poisson( scale * (eta + sin.as_array()))/scale, ag) elif noise == 'gaussian': noisy_data = noise.gaussian(sin, var=0.1, seed=10) # np.random.seed(10) # n1 = np.random.normal(0, 0.1, size = ag.shape) # noisy_data = AcquisitionData(n1 + sin.as_array(), ag) else: raise ValueError('Unsupported Noise ', noise) #%% 'explicit' SPDHG, scalar step-sizes subsets = 10 size_of_subsets = int(len(angles) / subsets) # create Gradient operator op1 = GradientOperator(ig) # take angles and create uniform subsets in uniform+sequential setting list_angles = [ angles[i:i + size_of_subsets] for i in range(0, len(angles), size_of_subsets) ] # create acquisitioin geometries for each the interval of splitting angles list_geoms = [ AcquisitionGeometry('parallel', '2D', list_angles[i], detectors, pixel_size_h=0.1, angle_unit='radian') for i in range(len(list_angles)) ] # create with operators as many as the subsets A = BlockOperator(*[ AstraProjectorSimple(ig, list_geoms[i], dev) for i in range(subsets) ] + [op1]) ## number of subsets #(sub2ind, ind2sub) = divide_1Darray_equally(range(len(A)), subsets) # ## acquisisiton data ## acquisisiton data AD_list = [] for sub_num in range(subsets): for i in range(0, len(angles), size_of_subsets): arr = noisy_data.as_array()[i:i + size_of_subsets, :] AD_list.append( AcquisitionData(arr, geometry=list_geoms[sub_num])) g = BlockDataContainer(*AD_list) alpha = 0.5 ## block function F = BlockFunction(*[ *[KullbackLeibler(b=g[i]) for i in range(subsets)] + [alpha * MixedL21Norm()] ]) G = IndicatorBox(lower=0) prob = [1 / (2 * subsets)] * (len(A) - 1) + [1 / 2] spdhg = SPDHG(f=F, g=G, operator=A, max_iteration=1000, update_objective_interval=200, prob=prob) spdhg.run(1000, verbose=0) #%% 'explicit' PDHG, scalar step-sizes op1 = GradientOperator(ig) op2 = Aop # Create BlockOperator operator = BlockOperator(op1, op2, shape=(2, 1)) f2 = KullbackLeibler(b=noisy_data) g = IndicatorBox(lower=0) normK = operator.norm() sigma = 1 / normK tau = 1 / normK f1 = alpha * MixedL21Norm() f = BlockFunction(f1, f2) # Setup and run the PDHG algorithm pdhg = PDHG(f=f, g=g, operator=operator, tau=tau, sigma=sigma) pdhg.max_iteration = 1000 pdhg.update_objective_interval = 200 pdhg.run(1000, verbose=0) #%% show diff between PDHG and SPDHG # plt.imshow(spdhg.get_output().as_array() -pdhg.get_output().as_array()) # plt.colorbar() # plt.show() from cil.utilities.quality_measures import mae, mse, psnr qm = (mae(spdhg.get_output(), pdhg.get_output()), mse(spdhg.get_output(), pdhg.get_output()), psnr(spdhg.get_output(), pdhg.get_output())) if debug_print: print("Quality measures", qm) np.testing.assert_almost_equal(mae(spdhg.get_output(), pdhg.get_output()), 0.00150, decimal=3) np.testing.assert_almost_equal(mse(spdhg.get_output(), pdhg.get_output()), 1.68590e-05, decimal=3)
def test_SPDHG_vs_PDHG_implicit(self): data = dataexample.SIMPLE_PHANTOM_2D.get(size=(128, 128)) ig = data.geometry ig.voxel_size_x = 0.1 ig.voxel_size_y = 0.1 detectors = ig.shape[0] angles = np.linspace(0, np.pi, 90) ag = AcquisitionGeometry('parallel', '2D', angles, detectors, pixel_size_h=0.1, angle_unit='radian') # Select device dev = 'cpu' Aop = AstraProjectorSimple(ig, ag, dev) sin = Aop.direct(data) # Create noisy data. Apply Gaussian noise noises = ['gaussian', 'poisson'] noise = noises[1] noisy_data = ag.allocate() if noise == 'poisson': np.random.seed(10) scale = 20 eta = 0 noisy_data.fill( np.random.poisson(scale * (eta + sin.as_array())) / scale) elif noise == 'gaussian': np.random.seed(10) n1 = np.random.normal(0, 0.1, size=ag.shape) noisy_data.fill(n1 + sin.as_array()) else: raise ValueError('Unsupported Noise ', noise) # Create BlockOperator operator = Aop f = KullbackLeibler(b=noisy_data) alpha = 0.005 g = alpha * TotalVariation(50, 1e-4, lower=0) normK = operator.norm() #% 'implicit' PDHG, preconditioned step-sizes tau_tmp = 1. sigma_tmp = 1. tau = sigma_tmp / operator.adjoint( tau_tmp * operator.range_geometry().allocate(1.)) sigma = tau_tmp / operator.direct( sigma_tmp * operator.domain_geometry().allocate(1.)) # initial = operator.domain_geometry().allocate() # # Setup and run the PDHG algorithm pdhg = PDHG(f=f, g=g, operator=operator, tau=tau, sigma=sigma, max_iteration=1000, update_objective_interval=500) pdhg.run(verbose=0) subsets = 10 size_of_subsets = int(len(angles) / subsets) # take angles and create uniform subsets in uniform+sequential setting list_angles = [ angles[i:i + size_of_subsets] for i in range(0, len(angles), size_of_subsets) ] # create acquisitioin geometries for each the interval of splitting angles list_geoms = [ AcquisitionGeometry('parallel', '2D', list_angles[i], detectors, pixel_size_h=0.1, angle_unit='radian') for i in range(len(list_angles)) ] # create with operators as many as the subsets A = BlockOperator(*[ AstraProjectorSimple(ig, list_geoms[i], dev) for i in range(subsets) ]) ## number of subsets #(sub2ind, ind2sub) = divide_1Darray_equally(range(len(A)), subsets) # ## acquisisiton data AD_list = [] for sub_num in range(subsets): for i in range(0, len(angles), size_of_subsets): arr = noisy_data.as_array()[i:i + size_of_subsets, :] AD_list.append( AcquisitionData(arr, geometry=list_geoms[sub_num])) g = BlockDataContainer(*AD_list) ## block function F = BlockFunction(*[KullbackLeibler(b=g[i]) for i in range(subsets)]) G = alpha * TotalVariation(50, 1e-4, lower=0) prob = [1 / len(A)] * len(A) spdhg = SPDHG(f=F, g=G, operator=A, max_iteration=1000, update_objective_interval=200, prob=prob) spdhg.run(1000, verbose=0) from cil.utilities.quality_measures import mae, mse, psnr qm = (mae(spdhg.get_output(), pdhg.get_output()), mse(spdhg.get_output(), pdhg.get_output()), psnr(spdhg.get_output(), pdhg.get_output())) if debug_print: print("Quality measures", qm) np.testing.assert_almost_equal(mae(spdhg.get_output(), pdhg.get_output()), 0.000335, decimal=3) np.testing.assert_almost_equal(mse(spdhg.get_output(), pdhg.get_output()), 5.51141e-06, decimal=3)
max_iteration=10000, update_objective_interval=2) #%% algo.update_objective_interval = 2 algo.run(10, verbose=1) plotter2D(algo.solution, cmap='gist_earth') # %% 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(0.5 * L2NormSquared(b=ldata), alpha * MixedL21Norm()) BK = BlockOperator(K, nabla) normK = BK.norm() pdhg = PDHG(f=F, g=IndicatorBox(lower=0.), operator=BK, max_iteration=1000, update_objective_interval=100) #%% # pdhg.run(1000, verbose=2) #%% plotter2D(pdhg.solution, cmap='gist_earth') # %%
def test_BlockOperator(self): print("test_BlockOperator") ig = [ ImageGeometry(10,20,30) , \ ImageGeometry(10,20,30) , \ ImageGeometry(10,20,30) ] x = [g.allocate() for g in ig] ops = [IdentityOperator(g) for g in ig] K = BlockOperator(*ops) X = BlockDataContainer(x[0]) Y = K.direct(X) self.assertTrue(Y.shape == K.shape) numpy.testing.assert_array_equal( Y.get_item(0).as_array(), X.get_item(0).as_array()) numpy.testing.assert_array_equal( Y.get_item(1).as_array(), X.get_item(0).as_array()) #numpy.testing.assert_array_equal(Y.get_item(2).as_array(),X.get_item(2).as_array()) X = BlockDataContainer(*x) + 1 Y = K.T.direct(X) # K.T (1,3) X (3,1) => output shape (1,1) self.assertTrue(Y.shape == (1, 1)) zero = numpy.zeros(X.get_item(0).shape) numpy.testing.assert_array_equal( Y.get_item(0).as_array(), len(x) + zero) K2 = BlockOperator(*(ops + ops), shape=(3, 2)) Y = K2.T.direct(X) # K.T (2,3) X (3,1) => output shape (2,1) self.assertTrue(Y.shape == (2, 1)) try: # this should fail as the domain is not compatible ig = [ ImageGeometry(10,20,31) , \ ImageGeometry(10,20,30) , \ ImageGeometry(10,20,30) ] x = [g.allocate() for g in ig] ops = [IdentityOperator(g) for g in ig] K = BlockOperator(*ops) self.assertFalse(K.column_wise_compatible()) except ValueError as ve: print(ve) self.assertTrue(True) try: # this should fail as the range is not compatible ig = [ ImageGeometry(10,20,30) , \ ImageGeometry(10,20,30) , \ ImageGeometry(10,20,30) ] rg0 = [ ImageGeometry(10,20,31) , \ ImageGeometry(10,20,31) , \ ImageGeometry(10,20,31) ] rg1 = [ ImageGeometry(10,22,31) , \ ImageGeometry(10,22,31) , \ ImageGeometry(10,20,31) ] x = [g.allocate() for g in ig] ops = [ IdentityOperator(g, range_geometry=r) for g, r in zip(ig, rg0) ] ops += [ IdentityOperator(g, range_geometry=r) for g, r in zip(ig, rg1) ] K = BlockOperator(*ops, shape=(2, 3)) print("K col comp? ", K.column_wise_compatible()) print("K row comp? ", K.row_wise_compatible()) for op in ops: print("range", op.range_geometry().shape) for op in ops: print("domain", op.domain_geometry().shape) self.assertFalse(K.row_wise_compatible()) except ValueError as ve: print(ve) self.assertTrue(True)
# 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) # Setup and run the PDHG algorithm pdhg = PDHG(f=f,g=g,operator=operator, tau=tau, sigma=sigma) pdhg.max_iteration = 10000
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') # %%
if __name__ == '__main__': M, N, K = 20,30,50 from cil.optimisation.functions import L2NormSquared, MixedL21Norm, L1Norm from cil.framework import ImageGeometry, BlockGeometry 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 " )
def test_PDHG_vs_PDHG_explicit_axpby(self): data = dataexample.SIMPLE_PHANTOM_2D.get(size=(128, 128)) if debug_print: print("test_PDHG_vs_PDHG_explicit_axpby here") ig = data.geometry ig.voxel_size_x = 0.1 ig.voxel_size_y = 0.1 detectors = ig.shape[0] angles = np.linspace(0, np.pi, 180) ag = AcquisitionGeometry('parallel', '2D', angles, detectors, pixel_size_h=0.1, angle_unit='radian') dev = 'cpu' Aop = AstraProjectorSimple(ig, ag, dev) sin = Aop.direct(data) # Create noisy data. Apply Gaussian noise noises = ['gaussian', 'poisson'] noise = noises[1] if noise == 'poisson': np.random.seed(10) scale = 5 eta = 0 noisy_data = AcquisitionData( np.random.poisson(scale * (eta + sin.as_array())) / scale, geometry=ag) elif noise == 'gaussian': np.random.seed(10) n1 = np.random.normal(0, 0.1, size=ag.shape) noisy_data = AcquisitionData(n1 + sin.as_array(), geometry=ag) else: raise ValueError('Unsupported Noise ', noise) alpha = 0.5 op1 = GradientOperator(ig) op2 = Aop # Create BlockOperator operator = BlockOperator(op1, op2, shape=(2, 1)) f2 = KullbackLeibler(b=noisy_data) g = IndicatorBox(lower=0) normK = operator.norm() sigma = 1. / normK tau = 1. / normK f1 = alpha * MixedL21Norm() f = BlockFunction(f1, f2) # Setup and run the PDHG algorithm algos = [] algos.append( PDHG(f=f, g=g, operator=operator, tau=tau, sigma=sigma, max_iteration=1000, update_objective_interval=200, use_axpby=True)) algos[0].run(1000, verbose=0) algos.append( PDHG(f=f, g=g, operator=operator, tau=tau, sigma=sigma, max_iteration=1000, update_objective_interval=200, use_axpby=False)) algos[1].run(1000, verbose=0) from cil.utilities.quality_measures import mae, mse, psnr qm = (mae(algos[0].get_output(), algos[1].get_output()), mse(algos[0].get_output(), algos[1].get_output()), psnr(algos[0].get_output(), algos[1].get_output())) if debug_print: print("Quality measures", qm) np.testing.assert_array_less(qm[0], 0.005) np.testing.assert_array_less(qm[1], 3e-05)