Ejemplo n.º 1
0
    def __call__(self, y, exact=False, barycentric=False):
        """
        Evaluates the spline function at point(s) y, either with Cartesian or with barycentric coordinates.
        :param y: set of points
        :return: f(y)
        """
        if barycentric:
            b = y
            x = points_from_barycentric_coordinates(self.triangle, b)
        else:
            x = y
            b = barycentric_coordinates(self.triangle, x, exact=exact)

        k = determine_sub_triangle(b)

        if exact:
            return np.array([
                self.polynomial_pieces[k[i]].subs({
                    'X': x[i][0],
                    'Y': x[i][1]
                }) for i in range(len(x))
            ],
                            dtype=object)
        else:
            return np.array([
                self.polynomial_pieces[k[i]].subs({
                    'X': x[i][0],
                    'Y': x[i][1]
                }) for i in range(len(x))
            ],
                            dtype=np.float)
Ejemplo n.º 2
0
def test_coefficients_linear_multiple():
    vertices = np.array([
        [0, 0],
        [1, 0],
        [0, 1]
    ])

    points = np.array([
        [0, 0.25],
        [0, 0.5],
        [0.25, 0.25],
        [0.5, 0],
    ])

    b = barycentric_coordinates(vertices, points)
    k = determine_sub_triangle(b)

    expected = np.array([
        [0, 5, 6],
        [2, 5, 8],
        [3, 6, 9],
        [1, 3, 7]
    ])

    computed = coefficients_linear(k)

    np.testing.assert_almost_equal(computed, expected)
Ejemplo n.º 3
0
def test_coefficients_quadratic_single():
    vertices = np.array([
        [0, 0],
        [1, 0],
        [0, 1]
    ])

    points = np.array([
        [0, 0.25],
        [0, 0.5],
        [0.25, 0.25],
        [0.5, 0],
    ])

    b = barycentric_coordinates(vertices, points)
    k = determine_sub_triangle(b)

    expected = np.array([
        [0, 1, 2, 9, 10, 11],
        [6, 7, 8, 9, 10, 11],
        [1, 2, 3, 6, 10, 11],
        [1, 2, 3, 4, 5, 6]
    ])

    for c, e in zip(k, expected):
        computed = coefficients_quadratic(c)
        np.testing.assert_almost_equal(computed, e)
Ejemplo n.º 4
0
def test_derivative_evaluation_along_edge():
    """
    Test to see if the derivative matches that of the univariate quadratic
    spline along the bottom edge of unit simplex
    """

    triangle = np.array([[0, 0], [1, 0], [0, 1]])
    d = 2
    r = 1
    a = directional_coordinates(triangle, np.array([1, 0]))

    n = 1000
    t_values_1 = np.linspace(0, 0.5, n, endpoint=False)
    t_values_2 = np.linspace(0.5, 1, n, endpoint=False)

    p1 = np.array([t_values_1, np.zeros(n)]).T

    b1 = barycentric_coordinates(triangle, p1)
    k1 = determine_sub_triangle(b1)

    expected_derivative_1 = np.array(
        [edge_1_derivative(t) for t in t_values_1])
    computed_derivative_1 = evaluate_non_zero_basis_derivatives(d=d,
                                                                r=r,
                                                                k=k1,
                                                                b=b1,
                                                                a=a)

    np.testing.assert_almost_equal(expected_derivative_1,
                                   computed_derivative_1)

    p2 = np.array([t_values_2, np.zeros(n)]).T

    b2 = barycentric_coordinates(triangle, p2)
    k2 = determine_sub_triangle(b2)

    expected_derivative_2 = np.array(
        [edge_2_derivative(t) for t in t_values_2])
    computed_derivative_2 = evaluate_non_zero_basis_derivatives(d=d,
                                                                r=r,
                                                                k=k2,
                                                                b=b2,
                                                                a=a)

    np.testing.assert_almost_equal(expected_derivative_2,
                                   computed_derivative_2)
def test_points_from_barycentric_coordinates():
    vertices = np.array([[0, 0], [1, 0], [0, 1]])
    points = sample_triangle(vertices, 450)

    bary_coords = barycentric_coordinates(vertices, points)
    points_from_bary_coords = points_from_barycentric_coordinates(
        vertices, bary_coords)
    np.testing.assert_almost_equal(points, points_from_bary_coords)
def test_barycentric_coordinates_multiple():
    """
    Verifies that ~`barycentric_coordinates` returns the correct values when supplied with an array of input values.
    """

    triangle = np.array([[0, 0], [1, 0], [0, 1]])

    points = np.array([[0, 0], [1, 0], [0, 1], [0.5, 0], [-1, 0], [1.1, 0],
                       [1 / 3, 1 / 3]])

    expected = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1], [0.5, 0.5, 0],
                         [2, -1, 0], [-0.1, 1.1, 0], [1 / 3, 1 / 3, 1 / 3]])

    computed = barycentric_coordinates(triangle, points)
    np.testing.assert_almost_equal(computed, expected)
