Example #1
0
 def weight_norm(self):
     if self.weight is not None:
         if self._weight_norm is None:
             D = DiagonalOperator(self.weight)
             self._weight_norm = D.norm()
     else:
         self._weight_norm = 1.0
     return self._weight_norm
    def test_ChannelwiseOperator(self):
        print("test_ChannelwiseOperator")

        M = 3
        channels = 4
        ig = ImageGeometry(M, M, channels=channels)
        igs = ImageGeometry(M, M)
        x = ig.allocate('random', seed=100)
        diag = igs.allocate('random', seed=101)

        D = DiagonalOperator(diag)
        C = ChannelwiseOperator(D, channels)

        y = C.direct(x)

        y2 = ig.allocate()
        C.direct(x, y2)

        for c in range(channels):
            numpy.testing.assert_array_equal(y.subset(channel=2).as_array(), \
                                             (diag*x.subset(channel=2)).as_array())
            numpy.testing.assert_array_equal(y2.subset(channel=2).as_array(), \
                                             (diag*x.subset(channel=2)).as_array())

        z = C.adjoint(y)

        z2 = ig.allocate()
        C.adjoint(y, z2)

        for c in range(channels):
            numpy.testing.assert_array_equal(z.subset(channel=2).as_array(), \
                                             (diag*(diag*x.subset(channel=2))).as_array())
            numpy.testing.assert_array_equal(z2.subset(channel=2).as_array(), \
                                             (diag*(diag*x.subset(channel=2))).as_array())
    def test_DiagonalOperator(self):
        print("test_DiagonalOperator")

        M = 3
        ig = ImageGeometry(M, M)
        x = ig.allocate('random', seed=100)
        diag = ig.allocate('random', seed=101)

        # Set up example DiagonalOperator
        D = DiagonalOperator(diag)

        # Apply direct and check whether result equals diag*x as expected.
        z = D.direct(x)
        numpy.testing.assert_array_equal(z.as_array(), (diag * x).as_array())

        # Apply adjoint and check whether results equals diag*(diag*x) as expected.
        y = D.adjoint(z)
        numpy.testing.assert_array_equal(y.as_array(),
                                         (diag * (diag * x)).as_array())
Example #4
0
    def __init__(self, **kwargs):

        # Weight can be either a scalar or a DataContainer
        # Lispchitz constant L = 2 *||weight||

        self.weight = kwargs.get('weight', 1.0)
        self.b = kwargs.get('b', None)
        tmp_norm = 1.0
        self.tmp_space = self.weight * 0.

        if isinstance(self.weight, DataContainer):
            self.operator_weight = DiagonalOperator(self.weight)
            tmp_norm = self.operator_weight.norm()
            self.tmp_space = self.operator_weight.domain_geometry().allocate()

            if (self.weight < 0).any():
                raise ValueError('Weigth contains negative values')

        super(WeightedL2NormSquared, self).__init__(L=2 * tmp_norm)
Example #5
0
class WeightedL2NormSquared(Function):
    r""" WeightedL2NormSquared function: :math:`F(x) = \| x\|_{w}^{2}_{2} = \underset{i}{\sum}w_{i}*x_{i}^{2} = <x, w*x> = x^{T}*w*x`
                                                                    
    """
    def __init__(self, **kwargs):

        # Weight can be either a scalar or a DataContainer
        # Lispchitz constant L = 2 *||weight||

        self.weight = kwargs.get('weight', 1.0)
        self.b = kwargs.get('b', None)
        tmp_norm = 1.0
        self.tmp_space = self.weight * 0.

        if isinstance(self.weight, DataContainer):
            self.operator_weight = DiagonalOperator(self.weight)
            tmp_norm = self.operator_weight.norm()
            self.tmp_space = self.operator_weight.domain_geometry().allocate()

            if (self.weight < 0).any():
                raise ValueError('Weigth contains negative values')

        super(WeightedL2NormSquared, self).__init__(L=2 * tmp_norm)

    def __call__(self, x):

        self.operator_weight.direct(x, out=self.tmp_space)
        y = x.dot(self.tmp_space)

        if self.b is not None:
            self.operator_weight.direct(x - self.b, out=self.tmp_space)
            y = (x - self.b).dot(self.tmp_space)
        return y

    def gradient(self, x, out=None):

        if out is not None:

            out.fill(x)
            if self.b is not None:
                out -= self.b
            self.operator_weight.direct(out, out=out)
            out *= 2

        else:

            y = x
            if self.b is not None:
                y = x - self.b
            return 2 * self.weight * y

    def convex_conjugate(self, x):

        tmp = 0

        if self.b is not None:
            tmp = x.dot(self.b)

        return (1. / 4) * (x / self.weight.sqrt()).squared_norm() + tmp

    def proximal(self, x, tau, out=None):

        if out is None:

            if self.b is None:
                return x / (1 + 2 * tau * self.weight)
            else:
                tmp = x.subtract(self.b)
                tmp /= (1 + 2 * tau * self.weight)
                tmp += self.b
                return tmp

        else:

            if self.b is not None:
                x.subtract(self.b, out=out)
                out /= (1 + 2 * tau * self.weight)
                out += self.b
            else:
                x.divide((1 + 2 * tau * self.weight), out=out)
