Пример #1
0
def general_root(sigma):
    """ The general case of the root of a grade 0,4 multivector """
    output = general_root_val(sigma.value)
    return [
        cf.MultiVector(layout, output[0, :].copy()),
        cf.MultiVector(layout, output[1, :].copy())
    ]
Пример #2
0
def ga_exp(B):
    """
    Fast implementation of the translation and rotation specific exp function
    """
    if np.sum(np.abs(B.value)) < np.finfo(float).eps:
        return cf.MultiVector(layout, unit_scalar_mv.value)
    return cf.MultiVector(layout, val_exp(B.value))
Пример #3
0
    def test_rotor_between_objects(self):
        # Make a big array of data
        n_mvs = 1000
        generator_list = [random_point_pair, random_line, random_circle, \
                          random_sphere, random_plane]
        for generator in generator_list:
            mv_a_array = np.array([generator() for i in range(n_mvs)], dtype=np.double)
            mv_b_array = np.array([generator() for i in range(n_mvs)], dtype=np.double)

            mv_c_array = np.zeros(mv_b_array.shape, dtype=np.double)
            mv_d_array = np.zeros(mv_b_array.shape, dtype=np.double)

            print('Starting kernel')
            t = time.time()
            blockdim = 64
            griddim = int(math.ceil(n_mvs / blockdim))
            rotor_between_objects_kernel[griddim, blockdim](mv_a_array, mv_b_array, mv_c_array)
            end_time = time.time() - t
            print('Kernel finished')
            print(end_time)

            # Now do the non cuda kernel
            t = time.time()
            for i in range(mv_a_array.shape[0]):
                mv_a = cf.MultiVector(self.layout, mv_a_array[i, :])
                mv_b = cf.MultiVector(self.layout, mv_b_array[i, :])
                mv_d_array[i, :] = rotor_between_objects(mv_a, mv_b).value
            print(time.time() - t)

            np.testing.assert_almost_equal(mv_c_array, mv_d_array)
Пример #4
0
def neg_twiddle_root(C):
    """
    Square Root and Logarithm of Rotors
    in 3D Conformal Geometric Algebra
    Using Polar Decomposition
    Leo Dorst and Robert Valkenburg
    """
    output = neg_twiddle_root_val(C.value)
    return [
        cf.MultiVector(layout, output[0, :]),
        cf.MultiVector(layout, output[1, :])
    ]
Пример #5
0
def val_object_cost_function(obj_a_val, obj_b_val):
    """
    Evaluates the rotor cost function between two objects
    """
    grade_a = grade_obj_func(obj_a_val, gradeList, 0.0000001)
    grade_b = grade_obj_func(obj_b_val, gradeList, 0.0000001)
    if grade_a != grade_b:
        return np.finfo(float).max
    else:
        R = rotor_between_objects(cf.MultiVector(layout, obj_a_val),
                                  cf.MultiVector(layout, obj_b_val))
        return np.abs(val_rotor_cost_sparse(R.value))
Пример #6
0
def rotor_between_objects(C1, C2):
    """
    Hadfield and Lasenby AGACSE2018
    For any two conformal objects C1 and C2 this returns a rotor that takes C1 to C2
    Return a valid object from the addition result 1 + C2C1
    """
    if float(gmt_func(C1.value, C1.value)[0]) > 0:
        C = 1 + cf.MultiVector(layout, gmt_func(C2.value, C1.value))
        R = pos_twiddle_root(C)[0]
        return R
    else:
        return (1 -
                cf.MultiVector(layout, gmt_func(C2.value, C1.value))).normal()
Пример #7
0
    def test_normalise_mvs_kernel(self):

        n_mvs = 500
        mv_a_array = np.pi * np.array(
            [random_line().value for i in range(n_mvs)])
        mv_d_array = np.zeros(mv_a_array.shape)
        mv_b_array = mv_a_array.copy()

        print('Starting kernel')
        t = time.time()
        blockdim = 64
        griddim = int(math.ceil(n_mvs / blockdim))
        normalise_mvs_kernel[griddim, blockdim](mv_a_array)
        end_time = time.time() - t
        print('Kernel finished')
        print(end_time)

        # Now do the non cuda kernel
        t = time.time()
        for i in range(mv_a_array.shape[0]):
            mv_a = cf.MultiVector(self.layout, mv_b_array[i, :])
            mv_d_array[i, :] = mv_a.normal().value
        print(time.time() - t)

        np.testing.assert_almost_equal(mv_a_array, mv_d_array)
Пример #8
0
    def MultiVector(self, *args, **kw):
        '''
        create a multivector in this layout

        convenience func to Multivector(layout)
        '''
        return cf.MultiVector(layout=self, *args, **kw)
Пример #9
0
    def parse_multivector(self, mv_string: str) -> 'cf.MultiVector':
        """ Parses a multivector string into a MultiVector object """
        # Get the names of the canonical blades
        blade_name_index_map = {name: index for index, name in enumerate(self.names)}

        # Clean up the input string a bit
        cleaned_string = re.sub('[()]', '', mv_string)

        # Create a multivector
        mv_out = cf.MultiVector(self)

        # Apply the regex
        for m in _blade_pattern.finditer(cleaned_string):
            # Clean up the search result
            cleaned_match = m.group(0)

            # Split on the '^'
            stuff = cleaned_match.split('^')

            if len(stuff) == 2:
                # Extract the value of the blade and the index of the blade
                blade_val = float("".join(stuff[0].split()))
                blade_index = blade_name_index_map[stuff[1].strip()]
                mv_out[blade_index] = blade_val
            elif len(stuff) == 1:
                # Extract the value of the scalar
                blade_val = float("".join(stuff[0].split()))
                blade_index = 0
                mv_out[blade_index] = blade_val
        return mv_out
