Example #1
0
def eigenvalues_from_eigenvectors(verts, tris, eigs, Q=None):
    if Q is None:
        Q = compute_mesh_laplacian(verts,
                                   tris,
                                   'cotangent',
                                   return_vertex_area=False)
    return (eigs * (-Q * eigs)).sum(axis=0)
Example #2
0
def manifold_harmonics(verts,
                       tris,
                       K,
                       scaled=True,
                       return_D=False,
                       return_eigenvalues=False):
    Q, vertex_area = compute_mesh_laplacian(verts,
                                            tris,
                                            'cotangent',
                                            return_vertex_area=True,
                                            area_type='lumped_mass')
    if scaled:
        D = sparse.spdiags(vertex_area, 0, len(verts), len(verts))
    else:
        D = sparse.spdiags(np.ones_like(vertex_area), 0, len(verts),
                           len(verts))

    try:
        lambda_dense, Phi_dense = eigsh(-Q, M=D, k=K, sigma=0)
    except RuntimeError, e:
        if e.message == 'Factor is exactly singular':
            logging.warn(
                "factor is singular, trying some regularization and cholmod")
            chol_solve = factorized(-Q + sparse.eye(Q.shape[0]) * 1.e-9)
            OPinv = sparse.linalg.LinearOperator(Q.shape, matvec=chol_solve)
            lambda_dense, Phi_dense = eigsh(-Q, M=D, k=K, sigma=0, OPinv=OPinv)
        else:
            raise e
Example #3
0
 def __init__(self, verts, tris, m=1.0):
     self._verts = verts
     self._tris = tris
     # precompute some stuff needed later on
     e01 = verts[tris[:, 1]] - verts[tris[:, 0]]
     e12 = verts[tris[:, 2]] - verts[tris[:, 1]]
     e20 = verts[tris[:, 0]] - verts[tris[:, 2]]
     self._triangle_area = .5 * veclen(np.cross(e01, e12))
     unit_normal = normalized(np.cross(normalized(e01), normalized(e12)))
     self._un = unit_normal
     self._unit_normal_cross_e01 = np.cross(unit_normal, -e01)
     self._unit_normal_cross_e12 = np.cross(unit_normal, -e12)
     self._unit_normal_cross_e20 = np.cross(unit_normal, -e20)
     # parameters for heat method
     h = np.mean(map(veclen, [e01, e12, e20]))
     t = m * h**2
     # pre-factorize poisson systems
     Lc, vertex_area = compute_mesh_laplacian(verts,
                                              tris,
                                              area_type='lumped_mass')
     A = sparse.spdiags(vertex_area, 0, len(verts), len(verts))
     #self._factored_AtLc = splu((A - t * Lc).tocsc()).solve
     self._factored_AtLc = cholesky((A - t * Lc).tocsc(), mode='simplicial')
     #self._factored_L = splu(Lc.tocsc()).solve
     self._factored_L = cholesky(Lc.tocsc(), mode='simplicial')
Example #4
0
File: cmm.py Project: tneumann/cmm
def compressed_manifold_modes(verts, tris, K, mu, init=None, scaled=False,
                              return_info=False, return_eigenvalues=False, return_D=False,
                              order=True, algorithm=None,
                              **algorithm_params):
    Q, vertex_area = compute_mesh_laplacian(verts, tris, 'cotangent', 
                                            return_vertex_area=True, area_type='lumped_mass')
    if scaled:
        D = sparse.spdiags(np.sqrt(vertex_area), 0, len(verts), len(verts))
        Dinv = sparse.spdiags(1 / np.sqrt(vertex_area), 0, len(verts), len(verts))
    else:
        D = Dinv = None

    if init == 'mh':
        Phi_init = manifold_harmonics(verts, tris, K)
    elif init == 'varimax':
        Phi_init = varimax_modes(verts, tris, K)
    elif type(init) == np.ndarray:
        Phi_init = init
    else:
        Phi_init = None

    if algorithm is None:
        algorithm = solve_compressed_splitorth

    Phi, info = algorithm(
        Q, K, mu1=mu, Phi_init=Phi_init, D=D, Dinv=Dinv, 
        **algorithm_params)

    l = eigenvalues_from_eigenvectors(verts, tris, Phi, Q=Q)
    if order:
        idx = np.abs(l).argsort()
        Phi = Phi[:, idx]
        l = l[idx]

    result = [Phi]
    if return_eigenvalues:
        result.append(l)
    if return_D:
        if D is not None:
            result.append(D * D)
        else:
            result.append(None)
    if return_info:
        result.append(info)
    if len(result) == 1:
        return result[0]
    else:
        return result
