Exemplo n.º 1
0
    def derivative(self, displacement):
        """Derivative of the operator at ``displacement``.

        Parameters
        ----------
        displacement : `domain` `element-like`
            Point at which the derivative is computed.

        Returns
        -------
        derivative : `PointwiseInner`
            The derivative evaluated at ``displacement``.
        """
        # To implement the complex case we need to be able to embed the real
        # vector field space into the range of the gradient. Issue #59.
        if not self.range.is_rn:
            raise NotImplementedError('derivative not implemented for complex '
                                      'spaces.')

        displacement = self.domain.element(displacement)

        # TODO: allow users to select what method to use here.
        grad = Gradient(domain=self.range, method='central',
                        pad_mode='symmetric')
        grad_templ = grad(self.template)
        def_grad = self.domain.element(
            [_linear_deform(gf, displacement) for gf in grad_templ])

        return PointwiseInner(self.domain, def_grad)
    def derivative(self, displacement):
        """Derivative of the operator at ``displacement``.

        Parameters
        ----------
        displacement : `domain` `element-like`
            Point at which the derivative is computed.

        Returns
        -------
        derivative : `PointwiseInner`
            The derivative evaluated at ``displacement``.
            
            
        Test derivative TBC
        >>> import odl
        >>> import operators
        >>> import deform
        >>> X = odl.uniform_discr([-1, -1], [1, 1], [10, 10])
        >>> Y_aff = odl.rn(6)
        >>> parameters = Y_aff.element([.1, .1, .1, .1, .1, .1])
        >>> embedding = operators.Embedding_Affine(Y_aff, X.tangent_bundle)
        >>> displacement = embedding(parameters)
        >>> T = deform.LinDeformFixedDispAffine(displacement, parameters)
        >>> x = odl.phantom.white_noise(T.domain)
        >>> y = odl.phantom.white_noise(T.range)
        >>> print(T(x).inner(y)/x.inner(T.adjoint(y)))
        >>> x = odl.phantom.shepp_logan(T.domain)
        >>> y = odl.phantom.shepp_logan(T.domain)
        >>> print(T(x).inner(y)/x.inner(T.adjoint(y)))        
        """
        # To implement the complex case we need to be able to embed the real
        # vector field space into the range of the gradient. Issue #59.
        if not self.range.is_real:
            raise NotImplementedError('derivative not implemented for complex '
                                      'spaces.')

        displacement = self.domain.element(displacement)

        image_pts = self.template.space.points()
        for i, vi in enumerate(displacement):
            image_pts[:, i] += vi.asarray().ravel()

        space = self.template.space

        if space.ndim == 1:
            x = np.unique(space.points()[:, 0])
            itemplate = interpolate.CubicSpline(x, self.template)

            ptsx = image_pts[:, 0]

            dIx = itemplate(ptsx, nu=1)

            grad = space.tangent_bundle.element()
            grad[0] = dIx.reshape(space.shape)
        elif space.ndim == 2:
            x = np.unique(space.points()[:, 0])
            y = np.unique(space.points()[:, 1])
            itemplate = interpolate.RectBivariateSpline(x,
                                                        y,
                                                        self.template,
                                                        kx=2,
                                                        ky=2)

            ptsx = image_pts[:, 0]
            ptsy = image_pts[:, 1]

            dIx = itemplate(ptsx, ptsy, dx=1, dy=0, grid=False)
            dIy = itemplate(ptsx, ptsy, dx=0, dy=1, grid=False)

            def_grad = space.tangent_bundle.element()
            def_grad[0] = dIx.reshape(space.shape)
            def_grad[1] = dIy.reshape(space.shape)

        else:
            raise NotImplementedError('Interpolation not implemented '
                                      'for this dimension.')

        return PointwiseInner(self.domain, def_grad)