Ejemplo n.º 1
0
    def test_order_handling(self, start, end, t_func):
        # geometric_slerp() should handle scenarios with
        # ascending and descending t value arrays gracefully;
        # results should simply be reversed

        # for scrambled / unsorted parameters, the same values
        # should be returned, just in scrambled order

        num_t_vals = 20
        np.random.seed(789)
        forward_t_vals = t_func(0, 10, num_t_vals)
        # normalize to max of 1
        forward_t_vals /= forward_t_vals.max()
        reverse_t_vals = np.flipud(forward_t_vals)
        shuffled_indices = np.arange(num_t_vals)
        np.random.shuffle(shuffled_indices)
        scramble_t_vals = forward_t_vals.copy()[shuffled_indices]

        forward_results = geometric_slerp(start=start,
                                          end=end,
                                          t=forward_t_vals)
        reverse_results = geometric_slerp(start=start,
                                          end=end,
                                          t=reverse_t_vals)
        scrambled_results = geometric_slerp(start=start,
                                            end=end,
                                            t=scramble_t_vals)

        # check fidelity to input order
        assert_allclose(forward_results, np.flipud(reverse_results))
        assert_allclose(forward_results[shuffled_indices], scrambled_results)
Ejemplo n.º 2
0
 def test_input_shape_flat(self, start, end):
     # geometric_slerp should handle input arrays that are
     # not flat appropriately
     with pytest.raises(ValueError, match='one-dimensional'):
         geometric_slerp(start=start,
                         end=end,
                         t=np.linspace(0, 1, 10))
Ejemplo n.º 3
0
 def test_unit_sphere_enforcement(self, start, end):
     # geometric_slerp() should raise on input that clearly
     # cannot be on an n-sphere of radius 1
     with pytest.raises(ValueError, match='unit n-sphere'):
         geometric_slerp(start=start,
                         end=end,
                         t=np.linspace(0, 1, 5))
Ejemplo n.º 4
0
 def test_input_at_least1d(self, start, end):
     # empty inputs to geometric_slerp must
     # be handled appropriately when not detected
     # by mismatch
     with pytest.raises(ValueError, match='at least two-dim'):
         geometric_slerp(start=start,
                         end=end,
                         t=np.linspace(0, 1, 10))
Ejemplo n.º 5
0
 def test_input_dim_mismatch(self, start, end):
     # geometric_slerp must appropriately handle cases where
     # an interpolation is attempted across two different
     # dimensionalities
     with pytest.raises(ValueError, match='dimensions'):
         geometric_slerp(start=start,
                         end=end,
                         t=np.linspace(0, 1, 10))
Ejemplo n.º 6
0
    def test_degenerate_input(self, start, t):
        shape = (t.size,) + start.shape
        expected = np.full(shape, start)

        actual = geometric_slerp(start=start, end=start, t=t)
        assert_allclose(actual, expected)

        # Check that degenerate and non-degenerate inputs yield the same size
        non_degenerate = geometric_slerp(start=start, end=start[::-1], t=t)
        assert actual.size == non_degenerate.size
Ejemplo n.º 7
0
    def test_interpolation_param_ndim(self, t):
        # regression test for gh-14465
        arr1 = np.array([0, 1])
        arr2 = np.array([1, 0])

        with pytest.raises(ValueError):
            geometric_slerp(start=arr1, end=arr2, t=t)

        with pytest.raises(ValueError):
            geometric_slerp(start=arr1, end=arr1, t=t)
Ejemplo n.º 8
0
 def test_t_values_limits(self, t):
     # geometric_slerp() should appropriately handle
     # interpolation parameters < 0 and > 1
     with pytest.raises(ValueError, match='interpolation parameter'):
         _ = geometric_slerp(start=np.array([1, 0]),
                             end=np.array([0, 1]),
                             t=t)
Ejemplo n.º 9
0
 def test_0_sphere_handling(self, start, end):
     # it does not make sense to interpolate the set of
     # two points that is the 0-sphere
     with pytest.raises(ValueError, match='at least two-dim'):
         _ = geometric_slerp(start=start,
                             end=end,
                             t=np.linspace(0, 1, 4))
Ejemplo n.º 10
0
    def test_degenerate_input(self, start, t):
        if np.asarray(t).ndim > 1:
            with pytest.raises(ValueError):
                geometric_slerp(start=start, end=start, t=t)
        else:

            shape = (t.size,) + start.shape
            expected = np.full(shape, start)

            actual = geometric_slerp(start=start, end=start, t=t)
            assert_allclose(actual, expected)

            # Check that degenerate and non-degenerate
            # inputs yield the same size
            non_degenerate = geometric_slerp(start=start, end=start[::-1], t=t)
            assert actual.size == non_degenerate.size
