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_PDHG_strongly_convex_gamma_g(self):

        ig = ImageGeometry(3,3)
        data = ig.allocate('random')

        f = L2NormSquared(b=data)
        g = L2NormSquared()
        operator = IdentityOperator(ig)

        # sigma, tau 
        sigma = 1.0
        tau  = 1.0        

        pdhg = PDHG(f=f, g=g, operator=operator, sigma = sigma, tau=tau,
                    max_iteration=5, gamma_g=0.5)
        pdhg.run(1, verbose=0)
        self.assertAlmostEquals(pdhg.theta, 1.0/ np.sqrt(1 + 2 * pdhg.gamma_g * tau))
        self.assertAlmostEquals(pdhg.tau, tau * pdhg.theta)
        self.assertAlmostEquals(pdhg.sigma, sigma / pdhg.theta)
        pdhg.run(4, verbose=0)
        self.assertNotEqual(pdhg.sigma, sigma)
        self.assertNotEqual(pdhg.tau, tau)  

        # check negative strongly convex constant
        with self.assertRaises(ValueError):
            pdhg = PDHG(f=f, g=g, operator=operator, sigma = sigma, tau=tau,
                    max_iteration=5, gamma_g=-0.5)  
        

        # check strongly convex constant not a number
        with self.assertRaises(ValueError):
            pdhg = PDHG(f=f, g=g, operator=operator, sigma = sigma, tau=tau,
                    max_iteration=5, gamma_g="-0.5")  
Ejemplo n.º 3
0
    def test_Norm2sq_as_OperatorCompositionFunction(self):

        print('Test for OperatorCompositionFunction')

        M, N = 50, 50
        ig = ImageGeometry(voxel_num_x=M, voxel_num_y=N)
        #numpy.random.seed(1)
        b = ig.allocate('random', seed=1)

        print('Check call with IdentityOperator operator... OK\n')
        operator = 3 * IdentityOperator(ig)

        u = ig.allocate('random', seed=50)
        f = 0.5 * L2NormSquared(b=b)
        func1 = OperatorCompositionFunction(f, operator)
        func2 = LeastSquares(operator, b, 0.5)
        print("f.L {}".format(f.L))
        print("0.5*f.L {}".format((0.5 * f).L))
        print("type func1 {}".format(type(func1)))
        print("func1.L {}".format(func1.L))
        print("func2.L {}".format(func2.L))
        print("operator.norm() {}".format(operator.norm()))

        numpy.testing.assert_almost_equal(func1(u), func2(u))

        print('Check gradient with IdentityOperator operator... OK\n')

        tmp1 = ig.allocate()
        tmp2 = ig.allocate()
        res_gradient1 = func1.gradient(u)
        res_gradient2 = func2.gradient(u)
        func1.gradient(u, out=tmp1)
        func2.gradient(u, out=tmp2)

        self.assertNumpyArrayAlmostEqual(res_gradient1.as_array(),
                                         res_gradient2.as_array())
        self.assertNumpyArrayAlmostEqual(tmp1.as_array(), tmp2.as_array())

        print('Check call with MatrixOperator... OK\n')
        mat = np.random.randn(M, N)
        operator = MatrixOperator(mat)
        vg = VectorGeometry(N)
        b = vg.allocate('random')
        u = vg.allocate('random')

        func1 = OperatorCompositionFunction(0.5 * L2NormSquared(b=b), operator)
        func2 = LeastSquares(operator, b, 0.5)

        self.assertNumpyArrayAlmostEqual(func1(u), func2(u))
        numpy.testing.assert_almost_equal(func1.L, func2.L)
    def test_PDHG_strongly_convex_both_fconj_and_g(self):

        ig = ImageGeometry(3,3)
        data = ig.allocate('random')

        f = L2NormSquared(b=data)
        g = L2NormSquared()
        operator = IdentityOperator(ig)
    
        try:
            pdhg = PDHG(f=f, g=g, operator=operator, max_iteration=10, 
                        gamma_g = 0.5, gamma_fconj=0.5)
            pdhg.run(verbose=0)
        except ValueError as err:
            print(err)
Ejemplo n.º 5
0
    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)
