ResizingOperator

class odl.discr.discr_ops.ResizingOperator(*args, **kwargs)[source]

Bases: Operator

Operator mapping a discretized function to a new domain.

This operator is a mapping between uniformly discretized DiscretizedSpace spaces with the same DiscretizedSpace.cell_sides, but different DiscretizedSpace.shape. The underlying operation is array resizing, i.e. no resampling is performed. In axes where the domain is enlarged, the new entries are filled ("padded") according to a provided parameter pad_mode.

All resizing operator variants are linear, except constant padding with constant != 0.

See the online documentation on resizing operators for mathematical details.

Attributes:
adjoint

Adjoint of this operator.

axes

Dimensions in which an actual resizing is performed.

domain

Set of objects on which this operator can be evaluated.

inverse

(Pseudo-)Inverse of this operator.

is_functional

True if this operator's range is a Field.

is_linear

True if this operator is linear.

offset

Number of cells added to/removed from the left.

pad_const

Constant used by this operator in case of constant padding.

pad_mode

Padding mode used by this operator.

range

Set in which the result of an evaluation of this operator lies.

Methods

__call__(x[, out])

Return self(x[, out, **kwargs]).

derivative(point)

Derivative of this operator at point.

norm([estimate])

Return the operator norm of this operator.

__init__(domain, range=None, ran_shp=None, **kwargs)[source]

Initialize a new instance.

Parameters:
domainuniform DiscretizedSpace

Uniformly discretized space, the operator can be applied to its elements.

rangeuniform DiscretizedSpace, optional

Uniformly discretized space in which the result of the application of this operator lies. For the default None, a space with the same attributes as domain is used, except for its shape, which is set to ran_shp.

ran_shpsequence of ints, optional

Shape of the range of this operator. This can be provided instead of range and is mandatory if range is None.

offsetint or sequence of ints, optional

Number of cells to add to/remove from the left of domain.partition. By default, the difference is distributed evenly, with preference for left in case of ambiguity. This option is can only be used together with ran_shp.

pad_modestring, optional

Method to be used to fill in missing values in an enlarged array.

'constant': Fill with pad_const.

'symmetric': Reflect at the boundaries, not doubling the outmost values. This requires left and right padding sizes to be strictly smaller than the original array shape.

'periodic': Fill in values from the other side, keeping the order. This requires left and right padding sizes to be at most as large as the original array shape.

'order0': Extend constantly with the outmost values (ensures continuity).

'order1': Extend with constant slope (ensures continuity of the first derivative). This requires at least 2 values along each axis where padding is applied.

pad_constscalar, optional

Value to be used in the 'constant' padding mode.

discr_kwargs: dict, optional

Keyword arguments passed to the uniform_discr constructor.

Examples

The simplest way of initializing a resizing operator is by providing ran_shp and, optionally, parameters for the padding variant to be used. The range is inferred from domain and the supplied parameters. If no offset is given, the difference in size is evenly distributed to both sides:

>>> space = odl.uniform_discr([0, 0], [1, 1], (2, 4))
>>> resize_op = odl.ResizingOperator(space, ran_shp=(4, 4))
>>> resize_op.range
uniform_discr([-0.5,  0. ], [ 1.5,  1. ], (4, 4))

Testing different padding methods in the first axis (zero padding is the default):

>>> x = [[1, 2, 3, 4],
...      [5, 6, 7, 8]]
>>> resize_op = odl.ResizingOperator(space, ran_shp=(4, 4))
>>> print(resize_op(x))
[[ 0.,  0.,  0.,  0.],
 [ 1.,  2.,  3.,  4.],
 [ 5.,  6.,  7.,  8.],
 [ 0.,  0.,  0.,  0.]]
>>>
>>> resize_op = odl.ResizingOperator(space, ran_shp=(4, 4),
...                                  offset=(0, 0),
...                                  pad_mode='periodic')
>>> print(resize_op(x))
[[ 1.,  2.,  3.,  4.],
 [ 5.,  6.,  7.,  8.],
 [ 1.,  2.,  3.,  4.],
 [ 5.,  6.,  7.,  8.]]
>>>
>>> resize_op = odl.ResizingOperator(space, ran_shp=(4, 4),
...                                  offset=(0, 0),
...                                  pad_mode='order0')
>>> print(resize_op(x))
[[ 1.,  2.,  3.,  4.],
 [ 5.,  6.,  7.,  8.],
 [ 5.,  6.,  7.,  8.],
 [ 5.,  6.,  7.,  8.]]

Alternatively, the range of the operator can be provided directly. This requires that the partitions match, i.e. that the cell sizes are the same and there is no shift:

>>> # Same space as in the first example, see above
>>> large_spc = odl.uniform_discr([-0.5, 0], [1.5, 1], (4, 4))
>>> resize_op = odl.ResizingOperator(space, large_spc,
...                                  pad_mode='periodic')
>>> print(resize_op(x))
[[ 5.,  6.,  7.,  8.],
 [ 1.,  2.,  3.,  4.],
 [ 5.,  6.,  7.,  8.],
 [ 1.,  2.,  3.,  4.]]