Ejemplo n.º 11
0
 def test_tol_sign(self, tol):
     # geometric_slerp() currently handles negative
     # tol values, as long as they are floats
     _ = geometric_slerp(start=np.array([1, 0]),
                         end=np.array([0, 1]),
                         t=np.linspace(0, 1, 5),
                         tol=tol)
Ejemplo n.º 12
0
 def test_straightforward_examples(self, start, end, expected):
     # some straightforward interpolation tests, sufficiently
     # simple to use the unit circle to deduce expected values;
     # for larger dimensions, pad with constants so that the
     # data is N-D but simpler to reason about
     actual = geometric_slerp(start=start, end=end, t=np.linspace(0, 1, 4))
     assert_allclose(actual, expected, atol=1e-16)
Ejemplo n.º 13
0
 def test_tol_type(self, tol):
     # geometric_slerp() should raise if tol is not
     # a suitable float type
     with pytest.raises(ValueError, match='must be a float'):
         _ = geometric_slerp(start=np.array([1, 0]),
                             end=np.array([0, 1]),
                             t=np.linspace(0, 1, 5),
                             tol=tol)
Ejemplo n.º 14
0
 def test_scalar_t(self):
     # when t is a scalar, return value is a single
     # interpolated point of the appropriate dimensionality
     # requested by reviewer in gh-10380
     actual = geometric_slerp([1, 0], [0, 1], 0.5)
     expected = np.array([np.sqrt(2) / 2, np.sqrt(2) / 2], dtype=np.float64)
     assert actual.shape == (2, )
     assert_allclose(actual, expected)
Ejemplo n.º 15
0
 def test_degenerate_input(self, start):
     # handle start == end with repeated value
     # like np.linspace
     expected = [start] * 5
     actual = geometric_slerp(start=start,
                              end=start,
                              t=np.linspace(0, 1, 5))
     assert_allclose(actual, expected)
Ejemplo n.º 16
0
    def test_handle_antipodes(self, start, end, expected):
        # antipodal points must be handled appropriately;
        # there are an infinite number of possible geodesic
        # interpolations between them in higher dims
        if expected == "warning":
            with pytest.warns(UserWarning, match='antipodes'):
                res = geometric_slerp(start=start,
                                      end=end,
                                      t=np.linspace(0, 1, 10))
        else:
            res = geometric_slerp(start=start,
                                  end=end,
                                  t=np.linspace(0, 1, 10))

        # antipodes or near-antipodes should still produce
        # slerp paths on the surface of the sphere (but they
        # may be ambiguous):
        assert_allclose(np.linalg.norm(res, axis=1), 1.0)
Ejemplo n.º 17
0
 def test_ultra_close_gens(self):
     # use geometric_slerp to produce generators that
     # are close together, to push the limits
     # of the area (angle) calculations
     # also, limit generators to a single hemisphere
     path = geometric_slerp([0, 0, 1], [1, 0, 0], t=np.linspace(0, 1, 1000))
     sv = SphericalVoronoi(path)
     areas = sv.calculate_areas()
     assert_almost_equal(areas.sum(), 4 * np.pi)
Ejemplo n.º 18
0
    def test_shape_property(self, n_dims, n_pts):
        # geometric_slerp output shape should match
        # input dimensionality & requested number
        # of interpolation points
        start, end = _generate_spherical_points(n_dims, 2)

        actual = geometric_slerp(start=start,
                                 end=end,
                                 t=np.linspace(0, 1, n_pts))

        assert actual.shape == (n_pts, n_dims)
Ejemplo n.º 19
0
def addCamerafield(points,delthe,delphi):
    """add the FOV of the camera"""
    radius = RADIUS
    # center = np.array([0, 0, 0])
    t_vals = np.linspace(0, 1, 2000)  # set the num of points on the line
    result = np.random.rand(0, 2000, 3)
    n = len(points)
    for i in range(n-2):
        for j in range(4):
            sphepoints=cart2spher(points[i])
            start = spher2cart(sphepoints+[sqrt(2)*cos(pi/4+j*pi/2)*delthe,sqrt(2)*sin(pi/4+j*pi/2)*delphi])
            end = spher2cart(sphepoints+[sqrt(2)*cos(pi/4+(j+1)*pi/2)*delthe,sqrt(2)*sin(pi/4+(j+1)*pi/2)*delphi])
            temp = geometric_slerp(start, end, t_vals)
            result = np.concatenate((result, temp[None]), axis=0)
    return radius*result