Ejemplo n.º 6
0
        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
    def test_cil_vs_cvxpy_totalvariation_anisotropic(self):

            # solution
            u_cvx = cvxpy.Variable(self.data.shape)

            # regularisation parameter
            alpha = 0.1

            # fidelity term
            fidelity = 0.5 * cvxpy.sum_squares(u_cvx - self.data.array)   
            regulariser = alpha * self.tv_cvxpy_regulariser(u_cvx, isotropic=False)

            # objective
            obj =  cvxpy.Minimize( regulariser +  fidelity)
            prob = cvxpy.Problem(obj, constraints = [])

            # Choose solver ( SCS, MOSEK(license needed) )
            tv_cvxpy = prob.solve(verbose = True, solver = cvxpy.SCS)        

            # use TotalVariation from CIL (with Fast Gradient Projection algorithm)
            TV = (alpha/3.0)*TotalVariation(max_iteration=200, isotropic=False)
            tv_cil = TV.proximal(self.data, tau=3.0)     

            # compare solution
            np.testing.assert_allclose(tv_cil.array, u_cvx.value, atol=1e-3)   

            # compare objectives
            f = 0.5*L2NormSquared(b=self.data)
            cil_objective = f(tv_cil) + TV(tv_cil)*(3)
            np.testing.assert_allclose(cil_objective, obj.value, atol=1e-3)              
Ejemplo n.º 8
0
    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
Ejemplo n.º 9
0
    def test_FISTA(self):
        print("Test FISTA")
        ig = ImageGeometry(127, 139, 149)
        initial = ig.allocate()
        b = initial.copy()
        # fill with random numbers
        b.fill(numpy.random.random(initial.shape))
        initial = ig.allocate(ImageGeometry.RANDOM)
        identity = IdentityOperator(ig)

        #### it seems FISTA does not work with Nowm2Sq
        # norm2sq = Norm2Sq(identity, b)
        # norm2sq.L = 2 * norm2sq.c * identity.norm()**2
        norm2sq = OperatorCompositionFunction(L2NormSquared(b=b), identity)
        opt = {'tol': 1e-4, 'memopt': False}
        if debug_print:
            print("initial objective", norm2sq(initial))
        alg = FISTA(initial=initial, f=norm2sq, g=ZeroFunction())
        alg.max_iteration = 2
        alg.run(20, verbose=0)
        self.assertNumpyArrayAlmostEqual(alg.x.as_array(), b.as_array())

        alg = FISTA(initial=initial,
                    f=norm2sq,
                    g=ZeroFunction(),
                    max_iteration=2,
                    update_objective_interval=2)

        self.assertTrue(alg.max_iteration == 2)
        self.assertTrue(alg.update_objective_interval == 2)

        alg.run(20, verbose=0)
        self.assertNumpyArrayAlmostEqual(alg.x.as_array(), b.as_array())
Ejemplo n.º 10
0
    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 test_PDHG_strongly_convex_gamma_fcong(self):

        ig = ImageGeometry(3,3)
        data = ig.allocate('random')

        f = L2NormSquared(b=data)
        g = L2NormSquared()
        operator = IdentityOperator(ig)

        # sigma, tau 
        sigma = 1.0
        tau  = 1.0        

        pdhg = PDHG(f=f, g=g, operator=operator, sigma = sigma, tau=tau,
                    max_iteration=5, gamma_fconj=0.5)
        pdhg.run(1, verbose=0)
        self.assertEquals(pdhg.theta, 1.0/ np.sqrt(1 + 2 * pdhg.gamma_fconj * sigma))
        self.assertEquals(pdhg.tau, tau / pdhg.theta)
        self.assertEquals(pdhg.sigma, sigma * pdhg.theta)
        pdhg.run(4, verbose=0)
        self.assertNotEqual(pdhg.sigma, sigma)
        self.assertNotEqual(pdhg.tau, tau) 

        # check negative strongly convex constant
        try:
            pdhg = PDHG(f=f, g=g, operator=operator, sigma = sigma, tau=tau,
                max_iteration=5, gamma_fconj=-0.5) 
        except ValueError as ve:
            print(ve) 

        # check strongly convex constant not a number
        try:
            pdhg = PDHG(f=f, g=g, operator=operator, sigma = sigma, tau=tau,
                max_iteration=5, gamma_fconj="-0.5") 
        except ValueError as ve:
            print(ve)                         
Ejemplo n.º 12
0
    def test_exception_initial_GD(self):
        print("Test FISTA")
        ig = ImageGeometry(127, 139, 149)
        initial = ig.allocate()
        b = initial.copy()
        # fill with random numbers
        b.fill(numpy.random.random(initial.shape))
        initial = ig.allocate(ImageGeometry.RANDOM)
        identity = IdentityOperator(ig)

        norm2sq = OperatorCompositionFunction(L2NormSquared(b=b), identity)
        opt = {'tol': 1e-4, 'memopt': False}
        print("initial objective", norm2sq(initial))
        try:
            alg = GD(initial=initial,
                     objective_function=norm2sq,
                     x_init=initial)
            assert False
        except ValueError as ve:
            assert True
