def test_CGLS(self): print ("Test CGLS") ig = ImageGeometry(124,153,154) x_init = ImageData(geometry=ig) b = x_init.copy() # fill with random numbers b.fill(numpy.random.random(x_init.shape)) identity = TomoIdentity(geometry=ig) alg = CGLS(x_init=x_init, operator=identity, data=b) alg.max_iteration = 1 alg.run(20, verbose=True) self.assertNumpyArrayAlmostEqual(alg.x.as_array(), b.as_array())
def test_GradientDescent(self): print ("Test GradientDescent") ig = ImageGeometry(12,13,14) x_init = ImageData(geometry=ig) b = x_init.copy() # fill with random numbers b.fill(numpy.random.random(x_init.shape)) identity = TomoIdentity(geometry=ig) norm2sq = Norm2sq(identity, b) alg = GradientDescent(x_init=x_init, objective_function=norm2sq, rate=0.3) alg.max_iteration = 20 alg.run(20, verbose=True) self.assertNumpyArrayAlmostEqual(alg.x.as_array(), b.as_array())
def test_FISTA(self): print ("Test FISTA") ig = ImageGeometry(127,139,149) x_init = ImageData(geometry=ig) b = x_init.copy() # fill with random numbers b.fill(numpy.random.random(x_init.shape)) x_init = ImageData(geometry=ig) x_init.fill(numpy.random.random(x_init.shape)) identity = TomoIdentity(geometry=ig) norm2sq = Norm2sq(identity, b) opt = {'tol': 1e-4, 'memopt':False} alg = FISTA(x_init=x_init, f=norm2sq, g=None, opt=opt) alg.max_iteration = 2 alg.run(20, verbose=True) self.assertNumpyArrayAlmostEqual(alg.x.as_array(), b.as_array()) alg.run(20, verbose=True) self.assertNumpyArrayAlmostEqual(alg.x.as_array(), b.as_array())
# ImageData object with this geometry and empty array and finally put some # data into its array, and display as image. N = 64 ig = ImageGeometry(voxel_num_x=N,voxel_num_y=N) Phantom = ImageData(geometry=ig) x = Phantom.as_array() x[round(N/4):round(3*N/4),round(N/4):round(3*N/4)] = 0.5 x[round(N/8):round(7*N/8),round(3*N/8):round(5*N/8)] = 1 plt.imshow(x) plt.title('Phantom image') plt.show() # Identity operator for denoising I = TomoIdentity(ig) # Data and add noise y = I.direct(Phantom) y.array = y.array + 0.1*np.random.randn(N, N) plt.imshow(y.array) plt.title('Noisy image') plt.show() ################### # Data fidelity term f_denoise = Norm2sq(I,y,c=0.5,memopt=True) # 1-norm regulariser
def test_FISTA_denoise_cvx(self): if not cvx_not_installable: opt = {'memopt': True} N = 64 ig = ImageGeometry(voxel_num_x=N, voxel_num_y=N) Phantom = ImageData(geometry=ig) x = Phantom.as_array() x[int(round(N / 4)):int(round(3 * N / 4)), int(round(N / 4)):int(round(3 * N / 4))] = 0.5 x[int(round(N / 8)):int(round(7 * N / 8)), int(round(3 * N / 8)):int(round(5 * N / 8))] = 1 # Identity operator for denoising I = TomoIdentity(ig) # Data and add noise y = I.direct(Phantom) y.array = y.array + 0.1 * np.random.randn(N, N) # Data fidelity term f_denoise = Norm2sq(I, y, c=0.5, memopt=True) # 1-norm regulariser lam1_denoise = 1.0 g1_denoise = Norm1(lam1_denoise) # Initial guess x_init_denoise = ImageData(np.zeros((N, N))) # Combine with least squares and solve using generic FISTA implementation x_fista1_denoise, it1_denoise, timing1_denoise, \ criter1_denoise = \ FISTA(x_init_denoise, f_denoise, g1_denoise, opt=opt) print(x_fista1_denoise) print(criter1_denoise[-1]) # Now denoise LS + 1-norm with FBPD x_fbpd1_denoise, itfbpd1_denoise, timingfbpd1_denoise,\ criterfbpd1_denoise = \ FBPD(x_init_denoise, I, None, f_denoise, g1_denoise) print(x_fbpd1_denoise) print(criterfbpd1_denoise[-1]) # Compare to CVXPY # Construct the problem. x1_denoise = Variable(N**2, 1) objective1_denoise = Minimize( 0.5 * sum_squares(x1_denoise - y.array.flatten()) + lam1_denoise * norm(x1_denoise, 1)) prob1_denoise = Problem(objective1_denoise) # The optimal objective is returned by prob.solve(). result1_denoise = prob1_denoise.solve(verbose=False, solver=SCS, eps=1e-12) # The optimal solution for x is stored in x.value and optimal objective value # is in result as well as in objective.value print( "CVXPY least squares plus 1-norm solution and objective value:" ) print(x1_denoise.value) print(objective1_denoise.value) self.assertNumpyArrayAlmostEqual(x_fista1_denoise.array.flatten(), x1_denoise.value, 5) self.assertNumpyArrayAlmostEqual(x_fbpd1_denoise.array.flatten(), x1_denoise.value, 5) x1_cvx = x1_denoise.value x1_cvx.shape = (N, N) # Now TV with FBPD lam_tv = 0.1 gtv = TV2D(lam_tv) gtv(gtv.op.direct(x_init_denoise)) opt_tv = {'tol': 1e-4, 'iter': 10000} x_fbpdtv_denoise, itfbpdtv_denoise, timingfbpdtv_denoise,\ criterfbpdtv_denoise = \ FBPD(x_init_denoise, gtv.op, None, f_denoise, gtv, opt=opt_tv) print(x_fbpdtv_denoise) print(criterfbpdtv_denoise[-1]) # Compare to CVXPY # Construct the problem. xtv_denoise = Variable((N, N)) objectivetv_denoise = Minimize(0.5 * sum_squares(xtv_denoise - y.array) + lam_tv * tv(xtv_denoise)) probtv_denoise = Problem(objectivetv_denoise) # The optimal objective is returned by prob.solve(). resulttv_denoise = probtv_denoise.solve(verbose=False, solver=SCS, eps=1e-12) # The optimal solution for x is stored in x.value and optimal objective value # is in result as well as in objective.value print( "CVXPY least squares plus 1-norm solution and objective value:" ) print(xtv_denoise.value) print(objectivetv_denoise.value) self.assertNumpyArrayAlmostEqual(x_fbpdtv_denoise.as_array(), xtv_denoise.value, 1) else: self.assertTrue(cvx_not_installable)