def test_barycentric_coordinates_single():
    """
    Verifies that ~`barycentric_coordinates` returns the correct values when supplied with a single input value.
    """
    triangle = np.array([[0, 0], [1, 0], [0, 1]])

    points = np.array([[0, 0], [1, 0], [0, 1], [0.5, 0], [-1, 0], [1.1, 0],
                       [1 / 3, 1 / 3]])

    expected = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1], [0.5, 0.5, 0],
                         [2, -1, 0], [-0.1, 1.1, 0], [1 / 3, 1 / 3, 1 / 3]])

    for b, p in zip(expected, points):
        computed = barycentric_coordinates(triangle, p)
        np.testing.assert_almost_equal(computed, np.atleast_2d(b))
Ejemplo n.º 8
0
def test_sample_triangle():
    """
    We sample a triangle, and assert that the barycentric coordinates of the resulting points are all
    positive, hence the points lie inside the triangle.
    """
    triangle = np.array([
        [0, 0],
        [1, 0],
        [0, 1]
    ])
    d = 30

    points = sample_triangle(triangle, d)
    bary_coords = barycentric_coordinates(triangle, points)

    assert np.all(bary_coords[bary_coords > 0])
Ejemplo n.º 9
0
    def find_triangle(self, x):
        """
        Given a point x in the domain of the triangulation, determine for which index i
        the point x lies in triangle i.
        :param np.ndarray x: point of interest
        :return: index i such that x lies in T_i
        """

        for k, T in enumerate(self.triangles):
            vertices = self.vertices[T]
            b = barycentric_coordinates(triangle=vertices, x=x)

            if np.all(b >= 0):
                return k
            else:
                continue

        return k
def test_non_zero_splines_evaluation_multiple_quadratic():
    """
    Computes all the non-zero quadratic basis splines at a set of points, and asserts
    that for each point, the basis functions sum to one.
    """

    triangle = np.array([[0, 0], [1, 0], [0, 1]])

    d = 2

    points = sample_triangle(triangle, 30)
    bary_coords = barycentric_coordinates(triangle, points)
    k = determine_sub_triangle(bary_coords)
    s = evaluate_non_zero_basis_splines(d, bary_coords, k)

    expected_sum = np.ones((len(points)))
    computed_sum = s.sum(axis=1)

    np.testing.assert_almost_equal(expected_sum, computed_sum)
def test_laplacian_quadratic_basis_functions():
    X, Y = sy.symbols('X Y')

    triangle = np.array([[0, 0], [1, 0], [0, 1]])

    S = SplineSpace(triangle, 2)
    points = sample_triangle(triangle, 10)
    for basis_num in range(12):
        b_num = S.basis()[basis_num]
        b_sym = polynomial_pieces(triangle,
                                  KNOT_MULTIPLICITIES_QUADRATIC[basis_num])

        for p in points:
            b = barycentric_coordinates(triangle, p)
            k = determine_sub_triangle(b)[0]
            b_lapl = sy.diff(b_sym[k], X, X) + sy.diff(b_sym[k], Y, Y)
            num_b_sym = sy.lambdify([X, Y], b_lapl)
            np.testing.assert_almost_equal(b_num.lapl(p),
                                           num_b_sym(p[0], p[1]))
Ejemplo n.º 12
0
def test_determine_sub_triangle_multiple():
    triangle = np.array([
        [0, 0],
        [1, 0],
        [0, 1]
    ])

    points = np.array([
        [0, 0.25],
        [0, 0.5],
        [0.25, 0.25],
        [0.5, 0],
    ])
    bary_coords = barycentric_coordinates(triangle, points)
    expected = np.array([
        0, 5, 7, 2
    ])

    computed = determine_sub_triangle(bary_coords)
    np.testing.assert_almost_equal(computed, expected)

    assert computed.dtype == np.int
Ejemplo n.º 13
0
    def D(self, x, u, r):
        """
        Evaluates the r'th directional derivative of the function at the point(s) x in direction u.
        :param x: set of points
        :param u: direction
        :param r: order of derivative
        :return: f^(r)(x)
        """

        b = barycentric_coordinates(self.triangle, x)
        k = determine_sub_triangle(b)
        a = directional_coordinates(self.triangle, u)
        z = evaluate_non_zero_basis_derivatives(a=a,
                                                b=b,
                                                k=k,
                                                r=r,
                                                d=self.degree)
        c = self._non_zero_coefficients(k)

        return np.einsum(
            '...i,...i->...', z,
            c)  # broadcast the dot product to compute all values at once.
Ejemplo n.º 14
0
    def __call__(self, x, barycentric=False, exact=False):
        """
        Evaluates the spline function at point(s) x.
        :param x: set of points
        :return: f(x)
        """
        if barycentric:
            b = x
        else:
            b = barycentric_coordinates(self.triangle, x, exact=exact)

        k = determine_sub_triangle(b)
        z = evaluate_non_zero_basis_splines(
            b=b,
            d=self.degree,
            k=k,
            exact=exact,
            alternative_basis=self.alternative_basis)
        c = self._non_zero_coefficients(k)

        return np.einsum(
            '...i,...i->...', z,
            c)  # broadcast the dot product to compute all values at once.