Ejemplo n.º 13
0
    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)
Ejemplo n.º 14
0
    def test_SumFunctionScalar(self):      
        numpy.random.seed(1)
        M, N, K = 3,4,5
        ig = ImageGeometry(M, N, K)
        
        tmp = ig.allocate('random')
        b = ig.allocate('random')
        
        scalar = 0.25
        f1 =  scalar * L2NormSquared(b=b)
        f2 = 5
           
        f = f1 + f2
        print(f)
        
        g = f2 + f1
        print(g)

        tau = 0.03
        
        # check call method       
        res1 = f(tmp)
        res2 = f1(tmp) + f2
        self.assertAlmostEqual(res1, res2)
        
        # check gradient
        res1 = f.gradient(tmp)
        res2 = f1.gradient(tmp)
        self.assertNumpyArrayAlmostEqual(res1.as_array(), res2.as_array())
        
        # check gradient with out
        out1 = tmp*0
        out2 = tmp*0
        f.gradient(tmp, out=out1)
        f1.gradient(tmp, out=out2)
        self.assertNumpyArrayAlmostEqual(out1.as_array(), out2.as_array())
        

        res1 = f.proximal(tmp, tau)
        res2 = f1.proximal(tmp, tau)
        
        # proximal of sum of function with scalar = proximal of function
        self.assertNumpyArrayAlmostEqual(res1.as_array(), res2.as_array())
        
        # proximal  with out of sum of function with scalar = proximal of function
        res1_out = ig.allocate()
        res2_out = ig.allocate()         
        f.proximal(tmp, tau, out = res1_out)
        f1.proximal(tmp, tau, out = res2_out)             
        self.assertNumpyArrayAlmostEqual(res1_out.as_array(), res2_out.as_array())

        res1 = f.proximal_conjugate(tmp, tau)
        res2 = f1.proximal_conjugate(tmp, tau)
        
        # proximal of sum of function with scalar = proximal of function
        self.assertNumpyArrayAlmostEqual(res1.as_array(), res2.as_array())
        
        # proximal  with out of sum of function with scalar = proximal of function
        res1_out = ig.allocate()
        res2_out = ig.allocate()         
        f.proximal_conjugate(tmp, tau, out = res1_out)
        f1.proximal_conjugate(tmp, tau, out = res2_out)             
        self.assertNumpyArrayAlmostEqual(res1_out.as_array(), res2_out.as_array())        
Ejemplo n.º 15
0
 
 # Run dot test to check validity of adjoint.
 print(BOP.dot_test(BOP))
 
 # 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)
 
Ejemplo n.º 16
0
    def test_TranslateFunction(self):

        # Test TranslationFunction

        ig = ImageGeometry(4, 4)
        tmp = ig.allocate('random', seed=10)
        b = ig.allocate('random', seed=10)
        scalar = 0.4
        tau = 0.05

        list1 = [
            L2NormSquared(), scalar * L2NormSquared(),
            scalar * L2NormSquared(b=b),
            L1Norm(), scalar * L1Norm(), scalar * L1Norm(b=b)
        ]

        list1_shift = [
            L2NormSquared().centered_at(ig.allocate()),
            scalar * L2NormSquared().centered_at(ig.allocate()),
            scalar * L2NormSquared().centered_at(b),
            L1Norm().centered_at(ig.allocate()),
            scalar * L1Norm().centered_at(ig.allocate()),
            scalar * L1Norm().centered_at(b)
        ]

        out_gradient1 = ig.allocate()
        out_gradient2 = ig.allocate()

        out_proximal1 = ig.allocate()
        out_proximal2 = ig.allocate()

        out_proximal_conj1 = ig.allocate()
        out_proximal_conj2 = ig.allocate()

        for func, func_shift in zip(list1, list1_shift):

            # check call
            res1 = func(tmp)
            res2 = func_shift(tmp)
            self.assertNumpyArrayAlmostEqual(res1, res2)

            try:
                # check gradient
                res1_gradient = func.gradient(tmp)
                res2_gradient = func_shift.gradient(tmp)
                self.assertNumpyArrayAlmostEqual(res1_gradient.as_array(),
                                                 res2_gradient.as_array())

                # check gradient out
                func.gradient(tmp, out=out_gradient1)
                func_shift.gradient(tmp, out=out_gradient2)
                self.assertNumpyArrayAlmostEqual(out_gradient1.as_array(),
                                                 out_gradient2.as_array())

            except NotImplementedError:
                print('Function is not differentiable')

            # check proximal
            func.proximal(tmp, tau, out=out_proximal1)
            func_shift.proximal(tmp, tau, out=out_proximal2)
            self.assertNumpyArrayAlmostEqual(out_proximal1.as_array(),
                                             out_proximal2.as_array())

            # check proximal conjugate
            func.proximal_conjugate(tmp, tau, out=out_proximal_conj1)
            func_shift.proximal_conjugate(tmp, tau, out=out_proximal_conj2)
            self.assertNumpyArrayAlmostEqual(out_proximal_conj1.as_array(),
                                             out_proximal_conj1.as_array())
