示例#1
0
def numerical_gradient(iobj, pos0, delta_t=0.01 / 10.0 / 10.0, order=5):

    check_vector3(pos0)

    assert issubclass(type(iobj), vector3.ImplicitFunction)

    m = order  # sample points: -m,...,-1,0,1,2,...,+m

    sample_points = range(-m, m + 1)
    n = m * 2 + 1

    x0 = 0
    findiff_weights = weights(k=1, x0=x0, xs=np.array(sample_points) * delta_t)

    pos = repeat_vect3(1, pos0)
    pos3 = np.tile(pos, (3 * n, 1))

    assert not issubclass(pos.dtype.type, np.integer)

    dx = repeat_vect3(1, make_vector3(1, 0, 0))
    dy = repeat_vect3(1, make_vector3(0, 1, 0))
    dz = repeat_vect3(1, make_vector3(0, 0, 1))
    dxyz = [dx, dy, dz]

    ci = 0
    for d in range(3):
        for i in sample_points:
            dd = dxyz[d]
            pos3[ci, :] = pos3[ci, :] + (dd * delta_t * float(i))
            ci += 1

    v = iobj.implicitFunction(pos3)

    v3 = np.reshape(v, (3, n), order='C')

    Lipchitz_beta = 1  # order. Keep it 1

    d0 = np.abs(np.diff(v3, axis=1))

    nonsmooth_ness = d0 / (np.abs(delta_t)**Lipchitz_beta)

    d = np.abs(np.diff(v3, n=1, axis=1)) / np.abs(delta_t)
    d = d - np.tile(np.mean(d, axis=1, keepdims=True), (1, d.shape[1]))
    d = np.abs(d) / np.abs(delta_t)
    d = d - np.tile(np.mean(d, axis=1, keepdims=True), (1, d.shape[1]))

    if (np.max(np.ravel(nonsmooth_ness))) > 100 * 10:
        print "warning: nonsmooth ",
    """ Calculating the numerical derivative using finite difference (convolution with weights) """
    # convolusion
    grad_cnv = np.dot(v3, findiff_weights)

    # Detecting sharp edges (non-smooth points, i.e. corners and edges and ridges)
    if np.max(np.abs(grad_cnv)) > 100:
        pass

    return grad_cnv.reshape(1, 3)
示例#2
0
    def test_gradients_using_numerical_gradient(self):
        def blend2():
            m1 = np.eye(4) * 1
            m1[0:3, 3] = [0, 1, 0]
            m1[3, 3] = 1

            m2 = np.eye(4) * 2
            m2[0:3, 3] = [2.5, 0, 0]
            m2[3, 3] = 1

            iobj_v = vector3.SimpleBlend(vector3.Ellipsoid(m1),
                                         vector3.Ellipsoid(m2))
            return iobj_v

        iobj_v = blend2()
        self.check_gradient_function(iobj_v, objname="blend2")

        examples_list = example_objects.get_all_examples([2])
        for example_name in examples_list:
            sys.stderr.write("example_name = ", example_name)
            iobj = example_objects.make_example_vectorized(example_name)
            self.check_gradient_function(iobj, objname=example_name)
        """ numerical """
        x = make_vector3(0, 2, 0)
        g2 = numerical_gradient(iobj_v, x)
        g = iobj_v.implicitGradient(repeat_vect3(1, x))
        np.set_printoptions(
            formatter={'all': lambda x: '' + ("%2.19f" % (x, ))})
        err = np.sum(np.abs(g - g2), axis=1)
        err_max = np.max(np.abs(g - g2), axis=1)
        err_rel = np.sum(np.abs(g - g2), axis=1) / np.mean(np.abs(g))
        sys.stderr.write(err, err_max, err_rel)
        # print(err)
        self.assertTrue(np.all(err < NUMERICAL_GRADIENT_TOLERANCE))
示例#3
0
    def test_unit_cube1(self):
        """  Points inside or outside the unit cube [0,1]^3 """
        count_inside = 0
        count_outside = 0

        my_cube = UnitCube1()
        for i in range(100):
            my_point = np.array(
                [np.random.randn(),
                 np.random.randn(),
                 np.random.randn()]) * 0.5 + 0.5

            is_inside = ((my_point[0] >= 0 - 0.5)
                         and (my_point[0] <= 1.0 - 0.5)
                         and (my_point[1] >= 0 - 0.5)
                         and (my_point[1] <= 1.0 - 0.5)
                         and (my_point[2] >= 0 - 0.5)
                         and (my_point[2] <= 1.0 - 0.5))

            if is_inside:
                count_inside += 1
            else:
                count_outside += 1

            v2 = my_cube.implicitFunction((repeat_vect3(1,
                                                        my_point)).reshape(3))

            self.assertEqual(is_inside, v2 >= 0,
                             'A point on surface is wrongly classified')

        print "point count: inside, outside = ", count_inside, ",", count_outside
示例#4
0
    def check_gradient_function_point1(self, iobj, x, tolerance, objname):
        """Tests the gradient using numerical method, verify with analytical and vectorized-analytical"""

        assert iobj is not None

        if iobj is not None:
            g_numer_vec = numerical_gradient(iobj, x)

            from vector3 import ImplicitFunction
            assert issubclass(type(iobj), ImplicitFunction)
            g_vec = iobj.implicitGradient(repeat_vect3(1, x))

            np.set_printoptions(
                formatter={'all': lambda x: '' + ("%2.7f" % (x, ))})
            self.check_two_vectors(
                g_vec, g_numer_vec, tolerance,
                "vec numerical versus analytical gradients (%s)" % (objname, ))
