PYTHON/Geometry.py
def mvee(atoms, tol = 0.00001):
    """
    Find the minimum volume ellipse around a set of atom objects.
    Return A, c where the equation for the ellipse given in "center form" is
    (x-c).T * A * (x-c) = 1
    [U Q V] = svd(A); 
    where r = 1/sqrt(Q)
    V is rotation matrix
    U is ??? 
    """
    points_asarray = np.array([atom.coordinates for atom in atoms])
    points = np.asmatrix(points_asarray)
    N, d = points.shape
    Q = np.column_stack((points, np.ones(N))).T
    err = tol+1.0
    u = np.ones(N)/N
    try:
        while err > tol:
            # assert u.sum() == 1 # invariant
            X = Q * np.diag(u) * Q.T
            M = np.diag(Q.T * la.inv(X) * Q)
            jdx = np.argmax(M)
            step_size = (M[jdx]-d-1.0)/((d+1)*(M[jdx]-1.0))
            new_u = (1-step_size)*u
            new_u[jdx] += step_size
            err = la.norm(new_u-u)
            u = new_u
        c = u*points
        A = la.inv(points.T*np.diag(u)*points - c.T*c)/d    
    except: # For singular matrix errors i.e. motif is ellipse rather than ellipsoid
        centroid = np.average(points_asarray,axis=0)
        plane = Plane(atoms)
        normal = np.array([plane.a,plane.b,plane.c])
        norm_mag = np.sqrt(np.dot(normal,normal))
        for i, norm in enumerate(normal):
            normal[i] = norm * 1 / norm_mag
        centroid = np.average(points,axis=0).reshape(-1,3)
        p1 = centroid + normal*0.00001
        p2 = centroid - normal*0.00001
        points_asarray = np.concatenate([points_asarray,p1,p2],axis=0)
        points = np.asmatrix(points_asarray)
        N, d = points.shape
        Q = np.column_stack((points, np.ones(N))).T
        err = tol+1.0
        u = np.ones(N)/N
        while err > tol:
            # assert u.sum() == 1 # invariant
            X = Q * np.diag(u) * Q.T
            M = np.diag(Q.T * la.inv(X) * Q)
            jdx = np.argmax(M)
            step_size = (M[jdx]-d-1.0)/((d+1)*(M[jdx]-1.0))
            new_u = (1-step_size)*u
            new_u[jdx] += step_size
            err = la.norm(new_u-u)
            u = new_u
        c = u*points
        A = la.inv(points.T*np.diag(u)*points - c.T*c)/d   
        
    return np.asarray(A), np.squeeze(np.asarray(c))

    Find the minimum volume ellipse around a set of atom objects.
    Return A, c where the equation for the ellipse given in "center form" is
    (x-c).T * A * (x-c) = 1
    [U Q V] = svd(A); 
    where r = 1/sqrt(Q)
    V is rotation matrix
    U is ??? 
    