Ejemplo n.º 17
0
    # Regularisation Parameter depending on the noise distribution
    if noise == 's&p':
        alpha = 0.8
    elif noise == 'poisson':
        alpha = 1.0
    elif noise == 'gaussian':
        alpha = .3

    # Choose data fidelity dependent on noise type.
    if noise == 's&p':
        f2 = L1Norm(b=noisy_data)
    elif noise == 'poisson':
        f2 = KullbackLeibler(noisy_data)
    elif noise == 'gaussian':
        f2 = 0.5 * L2NormSquared(b=noisy_data)

    # Create operators
    op1 = GradientOperator(ig, correlation=GradientOperator.CORRELATION_SPACE)
    op2 = MO

    # Create BlockOperator
    operator = BlockOperator(op1, op2, shape=(2, 1))

    # Create functions
    f = BlockFunction(alpha * MixedL21Norm(), f2)
    g = ZeroFunction()

    # Compute operator Norm
    normK = operator.norm()
    def test_PDHG_step_sizes(self):

        ig = ImageGeometry(3,3)
        data = ig.allocate('random')

        f = L2NormSquared(b=data)
        g = L2NormSquared()
        operator = 3*IdentityOperator(ig)

        #check if sigma, tau are None 
        pdhg = PDHG(f=f, g=g, operator=operator, max_iteration=10)
        self.assertAlmostEqual(pdhg.sigma, 1./operator.norm())
        self.assertAlmostEqual(pdhg.tau, 1./operator.norm())

        #check if sigma is negative
        with self.assertRaises(ValueError):
            pdhg = PDHG(f=f, g=g, operator=operator, max_iteration=10, sigma = -1)
        
        #check if tau is negative
        with self.assertRaises(ValueError):
            pdhg = PDHG(f=f, g=g, operator=operator, max_iteration=10, tau = -1)
        
        #check if tau is None 
        sigma = 3.0
        pdhg = PDHG(f=f, g=g, operator=operator, sigma = sigma, max_iteration=10)
        self.assertAlmostEqual(pdhg.sigma, sigma)
        self.assertAlmostEqual(pdhg.tau, 1./(sigma * operator.norm()**2)) 

        #check if sigma is None 
        tau = 3.0
        pdhg = PDHG(f=f, g=g, operator=operator, tau = tau, max_iteration=10)
        self.assertAlmostEqual(pdhg.tau, tau)
        self.assertAlmostEqual(pdhg.sigma, 1./(tau * operator.norm()**2)) 

        #check if sigma/tau are not None 
        tau = 1.0
        sigma = 1.0
        pdhg = PDHG(f=f, g=g, operator=operator, tau = tau, sigma = sigma, max_iteration=10)
        self.assertAlmostEqual(pdhg.tau, tau)
        self.assertAlmostEqual(pdhg.sigma, sigma) 

        #check sigma/tau as arrays, sigma wrong shape
        ig1 = ImageGeometry(2,2)
        sigma = ig1.allocate()
        with self.assertRaises(ValueError):
            pdhg = PDHG(f=f, g=g, operator=operator, sigma = sigma, max_iteration=10)

        #check sigma/tau as arrays, tau wrong shape
        tau = ig1.allocate()
        with self.assertRaises(ValueError):
            pdhg = PDHG(f=f, g=g, operator=operator, tau = tau, max_iteration=10)
        
        # check sigma not Number or object with correct shape
        with self.assertRaises(AttributeError):
            pdhg = PDHG(f=f, g=g, operator=operator, sigma = "sigma", max_iteration=10)
        
        # check tau not Number or object with correct shape
        with self.assertRaises(AttributeError):
            pdhg = PDHG(f=f, g=g, operator=operator, tau = "tau", max_iteration=10)
        
        # check warning message if condition is not satisfied
        sigma = 4
        tau = 1/3
        with warnings.catch_warnings(record=True) as wa:
            pdhg = PDHG(f=f, g=g, operator=operator, tau = tau, sigma = sigma, max_iteration=10)  
            assert "Convergence criterion" in str(wa[0].message)             
