def test_pointwise_norm_weighted(exponent): fspace = odl.uniform_discr([0, 0], [1, 1], (2, 2)) vfspace = ProductSpace(fspace, 3) weight = np.array([1.0, 2.0, 3.0]) pwnorm = PointwiseNorm(vfspace, exponent, weighting=weight) testarr = np.array([[[1, 2], [3, 4]], [[0, -1], [0, 1]], [[1, 1], [1, 1]]]) if exponent in (1.0, float('inf')): true_norm = np.linalg.norm(weight[:, None, None] * testarr, ord=exponent, axis=0) else: true_norm = np.linalg.norm( weight[:, None, None] ** (1 / exponent) * testarr, ord=exponent, axis=0) func = vfspace.element(testarr) func_pwnorm = pwnorm(func) assert all_almost_equal(func_pwnorm, true_norm.reshape(-1)) out = fspace.element() pwnorm(func, out=out) assert all_almost_equal(out, true_norm.reshape(-1))
def test_pointwise_inner_init_properties(): fspace = odl.uniform_discr([0, 0], [1, 1], (2, 2)) vfspace = ProductSpace(fspace, 3, exponent=2) # Make sure the code runs and test the properties pwinner = PointwiseInner(vfspace, vfspace.one()) assert pwinner.base_space == fspace assert all_equal(pwinner.weights, [1, 1, 1]) assert not pwinner.is_weighted repr(pwinner) pwinner = PointwiseInner(vfspace, vfspace.one(), weight=[1, 2, 3]) assert all_equal(pwinner.weights, [1, 2, 3]) assert pwinner.is_weighted # Bad input with pytest.raises(TypeError): PointwiseInner(odl.Rn(3), odl.Rn(3).one()) # No power space # TODO: Does not raise currently, although bad_vecfield not in vfspace! """ bad_vecfield = ProductSpace(fspace, 3, exponent=1).one() with pytest.raises(TypeError): PointwiseInner(vfspace, bad_vecfield) """ with pytest.raises(ValueError): PointwiseInner(vfspace, vfspace.one(), weight=-1) # < 0 not allowed with pytest.raises(ValueError): PointwiseInner(vfspace, vfspace.one(), weight=[1, 0, 1]) # 0 invalid
def test_pointwise_inner_weighted(): fspace = odl.uniform_discr([0, 0], [1, 1], (2, 2)) vfspace = ProductSpace(fspace, 3) array = np.array([[[-1, -3], [2, 0]], [[0, 0], [0, 1]], [[-1, 1], [1, 1]]]) weight = np.array([1.0, 2.0, 3.0]) pwinner = PointwiseInner(vfspace, vecfield=array, weighting=weight) testarr = np.array([[[1, 2], [3, 4]], [[0, -1], [0, 1]], [[1, 1], [1, 1]]]) true_inner = np.sum(weight[:, None, None] * testarr * array, axis=0) func = vfspace.element(testarr) func_pwinner = pwinner(func) assert all_almost_equal(func_pwinner, true_inner.reshape(-1)) out = fspace.element() pwinner(func, out=out) assert all_almost_equal(out, true_inner.reshape(-1))
def test_pointwise_inner_complex(): fspace = odl.uniform_discr([0, 0], [1, 1], (2, 2), dtype=complex) vfspace = ProductSpace(fspace, 3) array = np.array([[[-1 - 1j, -3], [2, 2j]], [[-1j, 0], [0, 1]], [[-1, 1 + 2j], [1, 1]]]) pwinner = PointwiseInner(vfspace, vecfield=array) testarr = np.array([[[1 + 1j, 2], [3, 4 - 2j]], [[0, -1], [0, 1]], [[1j, 1j], [1j, 1j]]]) true_inner = np.sum(testarr * array.conj(), axis=0) func = vfspace.element(testarr) func_pwinner = pwinner(func) assert all_almost_equal(func_pwinner, true_inner.reshape(-1)) out = fspace.element() pwinner(func, out=out) assert all_almost_equal(out, true_inner.reshape(-1))
def test_pointwise_norm_weighted(exponent): fspace = odl.uniform_discr([0, 0], [1, 1], (2, 2)) vfspace = ProductSpace(fspace, 3) weight = np.array([1.0, 2.0, 3.0]) pwnorm = PointwiseNorm(vfspace, exponent, weighting=weight) testarr = np.array([[[1, 2], [3, 4]], [[0, -1], [0, 1]], [[1, 1], [1, 1]]]) if exponent in (1.0, float('inf')): true_norm = np.linalg.norm(weight[:, None, None] * testarr, ord=exponent, axis=0) else: true_norm = np.linalg.norm(weight[:, None, None]**(1 / exponent) * testarr, ord=exponent, axis=0) func = vfspace.element(testarr) func_pwnorm = pwnorm(func) assert all_almost_equal(func_pwnorm, true_norm.reshape(-1)) out = fspace.element() pwnorm(func, out=out) assert all_almost_equal(out, true_norm.reshape(-1))
def test_pointwise_inner_adjoint_weighted(): # Weighted product space only fspace = odl.uniform_discr([0, 0], [1, 1], (2, 2), dtype=complex) vfspace = ProductSpace(fspace, 3, weighting=[2, 4, 6]) array = np.array([[[-1 - 1j, -3], [2, 2j]], [[-1j, 0], [0, 1]], [[-1, 1 + 2j], [1, 1]]]) pwinner = PointwiseInner(vfspace, vecfield=array) testarr = np.array([[1 + 1j, 2], [3, 4 - 2j]]) true_inner_adj = testarr[None, :, :] * array # same as unweighted case testfunc = fspace.element(testarr) testfunc_pwinner_adj = pwinner.adjoint(testfunc) assert all_almost_equal(testfunc_pwinner_adj, true_inner_adj) out = vfspace.element() pwinner.adjoint(testfunc, out=out) assert all_almost_equal(out, true_inner_adj) # Using different weighting in the inner product pwinner = PointwiseInner(vfspace, vecfield=array, weighting=[4, 8, 12]) testarr = np.array([[1 + 1j, 2], [3, 4 - 2j]]) true_inner_adj = 2 * testarr[None, :, :] * array # w / v = (2, 2, 2) testfunc = fspace.element(testarr) testfunc_pwinner_adj = pwinner.adjoint(testfunc) assert all_almost_equal(testfunc_pwinner_adj, true_inner_adj) out = vfspace.element() pwinner.adjoint(testfunc, out=out) assert all_almost_equal(out, true_inner_adj)
def test_pointwise_norm_init_properties(): # 1d fspace = odl.uniform_discr([0, 0], [1, 1], (2, 2)) vfspace = ProductSpace(fspace, 1, exponent=1) # Make sure the code runs and test the properties pwnorm = PointwiseNorm(vfspace) assert pwnorm.base_space == fspace assert all_equal(pwnorm.weights, [1]) assert not pwnorm.is_weighted assert pwnorm.exponent == 1.0 repr(pwnorm) pwnorm = PointwiseNorm(vfspace, exponent=2) assert pwnorm.exponent == 2 pwnorm = PointwiseNorm(vfspace, weighting=2) assert all_equal(pwnorm.weights, [2]) assert pwnorm.is_weighted # 3d fspace = odl.uniform_discr([0, 0], [1, 1], (2, 2)) vfspace = ProductSpace(fspace, 3, exponent=1) # Make sure the code runs and test the properties pwnorm = PointwiseNorm(vfspace) assert pwnorm.base_space == fspace assert all_equal(pwnorm.weights, [1, 1, 1]) assert not pwnorm.is_weighted assert pwnorm.exponent == 1.0 repr(pwnorm) pwnorm = PointwiseNorm(vfspace, exponent=2) assert pwnorm.exponent == 2 pwnorm = PointwiseNorm(vfspace, weighting=[1, 2, 3]) assert all_equal(pwnorm.weights, [1, 2, 3]) assert pwnorm.is_weighted # Bad input with pytest.raises(TypeError): PointwiseNorm(odl.rn(3)) # No power space with pytest.raises(ValueError): PointwiseNorm(vfspace, exponent=0.5) # < 1 not allowed with pytest.raises(ValueError): PointwiseNorm(vfspace, weighting=-1) # < 0 not allowed with pytest.raises(ValueError): PointwiseNorm(vfspace, weighting=[1, 0, 1]) # 0 invalid
def test_pointwise_inner_real(): # 1d fspace = odl.uniform_discr([0, 0], [1, 1], (2, 2)) vfspace = ProductSpace(fspace, 1) array = np.array([[[-1, -3], [2, 0]]]) pwinner = PointwiseInner(vfspace, vecfield=array) testarr = np.array([[[1, 2], [3, 4]]]) true_inner = np.sum(testarr * array, axis=0) func = vfspace.element(testarr) func_pwinner = pwinner(func) assert all_almost_equal(func_pwinner, true_inner.reshape(-1)) out = fspace.element() pwinner(func, out=out) assert all_almost_equal(out, true_inner.reshape(-1)) # 3d fspace = odl.uniform_discr([0, 0], [1, 1], (2, 2)) vfspace = ProductSpace(fspace, 3) array = np.array([[[-1, -3], [2, 0]], [[0, 0], [0, 1]], [[-1, 1], [1, 1]]]) pwinner = PointwiseInner(vfspace, vecfield=array) testarr = np.array([[[1, 2], [3, 4]], [[0, -1], [0, 1]], [[1, 1], [1, 1]]]) true_inner = np.sum(testarr * array, axis=0) func = vfspace.element(testarr) func_pwinner = pwinner(func) assert all_almost_equal(func_pwinner, true_inner.reshape(-1)) out = fspace.element() pwinner(func, out=out) assert all_almost_equal(out, true_inner.reshape(-1))
def test_pointwise_inner_adjoint(): # 1d fspace = odl.uniform_discr([0, 0], [1, 1], (2, 2), dtype=complex) vfspace = ProductSpace(fspace, 1) array = np.array([[[-1, -3], [2, 0]]]) pwinner = PointwiseInner(vfspace, vecfield=array) testarr = np.array([[1 + 1j, 2], [3, 4 - 2j]]) true_inner_adj = testarr[None, :, :] * array testfunc = fspace.element(testarr) testfunc_pwinner_adj = pwinner.adjoint(testfunc) assert all_almost_equal(testfunc_pwinner_adj, true_inner_adj.reshape([1, -1])) out = vfspace.element() pwinner.adjoint(testfunc, out=out) assert all_almost_equal(out, true_inner_adj.reshape([1, -1])) # 3d fspace = odl.uniform_discr([0, 0], [1, 1], (2, 2), dtype=complex) vfspace = ProductSpace(fspace, 3) array = np.array([[[-1 - 1j, -3], [2, 2j]], [[-1j, 0], [0, 1]], [[-1, 1 + 2j], [1, 1]]]) pwinner = PointwiseInner(vfspace, vecfield=array) testarr = np.array([[1 + 1j, 2], [3, 4 - 2j]]) true_inner_adj = testarr[None, :, :] * array testfunc = fspace.element(testarr) testfunc_pwinner_adj = pwinner.adjoint(testfunc) assert all_almost_equal(testfunc_pwinner_adj, true_inner_adj.reshape([3, -1])) out = vfspace.element() pwinner.adjoint(testfunc, out=out) assert all_almost_equal(out, true_inner_adj.reshape([3, -1]))
def test_pointwise_norm_complex(exponent): fspace = odl.uniform_discr([0, 0], [1, 1], (2, 2), dtype=complex) vfspace = ProductSpace(fspace, 3) pwnorm = PointwiseNorm(vfspace, exponent) testarr = np.array([[[1 + 1j, 2], [3, 4 - 2j]], [[0, -1], [0, 1]], [[1j, 1j], [1j, 1j]]]) true_norm = np.linalg.norm(testarr, ord=exponent, axis=0) func = vfspace.element(testarr) func_pwnorm = pwnorm(func) assert all_almost_equal(func_pwnorm, true_norm.reshape(-1)) out = fspace.element() pwnorm(func, out=out) assert all_almost_equal(out, true_norm.reshape(-1))
def __init__(self, space, data, forward, tau, alpha_df, alpha_of, grad=None, huber=False, gamma=1e-7, aug_lagr=False, lagr_mult=None): self.N = round(len(space) / 2) # number of time steps\ self.space = space self.image_space = self.space[0] self.space_time = ProductSpace(self.image_space, self.N) self.data = data self.forward = forward self.tau = tau self.alpha_df = alpha_df self.alpha_of = alpha_of self.grad = grad self.data_fit = DataFitL2TimeDep(self.space, self.data, self.forward, self.alpha_df) self.aug_lagr = aug_lagr if lagr_mult is None: self.lagr_mult = self.space_time.zero() else: self.lagr_mult = lagr_mult if huber is False: self.of_constr = L2OpticalFlowConstraint(self.space, self.tau, self.alpha_of, self.grad) else: self.of_constr = HuberL1OpticalFlowConstraint( self.space, self.tau, self.alpha_of, self.grad, gamma) if aug_lagr is True: self.aug_lagr_term = AugmentedLagrangeTerm(self.space, self.lagr_mult, self.tau, self.grad) super(smooth_term_OF, self).__init__(space=space, linear=False, grad_lipschitz=np.nan)
def test_pointwise_norm_gradient_real(exponent): # The operator is not differentiable for exponent 'inf' if exponent == float('inf'): fspace = odl.uniform_discr([0, 0], [1, 1], (2, 2)) vfspace = ProductSpace(fspace, 1) pwnorm = PointwiseNorm(vfspace, exponent) point = vfspace.one() with pytest.raises(NotImplementedError): pwnorm.derivative(point) return # 1d fspace = odl.uniform_discr([0, 0], [1, 1], (2, 2)) vfspace = ProductSpace(fspace, 1) pwnorm = PointwiseNorm(vfspace, exponent) point = noise_element(vfspace) direction = noise_element(vfspace) # Computing expected result tmp = pwnorm(point).ufuncs.power(1 - exponent) v_field = vfspace.element() for i in range(len(v_field)): v_field[i] = tmp * point[i] * np.abs(point[i])**(exponent - 2) pwinner = odl.PointwiseInner(vfspace, v_field) expected_result = pwinner(direction) func_pwnorm = pwnorm.derivative(point) assert all_almost_equal(func_pwnorm(direction), expected_result) # 3d fspace = odl.uniform_discr([0, 0], [1, 1], (2, 2)) vfspace = ProductSpace(fspace, 3) pwnorm = PointwiseNorm(vfspace, exponent) point = noise_element(vfspace) direction = noise_element(vfspace) # Computing expected result tmp = pwnorm(point).ufuncs.power(1 - exponent) v_field = vfspace.element() for i in range(len(v_field)): v_field[i] = tmp * point[i] * np.abs(point[i])**(exponent - 2) pwinner = odl.PointwiseInner(vfspace, v_field) expected_result = pwinner(direction) func_pwnorm = pwnorm.derivative(point) assert all_almost_equal(func_pwnorm(direction), expected_result)
def test_pointwise_inner_adjoint_weighted(): # Weighted product space only fspace = odl.uniform_discr([0, 0], [1, 1], (2, 2), dtype=complex) vfspace = ProductSpace(fspace, 3, weighting=[2, 4, 6]) array = np.array([[[-1 - 1j, -3], [2, 2j]], [[-1j, 0], [0, 1]], [[-1, 1 + 2j], [1, 1]]]) pwinner = PointwiseInner(vfspace, vecfield=array) testarr = np.array([[1 + 1j, 2], [3, 4 - 2j]]) true_inner_adj = testarr[None, :, :] * array # same as unweighted case testfunc = fspace.element(testarr) testfunc_pwinner_adj = pwinner.adjoint(testfunc) assert all_almost_equal(testfunc_pwinner_adj, true_inner_adj.reshape([3, -1])) out = vfspace.element() pwinner.adjoint(testfunc, out=out) assert all_almost_equal(out, true_inner_adj.reshape([3, -1])) # Using different weighting in the inner product pwinner = PointwiseInner(vfspace, vecfield=array, weighting=[4, 8, 12]) testarr = np.array([[1 + 1j, 2], [3, 4 - 2j]]) true_inner_adj = 2 * testarr[None, :, :] * array # w / v = (2, 2, 2) testfunc = fspace.element(testarr) testfunc_pwinner_adj = pwinner.adjoint(testfunc) assert all_almost_equal(testfunc_pwinner_adj, true_inner_adj.reshape([3, -1])) out = vfspace.element() pwinner.adjoint(testfunc, out=out) assert all_almost_equal(out, true_inner_adj.reshape([3, -1]))
def test_pointwise_inner_init_properties(): fspace = odl.uniform_discr([0, 0], [1, 1], (2, 2)) vfspace = ProductSpace(fspace, 3, exponent=2) # Make sure the code runs and test the properties pwinner = PointwiseInner(vfspace, vfspace.one()) assert pwinner.base_space == fspace assert all_equal(pwinner.weights, [1, 1, 1]) assert not pwinner.is_weighted repr(pwinner) pwinner = PointwiseInner(vfspace, vfspace.one(), weighting=[1, 2, 3]) assert all_equal(pwinner.weights, [1, 2, 3]) assert pwinner.is_weighted # Bad input with pytest.raises(TypeError): PointwiseInner(odl.rn(3), odl.rn(3).one()) # No power space # TODO: Does not raise currently, although bad_vecfield not in vfspace! """
def test_pointwise_sum(): """PointwiseSum currently depends on PointwiseInner, we verify that.""" fspace = odl.uniform_discr([0, 0], [1, 1], (2, 2)) vfspace = ProductSpace(fspace, 3, exponent=2) # Make sure the code runs and test the properties psum = PointwiseSum(vfspace) assert isinstance(psum, PointwiseInner) assert psum.base_space == fspace assert all_equal(psum.weights, [1, 1, 1]) assert all_equal(psum.vecfield, psum.domain.one())
def test_pointwise_norm_real(exponent): # 1d fspace = odl.uniform_discr([0, 0], [1, 1], (2, 2)) vfspace = ProductSpace(fspace, 1) pwnorm = PointwiseNorm(vfspace, exponent) testarr = np.array([[[1, 2], [3, 4]]]) true_norm = np.linalg.norm(testarr, ord=exponent, axis=0) func = vfspace.element(testarr) func_pwnorm = pwnorm(func) assert all_almost_equal(func_pwnorm, true_norm) out = fspace.element() pwnorm(func, out=out) assert all_almost_equal(out, true_norm) # 3d fspace = odl.uniform_discr([0, 0], [1, 1], (2, 2)) vfspace = ProductSpace(fspace, 3) pwnorm = PointwiseNorm(vfspace, exponent) testarr = np.array([[[1, 2], [3, 4]], [[0, -1], [0, 1]], [[1, 1], [1, 1]]]) true_norm = np.linalg.norm(testarr, ord=exponent, axis=0) func = vfspace.element(testarr) func_pwnorm = pwnorm(func) assert all_almost_equal(func_pwnorm, true_norm) out = fspace.element() pwnorm(func, out=out) assert all_almost_equal(out, true_norm)
def test_matrix_representation_lin_space_to_product(): # Verify that the matrix representation function returns the correct matrix n = 3 rn = odl.rn(n) A = np.random.rand(n, n) Aop = odl.MatrixOperator(A) m = 2 rm = odl.rn(m) B = np.random.rand(m, n) Bop = odl.MatrixOperator(B) dom = ProductSpace(rn, 1) ran = ProductSpace(rn, rm) AB_matrix = np.vstack([A, B]) ABop = ProductSpaceOperator([[Aop], [Bop]], dom, ran) the_matrix = matrix_representation(ABop) assert almost_equal(np.sum(np.abs(AB_matrix - the_matrix)), 1e-6)
def __init__(self, space, a, b): """Initialize a LinCombOperator instance. Parameters ---------- space : `LinearSpace` The space of elements which the operator is acting on a, b : scalar Scalars to multiply ``x[0]`` and ``x[1]`` with, respectively """ domain = ProductSpace(space, space) super().__init__(domain, space, linear=True) self.a = a self.b = b
def __init__(self, space, data, forward=None): self.space = space self.image_space = self.space[0] self.affine_space = self.space[1] self.rest_space = self.space[2] self.deformation_space = ProductSpace(self.affine_space, self.rest_space) self.data = data if forward is None: self.forward = IdentityOperator(self.image_space) else: self.forward = forward self.datafit = 0.5 * L2NormSquared(self.image_space).translated( self.data) self.embedding_affine_rest = ops.Embedding_Affine_Rest( self.deformation_space, self.image_space.tangent_bundle) self.embedding_affine = ops.Embedding_Affine( self.affine_space, self.image_space.tangent_bundle) super(DataFitL2DispAffRest, self).__init__(space=space, linear=False, grad_lipschitz=np.nan)
def __init__(self, sspace, vecfield, vfspace=None, weight=None): """Initialize a new instance. Parameters ---------- sspace : `LinearSpace` "Scalar" space on which the operator acts vecfield : domain `element-like` Vector field of the point-wise inner product operator vfspace : `ProductSpace`, optional Space of vector fields to which the operator maps. It must be a power space with ``sspace`` as base space. This option is intended to enforce an operator range with a certain weighting. Default: ``ProductSpace(space, len(vecfield), weight=weight)`` weight : `array-like` or `float`, optional Weighting array or constant of the inner product operator. If an array is given, its length must be equal to ``len(vecfield)``, and all entries must be positive. A provided constant must be positive. By default, the weights are is taken from ``range.weighting`` if applicable. Note that this excludes unusual weightings with custom inner product, norm or dist. """ if vfspace is None: vfspace = ProductSpace(sspace, len(vecfield), weight=weight) else: if not isinstance(vfspace, ProductSpace): raise TypeError('`vfspace` {!r} is not a ' 'ProductSpace instance'.format(vfspace)) if vfspace[0] != sspace: raise ValueError('base space of the range is different from ' 'the given scalar space ({!r} != {!r})' ''.format(vfspace[0], sspace)) super().__init__(vfspace, vecfield, weight=weight) # Switch domain and range self._domain, self._range = self._range, self._domain # Get weighting from range if hasattr(self.range.weighting, 'vector'): self._ran_weights = self.range.weighting.vector elif hasattr(self.range.weighting, 'const'): self._ran_weights = (self.range.weighting.const * np.ones(len(self.range))) else: raise ValueError('weighting scheme {!r} of the range does ' 'not define a weighting vector or constant' ''.format(self.range.weighting))
def test_pointwise_norm_gradient_real_with_zeros(exponent): # The gradient is only well-defined in points with zeros if the exponent is # >= 2 and < inf if exponent < 2 or exponent == float('inf'): pytest.skip('differential of operator has singularity for this ' 'exponent') # 1d fspace = odl.uniform_discr([0, 0], [1, 1], (2, 2)) vfspace = ProductSpace(fspace, 1) pwnorm = PointwiseNorm(vfspace, exponent) test_point = np.array([[[0, 0], # This makes the point singular for p < 2 [1, 2]]]) test_direction = np.array([[[1, 2], [4, 5]]]) point = vfspace.element(test_point) direction = vfspace.element(test_direction) func_pwnorm = pwnorm.derivative(point) assert not np.any(np.isnan(func_pwnorm(direction))) # 3d fspace = odl.uniform_discr([0, 0], [1, 1], (2, 2)) vfspace = ProductSpace(fspace, 3) pwnorm = PointwiseNorm(vfspace, exponent) test_point = np.array([[[0, 0], # This makes the point singular for p < 2 [1, 2]], [[3, 4], [0, 0]], # This makes the point singular for p < 2 [[5, 6], [7, 8]]]) test_direction = np.array([[[0, 1], [2, 3]], [[4, 5], [6, 7]], [[8, 9], [0, 1]]]) point = vfspace.element(test_point) direction = vfspace.element(test_direction) func_pwnorm = pwnorm.derivative(point) assert not np.any(np.isnan(func_pwnorm(direction)))
def __init__(self, ops, x0, niter, omega=1, random=False, projection=None, callback=None, callback_loop='outer', **kwargs): """ Calls `odl.solvers.iterative.iterative.kaczmarz`. Parameters ---------- ops : sequence of `odl.Operator` The forward operators of the inverse problem. The call ``ops[i].derivative(x).adjoint`` must be valid for all i. x0 : ``op.domain`` element Initial value. niter : int Number of iterations. omega : positive float or sequence of positive floats, optional Relaxation parameter. If a single float is given it is used for all operators. random : bool, optional Whether the order of the operators is randomized in each iteration. projection : callable, optional Callable that can be used to modify the iterates in each iteration. callback : :class:`odl.solvers.util.callback.Callback`, optional Object that is called in each iteration. callback_loop : {'inner', 'outer'} Whether the `callback` should be called in the inner or outer loop. """ self.ops = ops self.x0 = x0 self.niter = niter self.omega = omega self.projection = projection self.random = random self.callback_loop = callback_loop super().__init__(reco_space=self.ops[0].domain, observation_space=ProductSpace(*(op.range for op in self.ops)), callback=callback, **kwargs)
def __init__(self, op, x0, niter, noise='poisson', callback=None, sensitivities=None, **kwargs): """ Calls `odl.solvers.iterative.statistical.osmlem`. Parameters ---------- op : `odl.operator.Operator` or sequence of `odl.operator.Operator` The forward operator(s) of the inverse problem. If an operator sequence is given, Ordered Subsets MLEM is applied. x0 : ``op.domain`` element Initial value. niter : int Number of iterations. noise : {'poisson'}, optional Noise model determining the variant of MLEM. For ``'poisson'``, the initial value of ``x`` should be non-negative. callback : :class:`odl.solvers.util.callback.Callback`, optional Object that is called in each iteration. sensitivities : float or ``op.domain`` `element-like`, optional Usable with ``noise='poisson'``. The algorithm contains an ``A^T 1`` term, if this parameter is given, it is replaced by it. Default: ``op[i].adjoint(op[i].range.one())`` """ self.os_mode = not isinstance(op, Operator) self.op = op if self.os_mode else [op] self.x0 = x0 self.niter = niter self.noise = noise self.sensitivities = sensitivities observation_space = (ProductSpace( *(op.range for op in self.op)) if self.os_mode else self.op[0].range) super().__init__(reco_space=self.op[0].domain, observation_space=observation_space, callback=callback, **kwargs)
def test_matrix_representation_product_to_product_two(): # Verify that the matrix representation function returns the correct matrix n = 3 rn = odl.rn(n) A = np.random.rand(n, n) Aop = odl.MatrixOperator(A) B = np.random.rand(n, n) Bop = odl.MatrixOperator(B) ran_and_dom = ProductSpace(rn, 2) AB_matrix = np.vstack( [np.hstack([A, np.zeros((n, n))]), np.hstack([np.zeros((n, n)), B])]) ABop = ProductSpaceOperator([[Aop, 0], [0, Bop]], ran_and_dom, ran_and_dom) the_matrix = matrix_representation(ABop) assert almost_equal(np.sum(np.abs(AB_matrix - the_matrix)), 1e-6)
def __init__(self, space, alpha=1, grad=None): if not len(space) == 2: raise ValueError('Domain has not the right shape. Len=2 expected') if grad is None: grad = odl.Gradient(space[0], method='forward', pad_mode='symmetric') grad.norm = 2 * np.sqrt(sum(1 / grad.domain.cell_sides**2)) else: grad = grad self.alpha = alpha self.grad = grad self.image_space_time = space[0] self.image_space = self.image_space_time[0] self.vf_space_time = space[1] self.vf_space = self.vf_space_time[0] self.im_vf_space = ProductSpace(self.image_space, self.vf_space) self.N = len(self.image_space_time) # number of time steps super(L1OpticalFlowConstraint, self).__init__(space=space, linear=False, grad_lipschitz=np.nan)
class DataFitL2DispAffRest(Functional): def __init__(self, space, data, forward=None): self.space = space self.image_space = self.space[0] self.affine_space = self.space[1] self.rest_space = self.space[2] self.deformation_space = ProductSpace(self.affine_space, self.rest_space) self.data = data if forward is None: self.forward = IdentityOperator(self.image_space) else: self.forward = forward self.datafit = 0.5 * L2NormSquared(self.image_space).translated( self.data) self.embedding_affine_rest = ops.Embedding_Affine_Rest( self.deformation_space, self.image_space.tangent_bundle) self.embedding_affine = ops.Embedding_Affine( self.affine_space, self.image_space.tangent_bundle) super(DataFitL2DispAffRest, self).__init__(space=space, linear=False, grad_lipschitz=np.nan) def __call__(self, x): xim = x[0] xaff = x[1] xrest = x[2] xdeform = self.deformation_space.element([xaff, xrest]) transl_operator = self.transl_op_fixed_vf(xdeform) fctl = self.datafit * self.forward * transl_operator return fctl(xim) def transl_op_fixed_im_aff(self, im, aff): affine_deform = defm.LinDeformFixedDisp(self.embedding_affine(aff)) deform_op = defm.LinDeformFixedTempl(affine_deform(im)) transl_operator = deform_op return transl_operator def transl_op_fixed_im_rest(self, im, rest): rest_deform = defm.LinDeformFixedDisp(rest) deformed_im = rest_deform(im) transl_operator = defm.LinDeformFixedTempl( deformed_im) * self.embedding_affine return transl_operator def transl_op_fixed_vf(self, disp): deform_op = defm.LinDeformFixedDisp(self.embedding_affine_rest(disp)) transl_operator = deform_op return transl_operator def partial_gradient(self, i): if i == 0: functional = self class auxOperator(Operator): def __init__(self): super(auxOperator, self).__init__(functional.space, functional.image_space) def _call(self, x, out): xim = x[0] xaff = x[1] xrest = x[2] xdeform = functional.deformation_space.element( [xaff, xrest]) transl_operator = functional.transl_op_fixed_vf(xdeform) func = functional.datafit * functional.forward * transl_operator grad = func.gradient out.assign(grad(xim)) return auxOperator() elif i == 1: functional = self class auxOperator(Operator): def __init__(self): super(auxOperator, self).__init__(functional.space, functional.affine_space) def _call(self, x, out): xim = x[0] xaff = x[1] xrest = x[2] transl_operator = functional.transl_op_fixed_im_rest( xim, xrest) func = functional.datafit * functional.forward * transl_operator grad = func.gradient out.assign(grad(xaff)) return auxOperator() elif i == 2: functional = self class auxOperator(Operator): def __init__(self): super(auxOperator, self).__init__(functional.space, functional.rest_space) def _call(self, x, out): xim = x[0] xaff = x[1] xrest = x[2] transl_operator = functional.transl_op_fixed_im_aff( xim, xaff) func = functional.datafit * functional.forward * transl_operator grad = func.gradient out.assign(grad(xrest)) return auxOperator() else: raise ValueError('No gradient defined for this variable') @property def gradient(self): return BroadcastOperator(*[self.partial_gradient(i) for i in range(3)])
def __init__(self, domain=None, range=None, method='forward', padding_method='constant', padding_value=0): """Initialize a `Divergence` operator instance. Zero padding is assumed for the adjoint of the `Divergence` operator to match the negative `Gradient` operator. Parameters ---------- domain : power space of `DiscreteLp`, optional The space of elements which the operator acts on. This is required if ``range`` is not given. range : `DiscreteLp`, optional The space of elements to which the operator maps. This is required if ``domain`` is not given. method : {'central', 'forward', 'backward'}, optional Finite difference method to be used padding_method : {'constant', 'symmetric', 'periodic'}, optional 'constant' : Pads values outside the domain of ``f`` with a constant value given by ``padding_value``. 'symmetric' : Pads with the reflection of the vector mirrored along the edge of the array. 'periodic' : Pads with the values from the other side of the array. padding_value : `float`, optional If ``padding_method`` is 'constant', ``f`` assumes ``padding_value`` for indices outside the domain of ``f``. Examples -------- >>> import odl >>> ran = odl.uniform_discr([0, 0], [1, 1], (10, 20)) >>> dom = odl.ProductSpace(ran, ran.ndim) # 2-dimensional >>> div_op = Divergence(dom) >>> div_op.range == ran True >>> div_op2 = Divergence(range=ran) >>> div_op2.domain == dom True >>> div_op3 = Divergence(domain=dom, range=ran) >>> div_op3.domain == dom True >>> div_op3.range == ran True """ if domain is None and range is None: raise ValueError('either `domain` or `range` must be specified') if domain is None: if not isinstance(range, DiscreteLp): raise TypeError('`range` {!r} is not a DiscreteLp instance' ''.format(range)) domain = ProductSpace(range, range.ndim) if range is None: if not isinstance(domain, ProductSpace): raise TypeError('`domain` {!r} is not a ProductSpace instance' ''.format(domain)) range = domain[0] linear = not (padding_method == 'constant' and padding_value != 0) super().__init__(domain, range, linear=linear) self.method = method self.padding_method = padding_method self.padding_value = padding_value
class smooth_term_OF(Functional): def __init__(self, space, data, forward, tau, alpha_df, alpha_of, grad=None, huber=False, gamma=1e-7, aug_lagr=False, lagr_mult=None): self.N = round(len(space) / 2) # number of time steps\ self.space = space self.image_space = self.space[0] self.space_time = ProductSpace(self.image_space, self.N) self.data = data self.forward = forward self.tau = tau self.alpha_df = alpha_df self.alpha_of = alpha_of self.grad = grad self.data_fit = DataFitL2TimeDep(self.space, self.data, self.forward, self.alpha_df) self.aug_lagr = aug_lagr if lagr_mult is None: self.lagr_mult = self.space_time.zero() else: self.lagr_mult = lagr_mult if huber is False: self.of_constr = L2OpticalFlowConstraint(self.space, self.tau, self.alpha_of, self.grad) else: self.of_constr = HuberL1OpticalFlowConstraint( self.space, self.tau, self.alpha_of, self.grad, gamma) if aug_lagr is True: self.aug_lagr_term = AugmentedLagrangeTerm(self.space, self.lagr_mult, self.tau, self.grad) super(smooth_term_OF, self).__init__(space=space, linear=False, grad_lipschitz=np.nan) def __call__(self, x): ret = self.data_fit(x) + self.of_constr(x) if self.aug_lagr is True: ret += self.aug_lagr_term(x) return ret @property def gradient(self): grad_df = self.data_fit.gradient grad_of = self.of_constr.gradient if self.aug_lagr is True: grad_al = self.aug_lagr_term.gradient return BroadcastOperator(*[ grad_df[i] + grad_of[i] + grad_al[i] for i in range(2 * self.N) ]) else: return BroadcastOperator( *[grad_df[i] + grad_of[i] for i in range(2 * self.N)])
def __init__(self): super().__init__(domain=odl.Rn(3), range=ProductSpace(odl.Rn(3), ProductSpace(odl.Rn(3), odl.Rn(3))), linear=True)