Find the minimum volume ellipse around a set of atom objects.
Find the minimum volume ellipse around a set of atom objects .
def mvee(atoms, tol = 0.00001):
    points_asarray = np.array([atom.coordinates for atom in atoms])
    points = np.asmatrix(points_asarray)
    N, d = points.shape
    Q = np.column_stack((points, np.ones(N))).T
    err = tol+1.0
    u = np.ones(N)/N
    try:
        while err > tol:
            X = Q * np.diag(u) * Q.T
            M = np.diag(Q.T * la.inv(X) * Q)
            jdx = np.argmax(M)
            step_size = (M[jdx]-d-1.0)/((d+1)*(M[jdx]-1.0))
            new_u = (1-step_size)*u
            new_u[jdx] += step_size
            err = la.norm(new_u-u)
            u = new_u
        c = u*points
        A = la.inv(points.T*np.diag(u)*points - c.T*c)/d    
    except: 
        centroid = np.average(points_asarray,axis=0)
        plane = Plane(atoms)
        normal = np.array([plane.a,plane.b,plane.c])
        norm_mag = np.sqrt(np.dot(normal,normal))
        for i, norm in enumerate(normal):
            normal[i] = norm * 1 / norm_mag
        centroid = np.average(points,axis=0).reshape(-1,3)
        p1 = centroid + normal*0.00001
        p2 = centroid - normal*0.00001
        points_asarray = np.concatenate([points_asarray,p1,p2],axis=0)
        points = np.asmatrix(points_asarray)
        N, d = points.shape
        Q = np.column_stack((points, np.ones(N))).T
        err = tol+1.0
        u = np.ones(N)/N
        while err > tol:
            X = Q * np.diag(u) * Q.T
            M = np.diag(Q.T * la.inv(X) * Q)
            jdx = np.argmax(M)
            step_size = (M[jdx]-d-1.0)/((d+1)*(M[jdx]-1.0))
            new_u = (1-step_size)*u
            new_u[jdx] += step_size
            err = la.norm(new_u-u)
            u = new_u
        c = u*points
        A = la.inv(points.T*np.diag(u)*points - c.T*c)/d   
    return np.asarray(A), np.squeeze(np.asarray(c))
def mvee ( atoms , tol = 0.00001 ) : points_asarray = np . array ( [ atom . coordinates for atom in atoms ] ) points = np . asmatrix ( points_asarray ) N , d = points . shape Q = np . column_stack ( ( points , np . ones ( N ) ) ) . T err = tol + 1.0 u = np . ones ( N ) / N try : while err > tol : X = Q * np . diag ( u ) * Q . T M = np . diag ( Q . T * la . inv ( X ) * Q ) jdx = np . argmax ( M ) step_size = ( M [ jdx ] - d - 1.0 ) / ( ( d + 1 ) * ( M [ jdx ] - 1.0 ) ) new_u = ( 1 - step_size ) * u new_u [ jdx ] += step_size err = la . norm ( new_u - u ) u = new_u c = u * points A = la . inv ( points . T * np . diag ( u ) * points - c . T * c ) / d except : centroid = np . average ( points_asarray , axis = 0 ) plane = Plane ( atoms ) normal = np . array ( [ plane . a , plane . b , plane . c ] ) norm_mag = np . sqrt ( np . dot ( normal , normal ) ) for i , norm in enumerate ( normal ) : normal [ i ] = norm * 1 / norm_mag centroid = np . average ( points , axis = 0 ) . reshape ( - 1 , 3 ) p1 = centroid + normal * 0.00001 p2 = centroid - normal * 0.00001 points_asarray = np . concatenate ( [ points_asarray , p1 , p2 ] , axis = 0 ) points = np . asmatrix ( points_asarray ) N , d = points . shape Q = np . column_stack ( ( points , np . ones ( N ) ) ) . T err = tol + 1.0 u = np . ones ( N ) / N while err > tol : X = Q * np . diag ( u ) * Q . T M = np . diag ( Q . T * la . inv ( X ) * Q ) jdx = np . argmax ( M ) step_size = ( M [ jdx ] - d - 1.0 ) / ( ( d + 1 ) * ( M [ jdx ] - 1.0 ) ) new_u = ( 1 - step_size ) * u new_u [ jdx ] += step_size err = la . norm ( new_u - u ) u = new_u c = u * points A = la . inv ( points . T * np . diag ( u ) * points - c . T * c ) / d return np . asarray ( A ) , np . squeeze ( np . asarray ( c ) )
Find the minimum volume ellipse around a set of atom objects.
Find the minimum volume ellipse around a set of atom objects .
"""
    Find the minimum volume ellipse around a set of atom objects.
    Return A, c where the equation for the ellipse given in "center form" is
    (x-c).T * A * (x-c) = 1
    [U Q V] = svd(A); 
    where r = 1/sqrt(Q)
    V is rotation matrix
    U is ??? 
    """ # assert u.sum() == 1 # invariant # For singular matrix errors i.e. motif is ellipse rather than ellipsoid # assert u.sum() == 1 # invariant
atoms
tol