Пример #10
0
def rotor_vector_to_vector(v1, v2):
    """ Creates a rotor that takes one vector into another """
    if np.sum(np.abs(v1.value - v2.value)) > 0.000001:
        theta = angle_between_vectors(v1, v2)
        return generate_rotation_rotor(theta, v1, v2)
    else:
        mv = cf.MultiVector(layout)
        mv.value[0] = 1.0
        return mv
Пример #11
0
def generate_dilation_rotor(scale):
    """
    Generates a rotor that performs dilation about the origin
    """
    if abs(scale - 1.0) < 0.00001:
        u = np.zeros(32)
        u[0] = 1.0
        return cf.MultiVector(layout, u)
    gamma = math.log(scale)
    return math.cosh(gamma / 2) + math.sinh(gamma / 2) * (ninf ^ no)
Пример #12
0
def rotor_between_objects(X1, X2):
    """
    Lasenby and Hadfield AGACSE2018
    For any two conformal objects X1 and X2 this returns a rotor that takes X1 to X2
    Return a valid object from the addition result 1 + gamma*X2X1
    """
    return cf.MultiVector(
        layout,
        val_rotor_between_objects_root(val_normalised(X1.value),
                                       val_normalised(X2.value)))
Пример #13
0
def val_convert_2D_polar_line_to_conformal_line(rho, theta):
    """ Converts a 2D polar line to a conformal line """
    a = np.cos(theta)
    b = np.sin(theta)
    x0 = a * rho
    y0 = b * rho
    x1 = int(x0 + 10000 * (-b))
    y1 = int(y0 + 10000 * (a))
    x2 = int(x0 - 10000 * (-b))
    y2 = int(y0 - 10000 * (a))
    p1_val = val_convert_2D_point_to_conformal(x1, y1)
    p2_val = val_convert_2D_point_to_conformal(x2, y2)
    line_val = omt_func(omt_func(p1_val, p2_val), ninf_val)
    line_val = line_val / abs(cf.MultiVector(layout, line_val))
    return line_val
Пример #14
0
 def add(a, b):
     return cf.MultiVector(a.layout, a.value + b.value)
Пример #15
0
 def negate(a):
     return cf.MultiVector(a.layout, -a.value)
Пример #16
0
def negative_root(sigma):
    """ Square Root of Rotors - Evaluates the negative root """
    res_val = negative_root_val(sigma.value)
    return cf.MultiVector(layout, res_val)
Пример #17
0
def rotorconversion(x):
    """
    Converts between the parameters of a TR bivector and the rotor that it is generating
    """
    return cf.MultiVector(layout, val_rotorconversion(x))
Пример #18
0
def annhilate_k(K, C):
    """ Removes K from C = KX via (K[0] - K[4])*C """
    return cf.MultiVector(layout, val_annhilate_k(K.value, C.value))
Пример #19
0
def fast_dual(a):
    """
    Fast dual
    """
    return cf.MultiVector(layout, dual_func(a.value))
Пример #20
0
def rotor_between_planes(P1, P2):
    """ return the rotor between two planes """
    return cf.MultiVector(layout,
                          val_rotor_rotor_between_planes(P1.value, P2.value))
Пример #21
0
def val_distance_point_to_line(point, line):
    """
    Returns the euclidean distance between a point and a line
    """
    return float(abs(cf.MultiVector(layout, omt_func(point, line))))
Пример #22
0
def fast_down(mv):
    """ A fast version of down() """
    return cf.MultiVector(layout, val_down(mv.value))
Пример #23
0
def fast_up(mv):
    """ Fast up mapping """
    return cf.MultiVector(layout, val_up(mv.value))
Пример #24
0
def convert_2D_polar_line_to_conformal_line(rho, theta):
    """ Converts a 2D polar line to a conformal line """
    line_val = val_convert_2D_polar_line_to_conformal_line(rho, theta)
    return cf.MultiVector(layout, line_val)
Пример #25
0
def normalised(mv):
    """ fast version of the normal() function """
    return cf.MultiVector(layout, val_normalised(mv.value))
Пример #26
0
def apply_rotor(mv_in, rotor):
    """ Applies rotor to multivector in a fast way """
    return cf.MultiVector(layout, val_apply_rotor(mv_in.value, rotor.value))
Пример #27
0
 def add_e1(a):
     return cf.MultiVector(a.layout, a.value + e1.value)
Пример #28
0
def convert_2D_point_to_conformal(x, y):
    """ Convert a 2D point to conformal """
    return cf.MultiVector(layout, val_convert_2D_point_to_conformal(x, y))
Пример #29
0
def apply_rotor_inv(mv_in, rotor, rotor_inv):
    """ Applies rotor to multivector in a fast way takes pre computed adjoint"""
    return cf.MultiVector(
        layout, val_apply_rotor_inv(mv_in.value, rotor.value, rotor_inv.value))
Пример #30
0
def rotor_between_lines(L1, L2):
    """ return the rotor between two lines """
    return cf.MultiVector(layout, val_rotor_between_lines(L1.value, L2.value))