Similar to dihed_cos, but with relative vectors
427561
def _dihed_angle_low(av, bv, cv, deriv):
    """"""
    a = Vector3(9, deriv, av, (0, 1, 2))
    b = Vector3(9, deriv, bv, (3, 4, 5))
    c = Vector3(9, deriv, cv, (6, 7, 8))
    b /= b.norm()
    tmp = b.copy()
    tmp *= dot(a, b)
    a -= tmp
    tmp = b.copy()
    tmp *= dot(c, b)
    c -= tmp
    a /= a.norm()
    c /= c.norm()
    result = dot(a, c).results()
    # avoid trobles with the gradients by either using arccos or arcsin
    if abs(result[0]) < 0.5:
        # if the cosine is far away for -1 or +1, it is safe to take the arccos
        # and fix the sign of the angle.
        sign = 1-(np.linalg.det([av, bv, cv]) > 0)*2
        return _cos_to_angle(result, deriv, sign)
    else:
        # if the cosine is close to -1 or +1, it is better to compute the sine,
        # take the arcsin and fix the sign of the angle
        d = cross(b, a)
        side = (result[0] > 0)*2-1 # +1 means angle in range [-pi/2,pi/2]
        result = dot(d, c).results()
        return _sin_to_angle(result, deriv, side)
65365
def _repole(lon, lat, center):
    
    vec3 = sph2cart(*center)
    vec3 = np.squeeze(vec3)
    if not np.allclose(vec3, [0, 0, 1]):
        vec1 = np.cross(vec3, [0, 0, 1])
    else:
        vec1 = np.cross(vec3, [1, 0, 0])
    vec2 = np.cross(vec3, vec1)
    vecs = [item / np.linalg.norm(item) for item in [vec1, vec2, vec3]]
    basis = np.column_stack(vecs)

    xyz = sph2cart(lon, lat)
    xyz = np.column_stack(xyz)
    prime = xyz.dot(np.linalg.inv(basis))
    lon, lat = cart2sph(*prime.T)
    return lon[:,None], lat[:,None]
645953
def relative_idx(colptr, rowidx, snptr, snpar):
    
    
    relptr = matrix(0, (len(snptr),1))
    relidx = matrix(-1, (colptr[-1],1))

    def lfind(a,b):
        i = 0
        ret = +a
        for k in range(len(a)):
            while a[k] != b[i]: i += 1
            ret[k] = i
            i += 1
        return ret
    
    for k in range(len(snpar)):
        p = snpar[k]
        relptr[k+1] = relptr[k]
        if p != -1:
            nk = snptr[k+1] - snptr[k]
            relptr[k+1] += colptr[k+1] - colptr[k] - nk
            relidx[relptr[k]:relptr[k+1]] = lfind(rowidx[colptr[k]+nk:colptr[k+1]], rowidx[colptr[p]:colptr[p+1]])

    return relptr, relidx[:relptr[k+1]]
533006
def map(self, coords):
        
        m = np.empty(coords.shape)
        m[:, :3] = (coords[:, :3] * self.scale[np.newaxis, :3] +
                    coords[:, 3:] * self.translate[np.newaxis, :3])
        m[:, 3] = coords[:, 3]
        return m
664805
def ndim(self):
        """"""
        try:
            return self.__ndim
        except AttributeError:
            ndim = len(self.coord_vectors)
            self.__ndim = ndim
            return ndim
1101229
def cosine(a, b):
    
    result = np.dot(a, b) / np.linalg.norm(a) / np.linalg.norm(b)
    return np.clip(result, -1, 1)
493866
def dot_v3(v, w):
    """"""

    return sum([x * y for x, y in zip(v, w)])
989122
def G(w, Xs):
    ''''''
    n = len(Xs)
    P = projection_matrix(w)
    Ys = [np.dot(P, X) for X in Xs]
    A = calc_A(Ys)
    A_hat = calc_A_hat(A, skew_matrix(w))

    
    u = sum(np.dot(Y, Y) for Y in Ys) / n
    v = np.dot(A_hat, sum(np.dot(Y, Y) * Y for Y in Ys)) / np.trace(np.dot(A_hat, A))

    return sum((np.dot(Y, Y) - u - 2 * np.dot(Y, v)) ** 2 for Y in Ys)
859592
def dot(self, rhs):
    

    return self.x * rhs.x + self.y * rhs.y + self.z * rhs.z
426114
def get_cartesian_coords(self, fractional_coords: Vector3Like) -> np.ndarray:
        
        return dot(fractional_coords, self._matrix)
465165
def translate(self, disp):
        
        d = Vector(disp[0], disp[1], disp[2])
        for poly in self.polygons:
            for v in poly.vertices:
                v.pos = v.pos.plus(d)
241378
def dot_product(p1, p2, o=(0, 0)):
    
    v1 = vector(o, p1)
    v2 = vector(o, p2)
    return v1[0] * v2[0] + v1[1] * v2[1]
975686
def coords_by_dimension(self, dimensions=3):
        

        coords_matrix = self.vecs[:, :dimensions]
        varexp = self.cve[dimensions - 1]
        return coords_matrix, varexp
1234099
def get_frac_coords_from_lll(self, lll_frac_coords: Vector3Like) -> np.ndarray:
        
        return dot(lll_frac_coords, self.lll_mapping)
1013408
def vector_element(r, i, j):
    

    """
    return Matrix([r[p][i, j] for p in range(3)])
128277
def orthogonal_vector(v):
    """"""
    if v[1] != 0 or v[2] != 0:
        c = (1, 0, 0)
    else:
        c = (0, 1, 0)
    return np.cross(v, c)
904944
def get_aligned_adjacent_coords(x, y):
    '''
    
    '''
    return [(x-1, y), (x-1, y-1), (x, y-1), (x+1, y-1), (x+1, y), (x+1, y+1), (x, y+1), (x-1, y+1)]