Ejemplo n.º 19
0
    algo.update_objective_interval = 10
    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')

    # %%
Ejemplo n.º 20
0
    def tests_for_L2NormSq_and_weighted(self):
        numpy.random.seed(1)
        M, N, K = 2, 3, 1
        ig = ImageGeometry(voxel_num_x=M, voxel_num_y=N, voxel_num_z=K)
        u = ig.allocate('random')
        b = ig.allocate('random')

        # check grad/call no data
        f = L2NormSquared()
        a1 = f.gradient(u)
        a2 = 2 * u
        numpy.testing.assert_array_almost_equal(a1.as_array(),
                                                a2.as_array(),
                                                decimal=4)
        numpy.testing.assert_equal(f(u), u.squared_norm())

        # check grad/call with data

        #        igggg = ImageGeometry(4,4)
        f1 = L2NormSquared(b=b)
        b1 = f1.gradient(u)
        b2 = 2 * (u - b)

        numpy.testing.assert_array_almost_equal(b1.as_array(),
                                                b2.as_array(),
                                                decimal=4)
        numpy.testing.assert_equal(f1(u), ((u - b)).squared_norm())

        #check convex conjuagate no data
        c1 = f.convex_conjugate(u)
        c2 = 1 / 4 * u.squared_norm()
        numpy.testing.assert_equal(c1, c2)

        #check convex conjuagate with data
        d1 = f1.convex_conjugate(u)
        d2 = (1 / 4) * u.squared_norm() + u.dot(b)
        numpy.testing.assert_equal(d1, d2)

        # check proximal no data
        tau = 5
        e1 = f.proximal(u, tau)
        e2 = u / (1 + 2 * tau)
        numpy.testing.assert_array_almost_equal(e1.as_array(),
                                                e2.as_array(),
                                                decimal=4)

        # check proximal with data
        tau = 5
        h1 = f1.proximal(u, tau)
        h2 = (u - b) / (1 + 2 * tau) + b
        numpy.testing.assert_array_almost_equal(h1.as_array(),
                                                h2.as_array(),
                                                decimal=4)

        # check proximal conjugate no data
        tau = 0.2
        k1 = f.proximal_conjugate(u, tau)
        k2 = u / (1 + tau / 2)
        numpy.testing.assert_array_almost_equal(k1.as_array(),
                                                k2.as_array(),
                                                decimal=4)

        # check proximal conjugate with data
        l1 = f1.proximal_conjugate(u, tau)
        l2 = (u - tau * b) / (1 + tau / 2)
        numpy.testing.assert_array_almost_equal(l1.as_array(),
                                                l2.as_array(),
                                                decimal=4)

        # check scaled function properties

        # scalar
        scalar = 100
        f_scaled_no_data = scalar * L2NormSquared()
        f_scaled_data = scalar * L2NormSquared(b=b)

        # call
        numpy.testing.assert_equal(f_scaled_no_data(u), scalar * f(u))
        numpy.testing.assert_equal(f_scaled_data(u), scalar * f1(u))

        # grad
        numpy.testing.assert_array_almost_equal(
            f_scaled_no_data.gradient(u).as_array(),
            scalar * f.gradient(u).as_array(),
            decimal=4)
        numpy.testing.assert_array_almost_equal(
            f_scaled_data.gradient(u).as_array(),
            scalar * f1.gradient(u).as_array(),
            decimal=4)

        # conj
        numpy.testing.assert_almost_equal(f_scaled_no_data.convex_conjugate(u), \
                                   f.convex_conjugate(u/scalar) * scalar, decimal=4)

        numpy.testing.assert_almost_equal(f_scaled_data.convex_conjugate(u), \
                                   scalar * f1.convex_conjugate(u/scalar), decimal=4)

        # proximal
        numpy.testing.assert_array_almost_equal(f_scaled_no_data.proximal(u, tau).as_array(), \
                                                f.proximal(u, tau*scalar).as_array())


        numpy.testing.assert_array_almost_equal(f_scaled_data.proximal(u, tau).as_array(), \
                                                f1.proximal(u, tau*scalar).as_array())

        # proximal conjugate
        numpy.testing.assert_array_almost_equal(f_scaled_no_data.proximal_conjugate(u, tau).as_array(), \
                                                (u/(1 + tau/(2*scalar) )).as_array(), decimal=4)

        numpy.testing.assert_array_almost_equal(f_scaled_data.proximal_conjugate(u, tau).as_array(), \
                                                ((u - tau * b)/(1 + tau/(2*scalar) )).as_array(), decimal=4)

        print(" ####### check without out ######### ")

        u_out_no_out = ig.allocate('random_int')
        res_no_out = f_scaled_data.proximal_conjugate(u_out_no_out, 0.5)
        print(res_no_out.as_array())

        print(" ####### check with out ######### ")

        res_out = ig.allocate()
        f_scaled_data.proximal_conjugate(u_out_no_out, 0.5, out=res_out)

        print(res_out.as_array())

        numpy.testing.assert_array_almost_equal(res_no_out.as_array(), \
                                                res_out.as_array(), decimal=4)

        ig1 = ImageGeometry(2, 3)

        tau = 0.1

        u = ig1.allocate('random')
        b = ig1.allocate('random')

        scalar = 0.5
        f_scaled = scalar * L2NormSquared(b=b)
        f_noscaled = L2NormSquared(b=b)

        res1 = f_scaled.proximal(u, tau)
        res2 = f_noscaled.proximal(u, tau * scalar)

        #    res2 = (u + tau*b)/(1+tau)

        numpy.testing.assert_array_almost_equal(res1.as_array(), \
                                                res2.as_array(), decimal=4)

        print("Checks for WeightedL2NormSquared")

        # Tests for weighted L2NormSquared
        ig = ImageGeometry(voxel_num_x=3, voxel_num_y=3)
        weight = ig.allocate('random')

        f = WeightedL2NormSquared(weight=weight)
        x = ig.allocate(0.4)

        res1 = f(x)
        res2 = (weight * (x**2)).sum()
        numpy.testing.assert_almost_equal(res1, res2, decimal=4)

        print("Call of WeightedL2NormSquared is ... ok")

        # gradient for weighted L2NormSquared
        res1 = f.gradient(x)
        res2 = 2 * weight * x
        out = ig.allocate()
        f.gradient(x, out=out)
        numpy.testing.assert_array_almost_equal(res1.as_array(), \
                                                out.as_array(), decimal=4)
        numpy.testing.assert_array_almost_equal(res2.as_array(), \
                                                out.as_array(), decimal=4)

        print("GradientOperator of WeightedL2NormSquared is ... ok")

        # convex conjugate for weighted L2NormSquared
        res1 = f.convex_conjugate(x)
        res2 = 1 / 4 * (x / weight.sqrt()).squared_norm()
        numpy.testing.assert_array_almost_equal(res1, \
                                                res2, decimal=4)

        print("Convex conjugate of WeightedL2NormSquared is ... ok")

        # proximal for weighted L2NormSquared
        tau = 0.3
        out = ig.allocate()
        res1 = f.proximal(x, tau)
        f.proximal(x, tau, out=out)
        res2 = x / (1 + 2 * tau * weight)
        numpy.testing.assert_array_almost_equal(res1.as_array(), \
                                                res2.as_array(), decimal=4)

        print("Proximal of WeightedL2NormSquared is ... ok")

        tau = 0.3
        out = ig.allocate()
        res1 = f.proximal_conjugate(x, tau)
        res2 = x / (1 + tau / (2 * weight))
        numpy.testing.assert_array_almost_equal(res1.as_array(), \
                                                res2.as_array(), decimal=4)

        print("Proximal conjugate of WeightedL2NormSquared is ... ok")

        b = ig.allocate('random')
        f1 = TranslateFunction(WeightedL2NormSquared(weight=weight), b)
        f2 = WeightedL2NormSquared(weight=weight, b=b)
        res1 = f1(x)
        res2 = f2(x)
        numpy.testing.assert_almost_equal(res1, res2, decimal=4)

        print("Call of WeightedL2NormSquared vs TranslateFunction is ... ok")

        f1 = WeightedL2NormSquared(b=b)
        f2 = L2NormSquared(b=b)

        numpy.testing.assert_almost_equal(f1.L, f2.L, decimal=4)
        numpy.testing.assert_almost_equal(f1.L, 2, decimal=4)
        numpy.testing.assert_almost_equal(f2.L, 2, decimal=4)

        print("Check Lip constants ... ok")
