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())
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)
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)
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)
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)