Exemple #1
0
def test_point_collocation_scalar_valued_with_param(func_param_nd):
    """Check collocation of scalar-valued functions with parameters."""
    domain = odl.IntervalProd([0, 0], [1, 1])
    points = _points(domain, 3)
    mesh_shape = (2, 3)
    mesh = _meshgrid(domain, mesh_shape)

    func_ref, func = func_param_nd

    true_values_points = func_ref(points, c=2.5)
    true_values_mesh = func_ref(mesh, c=2.5)

    sampl_func = sampling_function(func, domain, out_dtype='float64')
    collocator = partial(point_collocation, sampl_func)

    # Out of place
    result_points = collocator(points, c=2.5)
    result_mesh = collocator(mesh, c=2.5)
    assert all_almost_equal(result_points, true_values_points)
    assert all_almost_equal(result_mesh, true_values_mesh)

    # In place
    out_points = np.empty(3, dtype='float64')
    out_mesh = np.empty(mesh_shape, dtype='float64')
    collocator(points, out=out_points, c=2.5)
    collocator(mesh, out=out_mesh, c=2.5)
    assert all_almost_equal(out_points, true_values_points)
    assert all_almost_equal(out_mesh, true_values_mesh)

    # Complex output
    true_values_points = func_ref(points, c=2j)
    true_values_mesh = func_ref(mesh, c=2j)

    sampl_func = sampling_function(func, domain, out_dtype='complex128')
    collocator = partial(point_collocation, sampl_func)

    result_points = collocator(points, c=2j)
    result_mesh = collocator(mesh, c=2j)
    assert all_almost_equal(result_points, true_values_points)
    assert all_almost_equal(result_mesh, true_values_mesh)
Exemple #2
0
def performance_example():
    # Simple function, already supports vectorization
    f_vec = sampling_function(lambda x: x**2, domain=odl.IntervalProd(0, 1))

    # Vectorized with NumPy's poor man's vectorization function
    f_novec = np.vectorize(lambda x: x**2)

    # We test both versions with 10000 evaluation points. The natively
    # vectorized version should be much faster than the one using
    # numpy.vectorize.
    points = np.linspace(0, 1, 10000)

    print('Vectorized runtime:     {:5f}'
          ''.format(timeit.timeit(lambda: f_vec(points), number=100)))
    print('Non-vectorized runtime: {:5f}'
          ''.format(timeit.timeit(lambda: f_novec(points), number=100)))
Exemple #3
0
def test_fspace_elem_eval_unusual_dtypes():
    """Check evaluation with unusual data types (int and string)."""
    domain = odl.Strings(3)
    strings = np.array(['aa', 'b', 'cab', 'aba'])
    out_vec = np.empty((4, ), dtype='int64')

    # Can be vectorized for arrays only
    sampl_func = sampling_function(
        lambda s: np.array([str(si).count('a') for si in s]),
        domain,
        out_dtype='int64')
    collocator = partial(point_collocation, sampl_func)

    true_values = [2, 0, 1, 2]

    assert collocator('abc') == 1
    assert all_equal(collocator(strings), true_values)
    collocator(strings, out=out_vec)
    assert all_equal(out_vec, true_values)
Exemple #4
0
def test_point_collocation_vector_valued(func_vec_nd):
    """Check collocation of vector-valued functions."""
    domain = odl.IntervalProd([0, 0], [1, 1])
    points = _points(domain, 3)
    mesh_shape = (2, 3)
    mesh = _meshgrid(domain, mesh_shape)
    point = [0.5, 0.5]
    values_points_shape = (2, 3)
    values_mesh_shape = (2, 2, 3)

    func_ref, func = func_vec_nd

    true_values_points = func_ref(points)
    true_values_mesh = func_ref(mesh)
    true_value_point = func_ref(point)

    sampl_func = sampling_function(func, domain, out_dtype=('float64', (2, )))
    collocator = partial(point_collocation, sampl_func)

    # Out of place
    result_points = collocator(points)
    result_mesh = collocator(mesh)
    assert all_almost_equal(result_points, true_values_points)
    assert all_almost_equal(result_mesh, true_values_mesh)
    assert result_points.dtype == 'float64'
    assert result_mesh.dtype == 'float64'
    assert result_points.flags.writeable
    assert result_mesh.flags.writeable

    # In place
    out_points = np.empty(values_points_shape, dtype='float64')
    out_mesh = np.empty(values_mesh_shape, dtype='float64')
    collocator(points, out=out_points)
    collocator(mesh, out=out_mesh)
    assert all_almost_equal(out_points, true_values_points)
    assert all_almost_equal(out_mesh, true_values_mesh)

    # Single point evaluation
    result_point = collocator(point)
    assert all_almost_equal(result_point, true_value_point)
    out_point = np.empty((2, ), dtype='float64')
    collocator(point, out=out_point)
    assert all_almost_equal(out_point, true_value_point)