Ejemplo n.º 20
0
 def test_numerical_stability_pi(self, k):
     # geometric_slerp should have excellent numerical
     # stability for angles approaching pi between
     # the start and end points
     angle = np.pi - k
     ts = np.linspace(0, 1, 100)
     P = np.array([1, 0, 0, 0])
     Q = np.array([np.cos(angle), np.sin(angle), 0, 0])
     # the test should only be enforced for cases where
     # geometric_slerp determines that the input is actually
     # on the unit sphere
     with np.testing.suppress_warnings() as sup:
         sup.filter(UserWarning)
         result = geometric_slerp(P, Q, ts, 1e-18)
         norms = np.linalg.norm(result, axis=1)
         error = np.max(np.abs(norms - 1))
         assert error < 4e-15
Ejemplo n.º 21
0
    def test_accept_arraylike(self):
        # array-like support requested by reviewer
        # in gh-10380
        actual = geometric_slerp([1, 0], [0, 1], [0, 1 / 3, 0.5, 2 / 3, 1])

        # expected values are based on visual inspection
        # of the unit circle for the progressions along
        # the circumference provided in t
        expected = np.array(
            [[1, 0], [np.sqrt(3) / 2, 0.5],
             [np.sqrt(2) / 2, np.sqrt(2) / 2], [0.5, np.sqrt(3) / 2], [0, 1]],
            dtype=np.float64)
        # Tyler's original Cython implementation of geometric_slerp
        # can pass at atol=0 here, but on balance we will accept
        # 1e-16 for an implementation that avoids Cython and
        # makes up accuracy ground elsewhere
        assert_allclose(actual, expected, atol=1e-16)
Ejemplo n.º 22
0
    def test_include_ends(self, n_dims, n_pts):
        # geometric_slerp should return a data structure
        # that includes the start and end coordinates
        # when t includes 0 and 1 ends
        # this is convenient for plotting surfaces represented
        # by interpolations for example

        # the generator doesn't work so well for the unit
        # sphere (it always produces antipodes), so use
        # custom values there
        start, end = _generate_spherical_points(n_dims, 2)

        actual = geometric_slerp(start=start,
                                 end=end,
                                 t=np.linspace(0, 1, n_pts))

        assert_allclose(actual[0], start)
        assert_allclose(actual[-1], end)
Ejemplo n.º 23
0
def addVoronoi(points):
    """add voronoi on the surface. Note that before using this function, modify the parameters(radius, center) first"""
    radius = RADIUS
    points = points/radius
    center = np.array([0, 0, 0])
    sv = SphericalVoronoi(points, 1, center)
    sv.sort_vertices_of_regions()
    t_vals = np.linspace(0, 1, 2000)#set the num of points on the line
    result = np.random.rand(0, 2000, 3)
    for region in sv.regions:
        n = len(region)
        for i in range(n):
            start = sv.vertices[region][i]
            end = sv.vertices[region][(i + 1) % n]
            if not (start == end).all():
                temp=radius*geometric_slerp(start, end, t_vals)
                result = np.concatenate((result, temp[None]), axis=0)
    return result
Ejemplo n.º 24
0
 def time_geometric_slerp_3d(self, num_points):
     # time geometric_slerp() for 3D interpolation
     geometric_slerp(start=self.start,
                     end=self.end,
                     t=self.t)
Ejemplo n.º 25
0
 def test_t_values_conversion(self, t):
     with pytest.raises(ValueError):
         _ = geometric_slerp(start=np.array([1]), end=np.array([0]), t=t)
Ejemplo n.º 26
0
# try applying spherical linear interpolation to improve plot
N = spherical_polyon.shape[0]
n_int = 900
interpolated_polygon = np.zeros((N * n_int, 3), dtype=np.float64)
t_values = np.float64(np.linspace(0, 1, n_int))

counter = 0
for i in range(N):
    if i == (N-1):
        next_index = 0
    else:
        next_index = i + 1

    interpolated_polygon[counter:(counter + n_int), ...] = geometric_slerp(spherical_polyon[i],
                                                               spherical_polyon[next_index],
							       t_values)
    counter += n_int

results = lib.cast_subgrids(spherical_polyon=spherical_polyon,
                            MAXD=4)

(edge_count_array_L1,
cartesian_coords_cells_L1,
edge_count_array_L2,
cartesian_coords_cells_L2,
edge_count_array_L3,
cartesian_coords_cells_L3,
edge_count_array_L4,
cartesian_coords_cells_L4) = results