示例#1
0
def test_empty_partition():
    """Check if empty partitions behave as expected and all methods work."""
    part = odl.RectPartition(odl.IntervalProd([], []),
                             odl.uniform_grid([], [], ()))

    assert part.cell_boundary_vecs == ()
    assert part.nodes_on_bdry is True
    assert part.nodes_on_bdry_byaxis == ()
    assert part.has_isotropic_cells
    assert part.boundary_cell_fractions == ()
    assert part.cell_sizes_vecs == ()
    assert np.array_equal(part.cell_sides, [])
    assert part.cell_volume == 0

    same = odl.RectPartition(odl.IntervalProd([], []),
                             odl.uniform_grid([], [], ()))
    assert part == same
    assert hash(part) == hash(same)
    other = odl.uniform_partition(0, 1, 4)
    assert part != other

    assert part[[]] == part
    assert part.insert(0, other) == other
    assert other.insert(0, part) == other
    assert other.insert(1, part) == other
    assert part.squeeze() == part
    assert part.index([]) == ()
    part.byaxis
    assert part == odl.uniform_partition([], [], ())
    repr(part)
示例#2
0
def test_reciprocal_grid_nd_halfcomplex():

    grid = odl.uniform_grid([0] * 3, [1] * 3, shape=(3, 4, 5))
    s = grid.stride
    n = np.array(grid.shape)
    stride_last = 2 * np.pi / (s[-1] * n[-1])
    n[-1] = n[-1] // 2 + 1

    # Without shift
    rgrid = reciprocal_grid(grid, shift=False, halfcomplex=True)
    assert all_equal(rgrid.shape, n)
    assert rgrid.max_pt[-1] == 0  # last dim is odd

    # With shift
    rgrid = reciprocal_grid(grid, shift=True, halfcomplex=True)
    assert all_equal(rgrid.shape, n)
    assert rgrid.max_pt[-1] == -stride_last / 2

    # Inverting should give back the original
    irgrid = realspace_grid(rgrid, grid.min_pt, halfcomplex=True,
                            halfcx_parity='odd')
    assert irgrid.approx_equals(grid, atol=1e-6)

    with pytest.raises(ValueError):
        realspace_grid(rgrid, grid.min_pt, halfcomplex=True,
                       halfcx_parity='+')
示例#3
0
def test_reciprocal_grid_nd_axes():

    grid = odl.uniform_grid([0] * 3, [1] * 3, shape=(3, 4, 5))
    s = grid.stride
    n = np.array(grid.shape)
    axes_list = [[1, -1], [0], 0, [0, 2, 1], [2, 0]]

    for axes in axes_list:
        active = np.zeros(grid.ndim, dtype=bool)
        active[axes] = True
        inactive = np.logical_not(active)

        true_recip_stride = np.empty(grid.ndim)
        true_recip_stride[active] = 2 * np.pi / (s[active] * n[active])
        true_recip_stride[inactive] = s[inactive]

        # Without shift altogether
        rgrid = reciprocal_grid(grid, shift=False, axes=axes,
                                halfcomplex=False)

        assert all_equal(rgrid.shape, n)
        assert all_almost_equal(rgrid.stride, true_recip_stride)
        assert all_almost_equal(rgrid.min_pt[active], -rgrid.max_pt[active])
        assert all_equal(rgrid.min_pt[inactive], grid.min_pt[inactive])
        assert all_equal(rgrid.max_pt[inactive], grid.max_pt[inactive])

        # Inverting should give back the original
        irgrid = realspace_grid(rgrid, grid.min_pt, axes=axes,
                                halfcomplex=False)
        assert irgrid.approx_equals(grid, atol=1e-6)