示例#5
0
    def test_ellipsoid_random_points(self):
        """Testing hundreds of random points on a sphere of size RADIUS"""
        for i in range(0, 30):

            RADIUS = 3
            POW = 4  # higher POW will get points more toward parallel to axes
            N = 500

            rcenter = make_random_vector3(1000, 1.0)
            centers_a = repeat_vect3(N, rcenter)
            r0 = make_random_vector3_vectorized(N, RADIUS, POW)
            r = r0 + centers_a

            assert r.shape[1] == 3
            xa = r

            m = np.eye(4) * RADIUS
            m[0:3, 3] = rcenter
            m[3, 3] = 1

            expected_grad = -r0
            check_vector3_vectorized(expected_grad)

            self.ellipsoid_point_and_gradient_vectorized(m, xa, expected_grad)
示例#6
0
def numerical_gradient(iobj, pos0, delta_t=0.01/10.0/10.0, order=5):

    check_vector3(pos0)
    assert issubclass(type(iobj), vector3.ImplicitFunction)
    m = order

    _VERBOSE = False
    import finite_diff_weights

    sample_points = range(-m, m+1)
    n = m*2+1

    x0 = 0
    findiff_weights = finite_diff_weights.weights(k=1, x0=x0, xs=np.array(sample_points) * delta_t)

    pos0_3 = repeat_vect3(1, pos0)
    pos = np.tile(pos0_3, (3*n, 1))
    assert not issubclass(pos.dtype.type, np.integer)

    dx = repeat_vect3(1, make_vector3(1, 0, 0))
    dy = repeat_vect3(1, make_vector3(0, 1, 0))
    dz = repeat_vect3(1, make_vector3(0, 0, 1))
    dxyz = [dx, dy, dz]

    ci = 0
    for d in range(3):
        for i in sample_points:
            dd = dxyz[d]
            pos[ci, :] = pos[ci, :] + (dd * delta_t * float(i))
            ci += 1

    v = iobj.implicitFunction(pos)
    v3 = np.reshape(v, (3, n), order='C')

    Lipchitz_beta = 1

    d0 = np.abs(np.diff(v3, axis=1))
    nonsmooth_ness = d0 / (np.abs(delta_t)**Lipchitz_beta)

    d = np.abs(np.diff(v3, n=1, axis=1)) / np.abs(delta_t)
    d = d - np.tile(np.mean(d, axis=1, keepdims=True), (1, d.shape[1]))
    d = np.abs(d) / np.abs(delta_t)
    d = d - np.tile(np.mean(d, axis=1, keepdims=True), (1, d.shape[1]))

    if(np.max(np.ravel(nonsmooth_ness))) > 100*10:
        print "warning: nonsmooth ",

    """ Calculating the numerical derivative using finite difference (convolution with weights) """

    grad_cnv = np.dot(v3, findiff_weights)

    if np.max(np.abs(grad_cnv)) > 100:
        pass

    if _VERBOSE:
        np.set_printoptions(formatter={'all': lambda x: ''+("%2.19f" % (x,))})

    """ Calculating the numerical derivative using 'mean of diff' """
    grad_mean = np.mean(-np.diff(v3, axis=1) / delta_t, axis=1)
    if _VERBOSE:
        sys.stderr.write("grad_mean: ", grad_mean)
        sys.stderr.write("grad_convolusion: ", grad_cnv)

    if False:
        g = iobj.implicitGradient(pos0_3)
    if _VERBOSE:
        sys.stderr.write("grad_analytical: ", g)

        sys.stderr.write("Errors:")
        sys.stderr.write("conv error: ", g - grad_cnv)

        sys.stderr.write("to be continued")

    return grad_cnv
示例#7
0
    def test_ellipsoid_certain_points(self):
        """ Ellipsoid using vectorized calculations """
        N = 10
        _x = make_vector3(0, 0, 1)
        xa = repeat_vect3(N, _x)

        m = np.eye(4)  # makeMatrix4( 1,0,0,0, 0,1,0,0,  0,0,1,0 )
        m[0, 0] = 1
        ga2 = repeat_vect3(N, make_vector3(0, 0, -1))
        self.ellipsoid_point_and_gradient_vectorized(m, xa, ga2)

        m = np.eye(4)
        self.ellipsoid_point_and_gradient_vectorized(
            m, repeat_vect3(N, make_vector3(0, 1, 0)),
            repeat_vect3(N, make_vector3(0, -1, 0)))

        m = np.eye(4)
        self.ellipsoid_point_and_gradient_vectorized(
            m, repeat_vect3(N, make_vector3(1, 0, 0)),
            repeat_vect3(N, make_vector3(-1, 0, 0)))

        xa = repeat_vect3(N, make_vector3(0, 0, 2))
        m = np.eye(4)
        m[2, 2] = 2
        self.ellipsoid_point_and_gradient_vectorized(
            m, xa, repeat_vect3(N, make_vector3(0, 0, -1)))

        xa = repeat_vect3(N, make_vector3(2, 0, 0))
        m = np.eye(4)
        m[0, 0] = 2
        self.ellipsoid_point_and_gradient_vectorized(
            m, xa, repeat_vect3(N, make_vector3(-1, 0, 0)))

        xa = repeat_vect3(N, make_vector3(0, 2, 0))
        m = np.eye(4)
        m[0, 0] = 2
        m[1, 1] = 2
        m[2, 2] = 2
        self.ellipsoid_point_and_gradient_vectorized(
            m, xa, repeat_vect3(N, make_vector3(0, -2, 0)))