Ejemplo n.º 21
0
def mse(dc1, dc2):
    ''' Returns the Mean Squared error of two DataContainers
    '''

    diff = dc1 - dc2
    return L2NormSquared().__call__(diff) / dc1.size
Ejemplo n.º 22
0
    def test_L2NormSquaredOut(self):
        # TESTS for L2 and scalar * L2

        M, N, K = 2, 3, 5
        ig = ImageGeometry(voxel_num_x=M, voxel_num_y=N, voxel_num_z=K)
        u = ig.allocate(ImageGeometry.RANDOM, seed=1)
        b = ig.allocate(ImageGeometry.RANDOM, seed=2)

        # check grad/call no data
        f = L2NormSquared()
        a1 = f.gradient(u)
        a2 = a1 * 0.
        f.gradient(u, out=a2)
        numpy.testing.assert_array_almost_equal(a1.as_array(),
                                                a2.as_array(),
                                                decimal=4)
        #numpy.testing.assert_equal(f(u), u.squared_norm())

        # check grad/call with data
        f1 = L2NormSquared(b=b)
        b1 = f1.gradient(u)
        b2 = b1 * 0.
        f1.gradient(u, out=b2)

        numpy.testing.assert_array_almost_equal(b1.as_array(),
                                                b2.as_array(),
                                                decimal=4)
        #numpy.testing.assert_equal(f1(u), (u-b).squared_norm())

        # check proximal no data
        tau = 5
        e1 = f.proximal(u, tau)
        e2 = e1 * 0.
        f.proximal(u, tau, out=e2)
        numpy.testing.assert_array_almost_equal(e1.as_array(),
                                                e2.as_array(),
                                                decimal=4)

        # check proximal with data
        tau = 5
        h1 = f1.proximal(u, tau)
        h2 = h1 * 0.
        f1.proximal(u, tau, out=h2)
        numpy.testing.assert_array_almost_equal(h1.as_array(),
                                                h2.as_array(),
                                                decimal=4)

        # check proximal conjugate no data
        tau = 0.2
        k1 = f.proximal_conjugate(u, tau)
        k2 = k1 * 0.
        f.proximal_conjugate(u, tau, out=k2)

        numpy.testing.assert_array_almost_equal(k1.as_array(),
                                                k2.as_array(),
                                                decimal=4)

        # check proximal conjugate with data
        l1 = f1.proximal_conjugate(u, tau)
        l2 = l1 * 0.
        f1.proximal_conjugate(u, tau, out=l2)
        numpy.testing.assert_array_almost_equal(l1.as_array(),
                                                l2.as_array(),
                                                decimal=4)

        # check scaled function properties

        # scalar
        scalar = 100
        f_scaled_no_data = scalar * L2NormSquared()
        f_scaled_data = scalar * L2NormSquared(b=b)

        # grad
        w = f_scaled_no_data.gradient(u)
        ww = w * 0
        f_scaled_no_data.gradient(u, out=ww)

        numpy.testing.assert_array_almost_equal(w.as_array(),
                                                ww.as_array(),
                                                decimal=4)

        # numpy.testing.assert_array_almost_equal(f_scaled_data.gradient(u).as_array(), scalar*f1.gradient(u).as_array(), decimal=4)

        # # conj
        # numpy.testing.assert_almost_equal(f_scaled_no_data.convex_conjugate(u), \
        #                         f.convex_conjugate(u/scalar) * scalar, decimal=4)

        # numpy.testing.assert_almost_equal(f_scaled_data.convex_conjugate(u), \
        #                         scalar * f1.convex_conjugate(u/scalar), decimal=4)

        # # proximal
        w = f_scaled_no_data.proximal(u, tau)
        ww = w * 0
        f_scaled_no_data.proximal(u, tau, out=ww)
        numpy.testing.assert_array_almost_equal(w.as_array(), \
                                                ww.as_array())

        # numpy.testing.assert_array_almost_equal(f_scaled_data.proximal(u, tau).as_array(), \
        #                                         f1.proximal(u, tau*scalar).as_array())

        # proximal conjugate
        w = f_scaled_no_data.proximal_conjugate(u, tau)
        ww = w * 0
        f_scaled_no_data.proximal_conjugate(u, tau, out=ww)
        numpy.testing.assert_array_almost_equal(w.as_array(), \
                                                ww.as_array(), decimal=4)
