def forward(self, x):
        """Compute forward-pass of this module on ``x``.

        Parameters
        ----------
        x : `torch.autograd.variable.Variable`
            Input of this layer. The contained tensor must have shape
            ``extra_shape + operator.domain.shape``, and
            ``len(extra_shape)`` must be at least 1 (batch axis).

        Returns
        -------
        out : `torch.autograd.variable.Variable`
            The computed output. Its tensor will have shape
            ``extra_shape + operator.range.shape``, where ``extra_shape``
            are the extra axes of ``x``.

        Examples
        --------
        Evaluating on a 2D tensor, where the operator expects a 1D input,
        i.e., with extra batch axis only:

        >>> matrix = np.array([[1, 0, 0],
        ...                    [0, 1, 1]], dtype='float32')
        >>> odl_op = odl.MatrixOperator(matrix)
        >>> odl_op.domain.shape
        (3,)
        >>> odl_op.range.shape
        (2,)
        >>> op_mod = OperatorAsModule(odl_op)
        >>> t = torch.ones(3)
        >>> x = autograd.Variable(t[None, :]) # "fake" batch axis
        >>> op_mod(x)
        Variable containing:
         1  2
        [torch.FloatTensor of size 1x2]
        >>> t = torch.ones(3)
        >>> x_tensor = torch.stack([0 * t, 1 * t])
        >>> x = autograd.Variable(x_tensor)  # batch of 2 inputs
        >>> op_mod(x)
        Variable containing:
         0  0
         1  2
        [torch.FloatTensor of size 2x2]

        An arbitrary number of axes is supported:

        >>> x = autograd.Variable(t[None, None, :])  # "fake" batch and channel
        >>> op_mod(x)
        Variable containing:
        (0 ,.,.) =
          1  2
        [torch.FloatTensor of size 1x1x2]
        >>> x_tensor = torch.stack([torch.stack([0 * t, 1 * t]),
        ...                         torch.stack([2 * t, 3 * t]),
        ...                         torch.stack([4 * t, 5 * t])])
        >>> x = autograd.Variable(x_tensor)  # batch of 3x2 inputs
        >>> op_mod(x)
        Variable containing:
        (0 ,.,.) =
           0   0
           1   2
        <BLANKLINE>
        (1 ,.,.) =
           2   4
           3   6
        <BLANKLINE>
        (2 ,.,.) =
           4   8
           5  10
        [torch.FloatTensor of size 3x2x2]
        """
        in_shape = x.data.shape
        op_in_shape = self.op_func.operator.domain.shape
        op_out_shape = self.op_func.operator.range.shape

        extra_shape = in_shape[:-len(op_in_shape)]

        if in_shape[-len(op_in_shape):] != op_in_shape or not extra_shape:
            shp_str = str(op_in_shape).strip('()')
            raise ValueError('expected input of shape (N, *, {}), got input '
                             'with shape {}'.format(shp_str, in_shape))

        # Flatten extra axes, then do one entry at a time
        newshape = (int(np.prod(extra_shape)),) + op_in_shape
        x_flat_xtra = x.reshape(*newshape)
        results = []
        for i in range(x_flat_xtra.data.shape[0]):
            results.append(self.op_func(x_flat_xtra[i]))

        # Reshape the resulting stack to the expected output shape
        stack_flat_xtra = torch.stack(results)
        return stack_flat_xtra.view(extra_shape + op_out_shape)
def forward ( self , x ) : in_shape = x . data . shape op_in_shape = self . op_func . operator . domain . shape op_out_shape = self . op_func . operator . range . shape extra_shape = in_shape [ : - len ( op_in_shape ) ] if in_shape [ - len ( op_in_shape ) : ] != op_in_shape or not extra_shape : shp_str = str ( op_in_shape ) . strip ( '()' ) raise ValueError ( 'expected input of shape (N, *, {}), got input ' 'with shape {}' . format ( shp_str , in_shape ) ) newshape = ( int ( np . prod ( extra_shape ) ) , ) + op_in_shape x_flat_xtra = x . reshape ( * newshape ) results = [ ] for i in range ( x_flat_xtra . data . shape [ 0 ] ) : results . append ( self . op_func ( x_flat_xtra [ i ] ) ) stack_flat_xtra = torch . stack ( results ) return stack_flat_xtra . view ( extra_shape + op_out_shape )
Compute forward-pass of this module on ``x``.

        Parameters
        ----------
        x : `torch.autograd.variable.Variable`
            Input of this layer. The contained tensor must have shape
            ``extra_shape + operator.domain.shape``, and
            ``len(extra_shape)`` must be at least 1 (batch axis).

        Returns
        -------
        out : `torch.autograd.variable.Variable`
            The computed output. Its tensor will have shape
            ``extra_shape + operator.range.shape``, where ``extra_shape``
            are the extra axes of ``x``.

        Examples
        --------
        Evaluating on a 2D tensor, where the operator expects a 1D input,
        i.e., with extra batch axis only:

        >>> matrix = np.array([[1, 0, 0],
        ...                    [0, 1, 1]], dtype='float32')
        >>> odl_op = odl.MatrixOperator(matrix)
        >>> odl_op.domain.shape
        (3,)
        >>> odl_op.range.shape
        (2,)
        >>> op_mod = OperatorAsModule(odl_op)
        >>> t = torch.ones(3)
        >>> x = autograd.Variable(t[None, :]) # "fake" batch axis
        >>> op_mod(x)
        Variable containing:
         1  2
        [torch.FloatTensor of size 1x2]
        >>> t = torch.ones(3)
        >>> x_tensor = torch.stack([0 * t, 1 * t])
        >>> x = autograd.Variable(x_tensor)  # batch of 2 inputs
        >>> op_mod(x)
        Variable containing:
         0  0
         1  2
        [torch.FloatTensor of size 2x2]

        An arbitrary number of axes is supported:

        >>> x = autograd.Variable(t[None, None, :])  # "fake" batch and channel
        >>> op_mod(x)
        Variable containing:
        (0 ,.,.) =
          1  2
        [torch.FloatTensor of size 1x1x2]
        >>> x_tensor = torch.stack([torch.stack([0 * t, 1 * t]),
        ...                         torch.stack([2 * t, 3 * t]),
        ...                         torch.stack([4 * t, 5 * t])])
        >>> x = autograd.Variable(x_tensor)  # batch of 3x2 inputs
        >>> op_mod(x)
        Variable containing:
        (0 ,.,.) =
           0   0
           1   2
        <BLANKLINE>
        (1 ,.,.) =
           2   4
           3   6
        <BLANKLINE>
        (2 ,.,.) =
           4   8
           5  10
        [torch.FloatTensor of size 3x2x2]