示例#4
0
def test_reciprocal_grid_1d(halfcomplex, shift, parity):

    shape = 10 if parity == 'even' else 11
    grid = odl.uniform_grid(0, 1, shape=shape)
    s = grid.stride
    n = np.array(grid.shape)

    rgrid = reciprocal_grid(grid, shift=shift, halfcomplex=halfcomplex)

    # Independent of halfcomplex, shift and parity
    true_recip_stride = 2 * np.pi / (s * n)
    assert all_almost_equal(rgrid.stride, true_recip_stride)

    if halfcomplex:
        assert all_equal(rgrid.shape, n // 2 + 1)

        if parity == 'odd' and shift:
            # Max point should be half a negative recip stride
            assert all_almost_equal(rgrid.max_pt, -true_recip_stride / 2)
        elif parity == 'even' and not shift:
            # Max point should be half a positive recip stride
            assert all_almost_equal(rgrid.max_pt, true_recip_stride / 2)
        elif (parity == 'odd' and not shift) or (parity == 'even' and shift):
            # Max should be zero
            assert all_almost_equal(rgrid.max_pt, 0)
        else:
            raise RuntimeError('parameter combination not covered')
    else:  # halfcomplex = False
        assert all_equal(rgrid.shape, n)

        if (parity == 'even' and shift) or (parity == 'odd' and not shift):
            # Zero should be at index n // 2
            assert all_almost_equal(rgrid[n // 2], 0)
        elif (parity == 'odd' and shift) or (parity == 'even' and not shift):
            # No point should be closer to 0 than half a recip stride
            atol = 0.999 * true_recip_stride / 2
            assert not rgrid.approx_contains(0, atol=atol)
        else:
            raise RuntimeError('parameter combination not covered')

        if not shift:
            # Grid Should be symmetric
            assert all_almost_equal(rgrid.min_pt, -rgrid.max_pt)
            if parity == 'odd':
                # Midpoint should be 0
                assert all_almost_equal(rgrid.mid_pt, 0)

    # Inverting should give back the original
    irgrid = realspace_grid(rgrid,
                            grid.min_pt,
                            halfcomplex=halfcomplex,
                            halfcx_parity=parity)
    assert irgrid.approx_equals(grid, atol=1e-6)
示例#5
0
def test_reciprocal_grid_nd():

    grid = odl.uniform_grid([0] * 3, [1] * 3, shape=(3, 4, 5))
    s = grid.stride
    n = np.array(grid.shape)

    true_recip_stride = 2 * np.pi / (s * n)

    # Without shift altogether
    rgrid = reciprocal_grid(grid, shift=False, halfcomplex=False)

    assert all_equal(rgrid.shape, n)
    assert all_almost_equal(rgrid.stride, true_recip_stride)
    assert all_almost_equal(rgrid.min_pt, -rgrid.max_pt)

    # Inverting should give back the original
    irgrid = realspace_grid(rgrid, grid.min_pt, halfcomplex=False)
    assert irgrid.approx_equals(grid, atol=1e-6)
示例#6
0
def test_reciprocal_grid_nd_shift_list():

    grid = odl.uniform_grid([0] * 3, [1] * 3, shape=(3, 4, 5))
    s = grid.stride
    n = np.array(grid.shape)
    shift = [False, True, False]

    true_recip_stride = 2 * np.pi / (s * n)

    # Shift only the even dimension, then zero must be contained
    rgrid = reciprocal_grid(grid, shift=shift, halfcomplex=False)
    noshift = np.where(np.logical_not(shift))

    assert all_equal(rgrid.shape, n)
    assert all_almost_equal(rgrid.stride, true_recip_stride)
    assert all_almost_equal(rgrid.min_pt[noshift], -rgrid.max_pt[noshift])
    assert all_almost_equal(rgrid[n // 2], [0] * 3)

    # Inverting should give back the original
    irgrid = realspace_grid(rgrid, grid.min_pt, halfcomplex=False)
    assert irgrid.approx_equals(grid, atol=1e-6)
示例#7
0
def test_partition_cell_volume():
    grid = odl.uniform_grid([0, 1], [2, 4], (5, 3))
    intv = odl.IntervalProd([0, 1], [2, 4])
    part = odl.RectPartition(intv, grid)
    true_volume = 0.5 * 1.5
    assert part.cell_volume == true_volume
示例#8
0
def test_partition_cell_sides():
    grid = odl.uniform_grid([0, 1], [2, 4], (5, 3))
    intv = odl.IntervalProd([0, 1], [2, 4])
    part = odl.RectPartition(intv, grid)
    true_sides = [0.5, 1.5]
    assert all_equal(part.cell_sides, true_sides)
示例#9
0
def test_norm_rectangle_boundary(odl_tspace_impl, exponent):
    # Check the constant function 1 in different situations regarding the
    # placement of the outermost grid points.
    impl = odl_tspace_impl

    dtype = 'float32'
    rect = odl.IntervalProd([-1, -2], [1, 2])
    fspace = odl.FunctionSpace(rect, out_dtype=dtype)

    # Standard case
    discr = odl.uniform_discr_fromspace(fspace, (4, 8),
                                        impl=impl,
                                        exponent=exponent)
    if exponent == float('inf'):
        assert discr.one().norm() == 1
    else:
        assert (discr.one().norm() == pytest.approx(rect.volume**(1 /
                                                                  exponent)))

    # Nodes on the boundary (everywhere)
    discr = odl.uniform_discr_fromspace(fspace, (4, 8),
                                        exponent=exponent,
                                        impl=impl,
                                        nodes_on_bdry=True)

    if exponent == float('inf'):
        assert discr.one().norm() == 1
    else:
        assert (discr.one().norm() == pytest.approx(rect.volume**(1 /
                                                                  exponent)))

    # Nodes on the boundary (selective)
    discr = odl.uniform_discr_fromspace(fspace, (4, 8),
                                        exponent=exponent,
                                        impl=impl,
                                        nodes_on_bdry=((False, True), False))

    if exponent == float('inf'):
        assert discr.one().norm() == 1
    else:
        assert (discr.one().norm() == pytest.approx(rect.volume**(1 /
                                                                  exponent)))

    discr = odl.uniform_discr_fromspace(fspace, (4, 8),
                                        exponent=exponent,
                                        impl=impl,
                                        nodes_on_bdry=(False, (True, False)))

    if exponent == float('inf'):
        assert discr.one().norm() == 1
    else:
        assert (discr.one().norm() == pytest.approx(rect.volume**(1 /
                                                                  exponent)))

    # Completely arbitrary boundary
    grid = odl.uniform_grid([0, 0], [1, 1], (4, 4))
    part = odl.RectPartition(rect, grid)
    weight = 1.0 if exponent == float('inf') else part.cell_volume
    tspace = odl.rn(part.shape,
                    dtype=dtype,
                    impl=impl,
                    exponent=exponent,
                    weighting=weight)
    discr = DiscreteLp(fspace, part, tspace)

    if exponent == float('inf'):
        assert discr.one().norm() == 1
    else:
        assert (discr.one().norm() == pytest.approx(rect.volume**(1 /
                                                                  exponent)))
示例#10
0
def test_norm_rectangle_boundary(fn_impl, exponent):
    # Check the constant function 1 in different situations regarding the
    # placement of the outermost grid points.

    if exponent == float('inf'):
        pytest.xfail('inf-norm not implemented in CUDA')

    dtype = 'float32'
    rect = odl.IntervalProd([-1, -2], [1, 2])
    fspace = odl.FunctionSpace(rect, out_dtype=dtype)

    # Standard case
    discr = odl.uniform_discr_fromspace(fspace, (4, 8),
                                        impl=fn_impl, exponent=exponent)
    if exponent == float('inf'):
        assert discr.one().norm() == 1
    else:
        assert almost_equal(discr.one().norm(),
                            (rect.volume) ** (1 / exponent))

    # Nodes on the boundary (everywhere)
    discr = odl.uniform_discr_fromspace(
        fspace, (4, 8), exponent=exponent,
        impl=fn_impl, nodes_on_bdry=True)

    if exponent == float('inf'):
        assert discr.one().norm() == 1
    else:
        assert almost_equal(discr.one().norm(),
                            (rect.volume) ** (1 / exponent))

    # Nodes on the boundary (selective)
    discr = odl.uniform_discr_fromspace(
        fspace, (4, 8), exponent=exponent,
        impl=fn_impl, nodes_on_bdry=((False, True), False))

    if exponent == float('inf'):
        assert discr.one().norm() == 1
    else:
        assert almost_equal(discr.one().norm(),
                            (rect.volume) ** (1 / exponent))

    discr = odl.uniform_discr_fromspace(
        fspace, (4, 8), exponent=exponent,
        impl=fn_impl, nodes_on_bdry=(False, (True, False)))

    if exponent == float('inf'):
        assert discr.one().norm() == 1
    else:
        assert almost_equal(discr.one().norm(),
                            (rect.volume) ** (1 / exponent))

    # Completely arbitrary boundary
    grid = odl.uniform_grid([0, 0], [1, 1], (4, 4))
    part = odl.RectPartition(rect, grid)
    weight = 1.0 if exponent == float('inf') else part.cell_volume
    dspace = odl.rn(part.size, dtype=dtype, impl=fn_impl, exponent=exponent,
                    weighting=weight)
    discr = DiscreteLp(fspace, part, dspace, exponent=exponent)

    if exponent == float('inf'):
        assert discr.one().norm() == 1
    else:
        assert almost_equal(discr.one().norm(),
                            (rect.volume) ** (1 / exponent))
示例#11
0
def test_partition_cell_volume():
    grid = odl.uniform_grid([0, 1], [2, 4], (5, 3))
    intv = odl.IntervalProd([0, 1], [2, 4])
    part = odl.RectPartition(intv, grid)
    true_volume = 0.5 * 1.5
    assert part.cell_volume == true_volume
示例#12
0
def test_partition_cell_sides():
    grid = odl.uniform_grid([0, 1], [2, 4], (5, 3))
    intv = odl.IntervalProd([0, 1], [2, 4])
    part = odl.RectPartition(intv, grid)
    true_sides = [0.5, 1.5]
    assert all_equal(part.cell_sides, true_sides)
示例#13
0
def numba_example():
    # Some functions are not easily vectorized, here we can use Numba to
    # improve performance.
    # See http://numba.pydata.org/

    try:
        import numba
    except ImportError:
        print('Numba not installed, skipping.')
        return

    def myfunc(x):
        """Return x - y if x > y, otherwise return x + y."""
        if x[0] > x[1]:
            return x[0] - x[1]
        else:
            return x[0] + x[1]

    # Numba expects functions f(x1, x2, x3, ...), while we have the
    # convention f(x) with x = (x1, x2, x3, ...). Therefore we need
    # to wrap the Numba-vectorized function.
    vectorized = numba.vectorize(lambda x, y: x - y if x > y else x + y)

    def myfunc_numba(x):
        """Return x - y if x > y, otherwise return x + y."""
        return vectorized(x[0], x[1])

    def myfunc_vec(x):
        """Return x - y if x > y, otherwise return x + y."""
        # This implementation uses Numpy's fast built-in vectorization
        # directly. The function np.where checks the condition in the
        # first argument and takes the values from the second argument
        # for all entries where the condition is `True`, otherwise
        # the values from the third argument are taken. The arrays are
        # automatically broadcast, i.e. the broadcast shape of the
        # condition expression determines the output shape.
        return np.where(x[0] > x[1], x[0] - x[1], x[0] + x[1])

    # Create (continuous) functions in the space of function defined
    # on the rectangle [0, 1] x [0, 1].
    f_vec = sampling_function(myfunc_vec,
                              domain=odl.IntervalProd([0, 0], [1, 1]))
    f_numba = sampling_function(myfunc_numba,
                                domain=odl.IntervalProd([0, 0], [1, 1]))

    # Create a unform grid in [0, 1] x [0, 1] (fspace.domain) with 2000
    # samples per dimension.
    grid = odl.uniform_grid([0, 0], [1, 1], shape=(2000, 2000))
    # The points() method really creates all grid points (2000^2) and
    # stores them one-by-one (row-wise) in a large array with shape
    # (2000*2000, 2). Since the function expects points[i] to be the
    # array of i-th components of all points, we need to transpose.
    points = grid.points().T
    # The meshgrid property only returns a sparse representation of the
    # grid, a tuple whose i-th entry is the vector of all possible i-th
    # components in the grid (2000). Extra dimensions are added to the
    # vector in order to support automatic broadcasting. This is both
    # faster and more memory-friendly than creating the full point array.
    # See the numpy.meshgrid function for more information.
    mesh = grid.meshgrid  # Returns a sparse meshgrid (2000 * 2)

    print('Native vectorized runtime (points):   {:5f}'
          ''.format(timeit.timeit(lambda: f_vec(points), number=1)))
    print('Native vectorized runtime (meshgrid): {:5f}'
          ''.format(timeit.timeit(lambda: f_vec(mesh), number=1)))
    print('Numba vectorized runtime (points):    {:5f}'
          ''.format(timeit.timeit(lambda: f_numba(points), number=1)))
    print('Numba vectorized runtime (meshgrid):  {:5f}'
          ''.format(timeit.timeit(lambda: f_numba(mesh), number=1)))