Ejemplo n.º 23
0
    def test_L2NormSquared(self):
        # TESTS for L2 and scalar * L2
        print("Test L2NormSquared")
        numpy.random.seed(1)
        M, N, K = 2, 3, 5
        ig = ImageGeometry(voxel_num_x=M, voxel_num_y=N, voxel_num_z=K)
        u = ig.allocate(ImageGeometry.RANDOM)
        b = ig.allocate(ImageGeometry.RANDOM)

        # check grad/call no data
        f = L2NormSquared()
        a1 = f.gradient(u)
        a2 = 2 * u
        numpy.testing.assert_array_almost_equal(a1.as_array(),
                                                a2.as_array(),
                                                decimal=4)
        numpy.testing.assert_equal(f(u), u.squared_norm())

        # check grad/call with data
        f1 = L2NormSquared(b=b)
        b1 = f1.gradient(u)
        b2 = 2 * (u - b)

        numpy.testing.assert_array_almost_equal(b1.as_array(),
                                                b2.as_array(),
                                                decimal=4)
        numpy.testing.assert_equal(f1(u), (u - b).squared_norm())

        #check convex conjuagate no data
        c1 = f.convex_conjugate(u)
        c2 = 1 / 4. * u.squared_norm()
        numpy.testing.assert_equal(c1, c2)

        #check convex conjugate with data
        d1 = f1.convex_conjugate(u)
        d2 = (1. / 4.) * u.squared_norm() + (u * b).sum()
        numpy.testing.assert_almost_equal(d1, d2, decimal=6)

        # check proximal no data
        tau = 5
        e1 = f.proximal(u, tau)
        e2 = u / (1 + 2 * tau)
        numpy.testing.assert_array_almost_equal(e1.as_array(),
                                                e2.as_array(),
                                                decimal=4)

        # check proximal with data
        tau = 5
        h1 = f1.proximal(u, tau)
        h2 = (u - b) / (1 + 2 * tau) + b
        numpy.testing.assert_array_almost_equal(h1.as_array(),
                                                h2.as_array(),
                                                decimal=4)

        # check proximal conjugate no data
        tau = 0.2
        k1 = f.proximal_conjugate(u, tau)
        k2 = u / (1 + tau / 2)
        numpy.testing.assert_array_almost_equal(k1.as_array(),
                                                k2.as_array(),
                                                decimal=4)

        # check proximal conjugate with data
        l1 = f1.proximal_conjugate(u, tau)
        l2 = (u - tau * b) / (1 + tau / 2)
        numpy.testing.assert_array_almost_equal(l1.as_array(),
                                                l2.as_array(),
                                                decimal=4)

        # check scaled function properties

        # scalar
        scalar = 100
        f_scaled_no_data = scalar * L2NormSquared()
        f_scaled_data = scalar * L2NormSquared(b=b)

        # call
        numpy.testing.assert_equal(f_scaled_no_data(u), scalar * f(u))
        numpy.testing.assert_equal(f_scaled_data(u), scalar * f1(u))

        # grad
        numpy.testing.assert_array_almost_equal(
            f_scaled_no_data.gradient(u).as_array(),
            scalar * f.gradient(u).as_array(),
            decimal=4)
        numpy.testing.assert_array_almost_equal(
            f_scaled_data.gradient(u).as_array(),
            scalar * f1.gradient(u).as_array(),
            decimal=4)

        # conj
        numpy.testing.assert_almost_equal(f_scaled_no_data.convex_conjugate(u), \
                                f.convex_conjugate(u/scalar) * scalar, decimal=4)

        numpy.testing.assert_almost_equal(f_scaled_data.convex_conjugate(u), \
                                scalar * f1.convex_conjugate(u/scalar), decimal=4)

        # proximal
        numpy.testing.assert_array_almost_equal(f_scaled_no_data.proximal(u, tau).as_array(), \
                                                f.proximal(u, tau*scalar).as_array())


        numpy.testing.assert_array_almost_equal(f_scaled_data.proximal(u, tau).as_array(), \
                                                f1.proximal(u, tau*scalar).as_array())

        # proximal conjugate
        numpy.testing.assert_array_almost_equal(f_scaled_no_data.proximal_conjugate(u, tau).as_array(), \
                                                (u/(1 + tau/(2*scalar) )).as_array(), decimal=4)

        numpy.testing.assert_array_almost_equal(f_scaled_data.proximal_conjugate(u, tau).as_array(), \
                                                ((u - tau * b)/(1 + tau/(2*scalar) )).as_array(), decimal=4)
Ejemplo n.º 24
0
    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 " )
#    res_no_out = f.proximal_conjugate( U, tau)
#    res_out = B.range_geometry().allocate()
#    f.proximal_conjugate( U, tau, out = res_out)
#    
#    numpy.testing.assert_array_almost_equal(res_no_out[0][0].as_array(), \
#                                            res_out[0][0].as_array(), decimal=4) 
Ejemplo n.º 25
0
    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))