Example #5
0
File: cmm.py Project: tneumann/cmm
def manifold_harmonics(verts, tris, K, scaled=True, return_D=False, return_eigenvalues=False):
    Q, vertex_area = compute_mesh_laplacian(
        verts, tris, 'cotangent', 
        return_vertex_area=True, area_type='lumped_mass'
    )
    if scaled:
        D = sparse.spdiags(vertex_area, 0, len(verts), len(verts))
    else:
        D = sparse.spdiags(np.ones_like(vertex_area), 0, len(verts), len(verts))

    try:
        lambda_dense, Phi_dense = eigsh(-Q, M=D, k=K, sigma=0)
    except RuntimeError, e:
        if e.message == 'Factor is exactly singular':
            logging.warn("factor is singular, trying some regularization and cholmod")
            chol_solve = factorized(-Q + sparse.eye(Q.shape[0]) * 1.e-9)
            OPinv = sparse.linalg.LinearOperator(Q.shape, matvec=chol_solve)
            lambda_dense, Phi_dense = eigsh(-Q, M=D, k=K, sigma=0, OPinv=OPinv)
        else:
            raise e
Example #6
0
 def __init__(self, verts, tris, m=1.0):
     self._verts = verts
     self._tris = tris
     # precompute some stuff needed later on
     e01 = verts[tris[:,1]] - verts[tris[:,0]]
     e12 = verts[tris[:,2]] - verts[tris[:,1]]
     e20 = verts[tris[:,0]] - verts[tris[:,2]]
     self._triangle_area = .5 * veclen(np.cross(e01, e12))
     unit_normal = normalized(np.cross(normalized(e01), normalized(e12)))
     self._un = unit_normal
     self._unit_normal_cross_e01 = np.cross(unit_normal, -e01)
     self._unit_normal_cross_e12 = np.cross(unit_normal, -e12)
     self._unit_normal_cross_e20 = np.cross(unit_normal, -e20)
     # parameters for heat method
     h = np.mean(map(veclen, [e01, e12, e20]))
     t = m * h ** 2
     # pre-factorize poisson systems
     Lc, vertex_area = compute_mesh_laplacian(verts, tris, area_type='lumped_mass')
     A = sparse.spdiags(vertex_area, 0, len(verts), len(verts))
     #self._factored_AtLc = splu((A - t * Lc).tocsc()).solve
     self._factored_AtLc = factorized((A - t * Lc).tocsc())
     #self._factored_L = splu(Lc.tocsc()).solve
     self._factored_L = factorized(Lc.tocsc())
Example #7
0
def compressed_manifold_modes(verts,
                              tris,
                              K,
                              mu,
                              init=None,
                              scaled=False,
                              return_info=False,
                              return_eigenvalues=False,
                              return_D=False,
                              order=True,
                              algorithm=None,
                              **algorithm_params):
    Q, vertex_area = compute_mesh_laplacian(verts,
                                            tris,
                                            'cotangent',
                                            return_vertex_area=True,
                                            area_type='lumped_mass')
    if scaled:
        D = sparse.spdiags(np.sqrt(vertex_area), 0, len(verts), len(verts))
        Dinv = sparse.spdiags(1 / np.sqrt(vertex_area), 0, len(verts),
                              len(verts))
    else:
        D = Dinv = None

    if init == 'mh':
        Phi_init = manifold_harmonics(verts, tris, K)
    elif init == 'varimax':
        Phi_init = varimax_modes(verts, tris, K)
    elif type(init) == np.ndarray:
        Phi_init = init
    else:
        Phi_init = None

    if algorithm is None:
        algorithm = solve_compressed_splitorth

    Phi, info = algorithm(Q,
                          K,
                          mu1=mu,
                          Phi_init=Phi_init,
                          D=D,
                          Dinv=Dinv,
                          **algorithm_params)

    l = eigenvalues_from_eigenvectors(verts, tris, Phi, Q=Q)
    if order:
        idx = np.abs(l).argsort()
        Phi = Phi[:, idx]
        l = l[idx]

    result = [Phi]
    if return_eigenvalues:
        result.append(l)
    if return_D:
        if D is not None:
            result.append(D * D)
        else:
            result.append(None)
    if return_info:
        result.append(info)
    if len(result) == 1:
        return result[0]
    else:
        return result
Example #8
0
File: cmm.py Project: tneumann/cmm
def eigenvalues_from_eigenvectors(verts, tris, eigs, Q=None):
    if Q is None:
        Q = compute_mesh_laplacian(verts, tris, 'cotangent', return_vertex_area=False)
    return (eigs * (-Q * eigs)).sum(axis=0)