Exemple #5
0
def test_fspace_elem_eval_vec_1d(func_vec_1d):
    """Test evaluation in 1d since it's a corner case regarding shapes."""
    domain = odl.IntervalProd(0, 1)
    points = _points(domain, 3)
    mesh_shape = (4, )
    mesh = _meshgrid(domain, mesh_shape)
    point1 = 0.5
    point2 = [0.5]
    values_points_shape = (2, 3)
    values_mesh_shape = (2, 4)
    value_point_shape = (2, )

    func_ref, func = func_vec_1d

    true_result_points = np.array(func_ref(points))
    true_result_mesh = np.array(func_ref(mesh))
    true_result_point = np.array(func_ref(np.array([point1]))).squeeze()

    sampl_func = sampling_function(func, domain, out_dtype=('float64', (2, )))
    collocator = partial(point_collocation, sampl_func)

    result_points = collocator(points)
    result_mesh = collocator(mesh)
    result_point1 = collocator(point1)
    result_point2 = collocator(point2)
    assert all_almost_equal(result_points, true_result_points)
    assert all_almost_equal(result_mesh, true_result_mesh)
    assert all_almost_equal(result_point1, true_result_point)
    assert all_almost_equal(result_point2, true_result_point)

    out_points = np.empty(values_points_shape, dtype='float64')
    out_mesh = np.empty(values_mesh_shape, dtype='float64')
    out_point1 = np.empty(value_point_shape, dtype='float64')
    out_point2 = np.empty(value_point_shape, dtype='float64')
    collocator(points, out=out_points)
    collocator(mesh, out=out_mesh)
    collocator(point1, out=out_point1)
    collocator(point2, out=out_point2)
    assert all_almost_equal(out_points, true_result_points)
    assert all_almost_equal(out_mesh, true_result_mesh)
    assert all_almost_equal(out_point1, true_result_point)
    assert all_almost_equal(out_point2, true_result_point)
Exemple #6
0
def test_point_collocation_tensor_valued(func_tens):
    """Check collocation of tensor-valued functions."""
    domain = odl.IntervalProd([0, 0], [1, 1])
    points = _points(domain, 4)
    mesh_shape = (4, 5)
    mesh = _meshgrid(domain, mesh_shape)
    point = [0.5, 0.5]
    values_points_shape = (2, 3, 4)
    values_mesh_shape = (2, 3, 4, 5)
    value_point_shape = (2, 3)

    func_ref, func = func_tens

    true_result_points = np.array(func_ref(points))
    true_result_mesh = np.array(func_ref(mesh))
    true_result_point = np.array(func_ref(np.array(point)[:, None])).squeeze()

    sampl_func = sampling_function(func, domain, out_dtype=('float64', (2, 3)))
    collocator = partial(point_collocation, sampl_func)

    result_points = collocator(points)
    result_mesh = collocator(mesh)
    result_point = collocator(point)
    assert all_almost_equal(result_points, true_result_points)
    assert all_almost_equal(result_mesh, true_result_mesh)
    assert all_almost_equal(result_point, true_result_point)
    assert result_points.flags.writeable
    assert result_mesh.flags.writeable
    assert result_point.flags.writeable

    out_points = np.empty(values_points_shape, dtype='float64')
    out_mesh = np.empty(values_mesh_shape, dtype='float64')
    out_point = np.empty(value_point_shape, dtype='float64')
    collocator(points, out=out_points)
    collocator(mesh, out=out_mesh)
    collocator(point, out=out_point)
    assert all_almost_equal(out_points, true_result_points)
    assert all_almost_equal(out_mesh, true_result_mesh)
    assert all_almost_equal(out_point, true_result_point)
Exemple #7
0
def test_point_collocation_scalar_valued(domain_ndim, out_dtype, func_nd):
    """Check collocation of scalar-valued functions."""
    domain = odl.IntervalProd([0] * domain_ndim, [1] * domain_ndim)
    points = _points(domain, 3)
    mesh_shape = tuple(range(2, 2 + domain_ndim))
    mesh = _meshgrid(domain, mesh_shape)
    point = [0.5] * domain_ndim

    func_ref, func = func_nd

    true_values_points = func_ref(points)
    true_values_mesh = func_ref(mesh)
    true_value_point = func_ref(point)

    sampl_func = sampling_function(func, domain, out_dtype)
    collocator = partial(point_collocation, sampl_func)

    # Out of place
    result_points = collocator(points)
    result_mesh = collocator(mesh)
    assert all_almost_equal(result_points, true_values_points)
    assert all_almost_equal(result_mesh, true_values_mesh)
    assert result_points.dtype == out_dtype
    assert result_mesh.dtype == out_dtype
    assert result_points.flags.writeable
    assert result_mesh.flags.writeable

    # In place
    out_points = np.empty(3, dtype=out_dtype)
    out_mesh = np.empty(mesh_shape, dtype=out_dtype)
    collocator(points, out=out_points)
    collocator(mesh, out=out_mesh)
    assert all_almost_equal(out_points, true_values_points)
    assert all_almost_equal(out_mesh, true_values_mesh)

    # Single point evaluation
    result_point = collocator(point)
    assert all_almost_equal(result_point, true_value_point)
Exemple #8
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)))