Example #6
0
    def tests_for_LS_weightedLS(self):

        ig = ImageGeometry(40, 30)

        numpy.random.seed(1)

        A = IdentityOperator(ig)
        b = ig.allocate('random')
        x = ig.allocate('random')
        c = numpy.float64(0.3)

        weight = ig.allocate('random')

        D = DiagonalOperator(weight)
        norm_weight = numpy.float64(D.norm())
        print("norm_weight", norm_weight)

        f1 = LeastSquares(A, b, c, weight)
        f2 = LeastSquares(A, b, c)

        print("Check LS vs wLS")

        # check Lipshitz
        numpy.testing.assert_almost_equal(f2.L, 2 * c * (A.norm()**2))
        print("unwrapped", 2. * c * norm_weight * (A.norm()**2))
        print("f1.L", f1.L)
        numpy.testing.assert_almost_equal(
            f1.L,
            numpy.float64(2.) * c * norm_weight * (A.norm()**2))
        print("Lipschitz is ... OK")

        # check call with weight
        res1 = c * (A.direct(x) - b).dot(weight * (A.direct(x) - b))
        res2 = f1(x)
        numpy.testing.assert_almost_equal(res1, res2)
        print("Call is ... OK")

        # check call without weight
        #res1 = c * (A.direct(x)-b).dot((A.direct(x) - b))
        res1 = c * (A.direct(x) - b).squared_norm()
        res2 = f2(x)
        numpy.testing.assert_almost_equal(res1, res2)
        print("Call without weight is ... OK")

        # check gradient with weight
        out = ig.allocate(None)
        res1 = f1.gradient(x)
        #out = f1.gradient(x)
        f1.gradient(x, out=out)
        res2 = 2 * c * A.adjoint(weight * (A.direct(x) - b))
        numpy.testing.assert_array_almost_equal(res1.as_array(),
                                                res2.as_array())
        numpy.testing.assert_array_almost_equal(out.as_array(),
                                                res2.as_array())
        print("GradientOperator is ... OK")

        # check gradient without weight
        out = ig.allocate()
        res1 = f2.gradient(x)
        f2.gradient(x, out=out)
        res2 = 2 * c * A.adjoint(A.direct(x) - b)
        numpy.testing.assert_array_almost_equal(res1.as_array(),
                                                res2.as_array())
        numpy.testing.assert_array_almost_equal(out.as_array(),
                                                res2.as_array())

        print("GradientOperator without weight is ... OK")

        print(
            "Compare Least Squares with DiagonalOperator + CompositionOperator"
        )

        ig2 = ImageGeometry(100, 100, 100)
        A = IdentityOperator(ig2)
        b = ig2.allocate('random')
        x = ig2.allocate('random')
        c = 0.3

        weight = ig2.allocate('random')

        weight_operator = DiagonalOperator(weight.sqrt())
        tmp_A = CompositionOperator(weight_operator, A)
        tmp_b = weight_operator.direct(b)

        f1 = LeastSquares(tmp_A, tmp_b, c)
        f2 = LeastSquares(A, b, c, weight)

        t0 = timer()
        res1 = f1(x)
        t1 = timer()
        print("Time with Composition+Diagonal is {}".format(t1 - t0))

        t2 = timer()
        res2 = f2(x)
        t3 = timer()
        print("Time with LS + weight is {}".format(t3 - t2))

        numpy.testing.assert_almost_equal(res1, res2, decimal=2)
Example #7
0
        return self.op.norm()


if __name__ == '__main__':

    from cil.optimisation.operators import DiagonalOperator

    M = 3
    channels = 4
    ig = ImageGeometry(M, M, channels=channels)
    igs = ImageGeometry(M, M)
    x = ig.allocate('random', seed=100)
    diag = igs.allocate('random', seed=101)

    D = DiagonalOperator(diag)
    C = ChannelwiseOperator(D, channels)

    y = C.direct(x)

    y2 = ig.allocate()
    C.direct(x, y2)

    print(y.subset(channel=2).as_array())
    print(y2.subset(channel=2).as_array())
    print((diag * x.subset(channel=2)).as_array())

    z = C.adjoint(y)

    z2 = ig.allocate()
    C.adjoint(y, z2)