예제 #1
0
    def devfun(theta):
        LambdatZtW = csc_matrix(Lambdat @ ZtW)

        L = cholesky_AAt(LambdatZtW, beta=1)
        L.L().todense().tofile('L-py.bin')

        # deviance function calculations
        Lambdat.data[:] = thfun(theta)
        Lambdat.todense().tofile('Lambdat-new-py.bin')

        LambdatZtW = csc_matrix(Lambdat @ ZtW)
        L = cholesky_AAt(LambdatZtW, beta=1)
        L.L().todense().tofile('L-new-py.bin')

        cu = L.solve_L(L.apply_P(Lambdat @ ZtWy), use_LDLt_decomposition=False)
        cu.tofile('cu-py.bin')

        RZX = L.solve_L(L.apply_P(Lambdat @ ZtWX),
                        use_LDLt_decomposition=False)
        RZX.tofile('RZX-py.bin')

        DD = XtWX - RZX.T @ RZX
        DD.tofile('DD-py.bin')

        # ran into an issue with using CHOLMOD here, fall back to scipy.sparse
        DD = csc_matrix(DD)
        betab = XtWy - RZX.T @ cu
        beta = spsolve(DD, betab)

        u = L.apply_Pt(
            L.solve_Lt((cu.T - RZX @ beta)[0], use_LDLt_decomposition=False))

        b = Lambdat.T @ u

        mu = Z.T @ b + X @ beta + offset

        # remember to do this in sparse mode
        wtres = Whalf * (y - mu)

        pwrss = (wtres * wtres).sum() + (u * u).sum()

        fn = float(len(mu))
        ld = L.logdet()

        REML = True
        if REML:
            ld += cholesky(DD).logdet()
            fn -= len(beta)

        deviance = ld + fn * (1. + np.log(2. * np.pi * pwrss) - np.log(fn))
        np.array([deviance]).tofile('deviance-py.bin')
        return deviance
예제 #2
0
def normal_equation_projections(A, m, n, orth_tol, max_refin, tol):
    """Return linear operators for matrix A using ``NormalEquation`` approach.
    """
    # Cholesky factorization
    factor = cholesky_AAt(A)

    # z = x - A.T inv(A A.T) A x
    def null_space(x):
        v = factor(A.dot(x))
        z = x - A.T.dot(v)

        # Iterative refinement to improve roundoff
        # errors described in [2]_, algorithm 5.1.
        k = 0
        while orthogonality(A, z) > orth_tol:
            if k >= max_refin:
                break
            # z_next = z - A.T inv(A A.T) A z
            v = factor(A.dot(z))
            z = z - A.T.dot(v)
            k += 1

        return z

    # z = inv(A A.T) A x
    def least_squares(x):
        return factor(A.dot(x))

    # z = A.T inv(A A.T) x
    def row_space(x):
        return A.T.dot(factor(x))

    return null_space, least_squares, row_space
예제 #3
0
 def spsolve(sparse_X, dense_b):
     # wrap the cholesky call in a context manager that swallows the
     # low-level std-out to stop it from swamping our stdout (these low-level
     # prints come from METIS, but the solution behaves as normal)
     with stdout_redirected():
         factor = cholesky_AAt(sparse_X.T)
     return factor(sparse_X.T.dot(dense_b)).toarray()
예제 #4
0
    def __init__(self, At, b, c, K, options):

        # x: lagrange multipliers
        self.x = np.zeros(shape=(c.shape[0], 1))

        # y: free variables
        self.y = np.ones(shape=(b.shape[0], 1))

        # z: conic variables
        zeroCones = np.zeros(shape=(K.f, 1))                              # Equality: 0s
        nnOrthants = np.zeros(shape=(K.l, 1))                              # Inequality: 1s
        PSDs = [np.identity(size).reshape((size**2, 1)) for size in K.s]  # PSD: identity
        self.z = vstack([zeroCones, nnOrthants, *PSDs])                      # Stack up the vectors

        # Primal and dual residuals
        self.pres = np.linalg.norm(c - At*self.y - self.z)
        self.dres = float('inf')

        # Cost
        self.cost = b.transpose() * self.y

        # Time
        self.time = CPUTime()

        # Factorization of system matrix
        self.KKT = cholesky_AAt( At.transpose(), 0.0 )
예제 #5
0
 def spsolve(sparse_X, dense_b):
     # wrap the cholesky call in a context manager that swallows the
     # low-level std-out to stop it from swamping our stdout (these low-level
     # prints come from METIS, but the solution behaves as normal)
     with stdout_redirected():
         factor = cholesky_AAt(sparse_X.T)
     return factor(sparse_X.T.dot(dense_b)).toarray()
예제 #6
0
def normal_equation_projections(A, m, n, orth_tol, max_refin, tol):
    """Return linear operators for matrix A using ``NormalEquation`` approach.
    """
    # Cholesky factorization
    factor = cholesky_AAt(A)

    # z = x - A.T inv(A A.T) A x
    def null_space(x):
        v = factor(A.dot(x))
        z = x - A.T.dot(v)

        # Iterative refinement to improve roundoff
        # errors described in [2]_, algorithm 5.1.
        k = 0
        while orthogonality(A, z) > orth_tol:
            if k >= max_refin:
                break
            # z_next = z - A.T inv(A A.T) A z
            v = factor(A.dot(z))
            z = z - A.T.dot(v)
            k += 1

        return z

    # z = inv(A A.T) A x
    def least_squares(x):
        return factor(A.dot(x))

    # z = A.T inv(A A.T) x
    def row_space(x):
        return A.T.dot(factor(x))

    return null_space, least_squares, row_space
예제 #7
0
파일: LSP.py 프로젝트: RianWoods/GFF
    def projectionls(neighbors, smp, Xsmp2D):
        #n = len(X)

        rows = len(neighbors) + len(smp)
        cols = len(neighbors)

        sA = SparseM2D()

        for i in range(len(neighbors)):
            sA.append(i, i, 1.0)
            maxv = -float('inf')
            minv = float('inf')
            for nv in neighbors[i]:
                j = nv[0]
                w = nv[1]
                if maxv < w:
                    maxv = w
                if minv > w:
                    minv = w

            sumv = 0.0
            for nv in neighbors[i]:
                w = nv[1]
                if maxv > minv:
                    d = (((w - minv) / (maxv - minv)) * (0.9)) + 0.1
                    sumv += (1 / d)

            for nv in neighbors[i]:
                j = nv[0]
                w = nv[1]
                if maxv > minv:
                    d = (((w - minv) / (maxv - minv)) * (0.9)) + 0.1
                    sA.append(i, j, (-((1.0 / d) / sumv)))
                else:
                    sA.append(i, j, (-(1.0 / len(neighbors[i]))))

        # add samples
        for i in range(len(smp)):
            sA.append(len(neighbors) + i, smp[i], 1.0)

        sB = SparseM2D()
        for i in range(len(Xsmp2D)):
            sB.append(len(neighbors) + i, 0, Xsmp2D[i][0])
            sB.append(len(neighbors) + i, 1, Xsmp2D[i][1])

        A = sA.makeScipySparse(rows, cols)
        B = sB.makeScipySparse(rows, 2)

        # ATA = (A.T*A)
        # ATB = (A.T*B)
        # factor = cholesky(ATA, beta=1.0)
        # x2 = factor(ATB).toarray()

        factor = cholesky_AAt(A.T)
        x2 = factor(A.T * B).toarray()

        # print(ATA)
        # print(ATB)
        #print(x2)
        return x2
예제 #8
0
 def spsolve(sparse_X, dense_b):
     # wrap the cholesky call in a context manager that swallows the
     # low-level std-out to stop it from swamping our stdout (these low-level
     # prints come from METIS, but the solution behaves as normal)
     # fileno doesnt seem to work when called by Jupyter
     # comment by Thanos
     #        try:
     #                __IPYTHON__
     #        except NameError:
     with stdout_redirected():
         factor = cholesky_AAt(sparse_X.T)
     #        else:
     #            factor = cholesky_AAt(sparse_X.T)
     return factor(sparse_X.T.dot(dense_b)).toarray()
    def computeExactComponent(self, omega):
        print 'dAlpha'
        print 'build LHS...'
        t0 = time.time()
        #
        #LHS = np.dot(self.hodge1,self.d0.todense())
        #ss = np.shape(omega)[0]
        #LHS = csc_matrix(LHS)
        #LHS = self.d0T.dot(LHS)
        #LHS = LHS #+ (1.e-8 * csc_matrix(np.identity(ss,float)))
        ##
        LHS = self.d0T.dot(self.hodge1)
        ss = np.shape(LHS)[0]
        LHS = csc_matrix(LHS)
        LHS = LHS.dot(self.d0)
        LHS = LHS  #- (1.e-8 * csc_matrix(np.identity(ss,float)))
        #LHS = LHS + (1.e-8 * np.identity(ss,float))
        #LHS = csc_matrix(LHS)
        #
        tSolve = time.time() - t0
        print("...sparse alpha LHS completed.")
        print("alpha LHS build took {:.5f} seconds.".format(tSolve))

        print 'build RHS...'
        t0 = time.time()
        RHS = self.d0T.dot(self.hodge1.dot(omega))
        #RHS = self.d0T.dot(omega)
        tSolve = time.time() - t0
        print("...sparse alpha RHS completed.")
        print("alpha RHS build took {:.5f} seconds.".format(tSolve))

        print 'solve dAlpha'
        #dAlpha = dsolve.spsolve(LHS, RHS , use_umfpack=True)
        #dAlpha = scipy.sparse.linalg.cg(LHS, RHS)[0]

        #sparse LU solve:
        #DLU = scipy.sparse.linalg.splu(LHS)
        #dAlpha = DLU.solve(RHS)

        #sparse Cholesky solve:
        llt = skchol.cholesky_AAt(LHS)  #factor
        dAlpha = llt(RHS)

        # now push alpha to a 1 form using d:
        dAlpha = self.d0.dot(dAlpha)
        #alpha = np.dot(self.d0.todense(),
        #               alpha)
        return dAlpha
예제 #10
0
    def fit(self):
        n = self.X.shape[0]
        self.mphi = self.phi(self.X)
        dphi = self.mphi.shape[1]
        self.factor = spch.cholesky_AAt(self.mphi.T, beta=self.variance)

        # precompute some useful quantities
        z = self.mphi.T.dot(self.y)
        self.theta = self.factor(z)

        # compute nll
        ssqr = self.variance
        ll = 0.5 * (z.T.dot(self.theta) / ssqr - self.factor.logdet()
                    - self.y.T.dot(self.y) / ssqr - np.log(2 * np.pi) * n - np.log(ssqr) * (n - dphi))

        self._nll = -ll[0, 0]
예제 #11
0
파일: nicp.py 프로젝트: HaoyangWang/menpo3d
 def spsolve(sparse_X, dense_b):
     # wrap the cholesky call in a context manager that swallows the
     # low-level std-out to stop it from swamping our stdout (these low-level
     # prints come from METIS, but the solution behaves as normal)
     with stdout_redirected():
         try:
             factor = cholesky_AAt(sparse_X.T)
             X = factor(sparse_X.T.dot(dense_b)).toarray()
         except CholmodError:
             warnings.warn("Matrix not positive definite."
                          "cholesky decomposition not available, using "
                          "scipy solver instead")
             #scipy.io.savemat('/data/tmp16', {'A_s': sparse_X})
             #exit(0)
             X = scipy_spsolve(sparse_X.T.dot(sparse_X),
                         sparse_X.T.dot(dense_b)).toarray()
     return X
예제 #12
0
def test_cholesky_matrix_market():
    for problem in ("well1033", "illc1033", "well1850", "illc1850"):
        X = mm_matrix(problem)
        y = mm_matrix(problem + "_rhs1")
        answer = np.linalg.lstsq(X.todense(), y)[0]
        XtX = (X.T * X).tocsc()
        Xty = X.T * y
        for mode in ("auto", "simplicial", "supernodal"):
            assert_allclose(cholesky(XtX, mode=mode)(Xty), answer)
            assert_allclose(cholesky_AAt(X.T, mode=mode)(Xty), answer)
            assert_allclose(cholesky(XtX, mode=mode).solve_A(Xty), answer)
            assert_allclose(cholesky_AAt(X.T, mode=mode).solve_A(Xty), answer)

            f1 = analyze(XtX, mode=mode)
            f2 = f1.cholesky(XtX)
            assert_allclose(f2(Xty), answer)
            assert_raises(CholmodError, f1, Xty)
            assert_raises(CholmodError, f1.solve_A, Xty)
            assert_raises(CholmodError, f1.solve_LDLt, Xty)
            assert_raises(CholmodError, f1.solve_LD, Xty)
            assert_raises(CholmodError, f1.solve_DLt, Xty)
            assert_raises(CholmodError, f1.solve_L, Xty)
            assert_raises(CholmodError, f1.solve_D, Xty)
            assert_raises(CholmodError, f1.apply_P, Xty)
            assert_raises(CholmodError, f1.apply_Pt, Xty)
            f1.P()
            assert_raises(CholmodError, f1.L)
            assert_raises(CholmodError, f1.LD)
            assert_raises(CholmodError, f1.L_D)
            assert_raises(CholmodError, f1.L_D)
            f1.cholesky_inplace(XtX)
            assert_allclose(f1(Xty), answer)

            f3 = analyze_AAt(X.T, mode=mode)
            f4 = f3.cholesky(XtX)
            assert_allclose(f4(Xty), answer)
            assert_raises(CholmodError, f3, Xty)
            f3.cholesky_AAt_inplace(X.T)
            assert_allclose(f3(Xty), answer)

            print(problem, mode)
            for f in (f1, f2, f3, f4):
                pXtX = XtX.todense()[f.P()[:, np.newaxis],
                                     f.P()[np.newaxis, :]]
                assert_allclose(np.prod(f.D()), np.linalg.det(XtX.todense()))
                assert_allclose((f.L() * f.L().T).todense(), pXtX)
                L, D = f.L_D()
                assert_allclose((L * D * L.T).todense(), pXtX)

                b = np.arange(XtX.shape[0])[:, np.newaxis]
                assert_allclose(f.solve_A(b), np.dot(XtX.todense().I, b))
                assert_allclose(f(b), np.dot(XtX.todense().I, b))
                assert_allclose(f.solve_LDLt(b),
                                np.dot((L * D * L.T).todense().I, b))
                assert_allclose(f.solve_LD(b), np.dot((L * D).todense().I, b))
                assert_allclose(f.solve_DLt(b), np.dot((D * L.T).todense().I,
                                                       b))
                assert_allclose(f.solve_L(b), np.dot(L.todense().I, b))
                assert_allclose(f.solve_Lt(b), np.dot(L.T.todense().I, b))
                assert_allclose(f.solve_D(b), np.dot(D.todense().I, b))

                assert_allclose(f.apply_P(b), b[f.P(), :])
                assert_allclose(f.apply_P(b), b[f.P(), :])
                # Pt is the inverse of P, and argsort inverts permutation
                # vectors:
                assert_allclose(f.apply_Pt(b), b[np.argsort(f.P()), :])
                assert_allclose(f.apply_Pt(b), b[np.argsort(f.P()), :])
예제 #13
0
def solve_linear_system(M,
                        C,
                        backend="all",
                        check=True,
                        backend_error_tol=1e-4,
                        verbose=0):
    """
    **Description:**
    Solves the sparse linear system M*x+C=0.

    **Arguments:**
    - `M` *(scipy.sparse.csr_matrix)*: A scipy csr_matrix.
    - `C` *(array_like)*: A vector of floats.
    - `backend` *(str, optional, default="all")*: The sparse linear solver
      to use. Options are "all", "sksparse" and "scipy". When set to "all" it
      tries all available backends.
    - `check` *(bool, optional, default=True)*: Whether to explicitly
      check the solution to the linear system.
    - `backend_error_tol` *(float, optional, default=1e-4)*: Error
      tolerance for the solution of the linear system.
    - `verbose` *(int, optional, default=0)*: The verbosity level.
      - verbose = 0: Do not print anything.
      - verbose = 1: Print warnings when backends fail.

    **Returns:**
    *(numpy.ndarray)* Floating-point solution to the linear system.

    **Example:**
    We solve a very simple linear equation.
    ```python {5}
    from cytools.utils import to_sparse, solve_linear_system
    id_array = [[0,0,1],[1,1,1],[2,2,1],[3,3,1],[4,4,1]]
    M = to_sparse(id_array, sparse_type="csr")
    C = [1,1,1,1,1]
    solve_linear_system(M, C)
    # array([-1., -1., -1., -1., -1.])
    ```
    """
    backends = ["all", "sksparse", "scipy"]
    if backend not in backends:
        raise Exception("Invalid linear system backend. "
                        f"The options are: {backends}.")
    system_solved = False
    if backend == "all":
        for s in backends[1:]:
            solution = solve_linear_system(M,
                                           C,
                                           backend=s,
                                           check=check,
                                           backend_error_tol=backend_error_tol,
                                           verbose=verbose)
            if solution is not None:
                return solution
    elif backend == "sksparse":
        try:
            from sksparse.cholmod import cholesky_AAt
            factor = cholesky_AAt(M.transpose())
            CC = -M.transpose() * C
            solution = factor(CC)
            system_solved = True
        except:
            if verbose >= 1:
                print("Linear backend error: sksparse failed.")
            system_solved = False
    elif backend == "scipy":
        try:
            from scipy.sparse.linalg import dsolve
            MM = M.transpose() * M
            CC = -M.transpose() * C
            solution = dsolve.spsolve(MM, CC).tolist()
            system_solved = True
        except:
            if verbose >= 1:
                print("Linear backend error: scipy failed.")
            system_solved = False
    if system_solved and check:
        res = M.dot(solution) + C
        max_error = max(abs(s) for s in res.flat)
        if max_error > backend_error_tol:
            system_solved = False
            if verbose >= 1:
                print("Linear backend error: Large numerical error.")
    if system_solved:
        return solution
    else:
        return None
    def execute(self,context):
        path='/home/student/Documents/codeFiles/'#bpy.utils.resource_path('USER') 
        
        SourceInpt=np.loadtxt(path+'source_vertz.txt',delimiter=',')
        TrgtInpt=np.loadtxt(path+'target_vertz.txt',delimiter=',')
        
        
        if int(np.size(TrgtInpt)/len(TrgtInpt))==1:
            TrgtInpt=np.reshape(TrgtInpt,(len(TrgtInpt),1))

        SF=ReadFaces(path+'source_facez.txt')
        TF=ReadFaces(path+'target_facez.txt')
        
        if context.scene.CorrPath!='Default':
            CrT,CrS=ReadCorrespondences(context.scene.CorrPath,TF)
        else:
            CrT=list(range(len(TF)))
            CrS=[i for i in CrT]
        NVrt=len(TrgtInpt)//3
        
        
        NPs=len(SourceInpt[0,:])
        if self.seqType=='DTSumnerPopovic':
            strttime=time.time()
            X=ConnectionMatrices(CrT,TF,NVrt)
            factor=chmd.cholesky(((X[:,:3*(NVrt-1)].transpose().dot(X[:,:3*(NVrt-1)]))).tocsc())
            Vref=X.dot(TrgtInpt[:,0])
            print("Preprocessing....",time.time()-strttime)

            strttime=time.time()
            Vdef=DTSumAndPop(SourceInpt[:,0:2],Vref,SF,CrS)
            Pose=factor(X[:,:3*(NVrt-1)].transpose().dot(Vdef))
            Pose=np.append(Pose,np.zeros(3))
            print("Pose Computation .....",time.time()-strttime)
            
            CreateMesh(np.reshape(Pose,(NVrt,3)),TF,1)
        else:
            strttime=time.time()
            A=sp.lil_matrix((2*len(CrT),NVrt))
            i=0
            for t in CrT:
                A[2*i:2*i+2,TF[t]]=np.array([[-1,1,0],[-1,0,1]])
                i+=1
            A=A.tocsc()
            factor=chmd.cholesky_AAt((A[:,0:(NVrt-1)].transpose()).tocsc())
            print("Preprocessing....",time.time()-strttime)

            strttime=time.time()
            Crrs=[]
            Crrt=[]
            for i in range(len(CrT)):
                Crrt=Crrt+TF[CrT[i]]
                Crrs=Crrs+SF[CrS[i]]
            Y=DTManifold(SourceInpt[:,0:2],TrgtInpt[:,0],Crrt,Crrs)
            P1=np.zeros([NVrt,3])
            P1[:NVrt-1]=factor(A[:,0:NVrt-1].transpose().dot(Y))
            print("Pose Computation .....",time.time()-strttime)
            
            CreateMesh(P1,TF,1)
        
        return {'FINISHED'}
예제 #15
0
    def execute(self, context):
        global Phi, path, FilePath
        ################# Input from user ###############
        Rigname = context.scene.RigName
        if path[len(path) - len(Rigname) - 1:len(path) - 1] != Rigname:
            path = FilePath + Rigname + '/'
        ################################################
        Vrt = np.loadtxt(path + '/' + 'vertz.txt', delimiter=',')
        Fcs = ReadTxt(path + '/' + Rigname + '_facz.txt')
        Nrml = np.loadtxt(path + '/' + 'Normal.txt', delimiter=',')

        NPs, NV = np.shape(Vrt)
        NPs = NPs // 3
        NF = len(Fcs)

        AA = ConnectionMatrices(Fcs, NV, NF)
        factor = chmd.cholesky_AAt(AA[:(NV - 1), :].tocsc())

        ########################## Comute Skeleton Frames ###########################################
        Joints = ReadTxt(path + '/' + Rigname + '_Joints.txt')
        Links = ReadTxt(path + '/' + Rigname + '_SkelEdgz.txt')

        VecIndx = []
        for ln in Links:
            VecIndx.append(ln)

        print("Computing Skeleton Frames.....")
        NJ = len(Joints)

        NFrm = len(VecIndx)
        SFrm = np.zeros([3, 3])
        SrFrm = np.zeros([3, 3 * NFrm])

        A = np.zeros([NJ, 3])
        RS = np.zeros((3 * NFrm, NPs - 1))
        AS = np.zeros((NFrm, NPs - 1))

        for ps in range(NPs):

            X = Vrt[3 * ps:3 * ps + 3, :].T
            for r in range(NJ):
                A[r] = np.mean(X[Joints[r]], axis=0)
            if ps == 0:
                np.savetxt(path + '/' + Rigname + '_RefSkel.txt',
                           A,
                           delimiter=',')

            t = 0
            for r in range(NFrm):

                V = (A[VecIndx[r][0]] - A[VecIndx[r][1]]
                     ) / np.linalg.norm(A[VecIndx[r][0]] - A[VecIndx[r][1]])

                tmp = X[Joints[VecIndx[r][0]][0]] - A[VecIndx[r][0]]
                B = np.cross(V, tmp) / np.linalg.norm(np.cross(V, tmp))
                N = np.cross(B, V) / np.linalg.norm(np.cross(B, V))

                SFrm[:, 0] = V
                SFrm[:, 1] = B
                SFrm[:, 2] = N

                if ps != 0:
                    Axs, Angl = RotMatToAnglAxis(
                        np.dot(SFrm, SrFrm[:, 3 * r:3 * r + 3].T))
                    RS[3 * r:3 * r + 3, ps - 1] = Axs
                    AS[r, ps - 1] = Angl
                else:
                    SrFrm[:, 3 * r:3 * r + 3] = SFrm
        np.savetxt(path + '/' + Rigname + '_RefFrames.txt',
                   SrFrm,
                   delimiter=',')

        ###################  Clustering ###################
        C = ReadTxt(path + '/' + 'ClusterKmeans.txt')
        Ncl = max(C[0]) + 1
        Cls = [[]] * Ncl
        t = 0
        for i in C[0]:
            Cls[i] = Cls[i] + [t]
            t += 1

        Vbar = np.zeros((6 * (NPs - 1), NF))
        Vref = np.zeros((6, NF))
        for i in range(NF):
            f = Fcs[i]
            for ps in range(NPs):
                tmp = Vrt[3 * ps:3 * ps + 3, f[1:]].T - Vrt[3 * ps:3 * ps + 3,
                                                            f[0]]
                if ps != 0:
                    Vbar[6 * (ps - 1):6 * (ps - 1) + 6, i] = np.ravel(tmp)
                else:
                    Vref[:, i] = np.ravel(tmp)

        ############ initialize Dl##################
        Dl = np.zeros((3 * (NPs - 1), 3 * Ncl))
        for j in range(Ncl):
            c = Cls[j]
            for ps in range(1, NPs):

                RefFrm = np.reshape(Vref[:, c], (3, 2 * len(c)), 'F')
                DefFrm = np.reshape(Vbar[6 * (ps - 1):6 * (ps - 1) + 6, c],
                                    (3, 2 * len(c)), 'F')

                X = Multiply(RefFrm, RefFrm.T)
                Y = Multiply(DefFrm, RefFrm.T)
                Dl[3 * (ps - 1):3 * (ps - 1) + 3,
                   3 * j:3 * j + 3] = Y.dot(np.linalg.inv(X))
        ###### Compute Weights #####################

        Q = np.zeros((3, 2 * (NPs - 1)))
        Bt = np.zeros(NF)
        t = 0
        for c in Cls:
            for f in c:
                for ps in range(NPs - 1):
                    tmp = np.reshape(Vref[:, f], (3, 2), 'F')
                    Q[:, 2 * ps:2 * ps + 2] = Dl[3 * ps:3 * ps + 3,
                                                 3 * t:3 * t + 3].dot(tmp)
                Vc = np.reshape(Vbar[:, f], (3, 2 * (NPs - 1)), 'F')
                Bt[f] = np.mean(
                    np.linalg.norm(Vc, axis=0) / np.linalg.norm(Q, axis=0))
            t += 1
        ##################################################################################
        #                        Connect Meshes
        ##################################################################################
        print("Computing Mesh Frames.....")
        RM = np.zeros((3 * Ncl, NPs - 1))
        AM = np.zeros((Ncl, NPs - 1))
        Sc = np.zeros((9 * Ncl, NPs - 1))

        #######################################
        JntPrFace = 2
        W = np.zeros((3 * Ncl, 3 * JntPrFace))
        H = np.zeros((9 * Ncl, 3 * JntPrFace + 1))
        JntInd = []
        Wgts = np.zeros((Ncl, JntPrFace))
        #######################################
        Wtmp = np.zeros((3, 3 * NFrm))
        Theta = np.ones((3 * JntPrFace + 1, NPs - 1))
        #Dl=np.zeros((3*(NPs-1),3*Ncl))
        #Bt=np.zeros(NF)

        for c in range(Ncl):
            for ps in range(NPs - 1):
                Q = Dl[3 * ps:3 * ps + 3, 3 * c:3 * c + 3]
                R, S = scla.polar(Q)
                Axs, Angl = RotMatToAnglAxis(R)

                RM[3 * c:3 * c + 3, ps] = Axs
                AM[c, ps] = Angl
                Sc[9 * c:9 * c + 9, ps] = np.ravel(S)

            Err = []
            for r in range(NFrm):
                U, Lmda, V = np.linalg.svd(
                    (RS[3 * r:3 * r + 3]).dot(RM[3 * c:3 * c + 3].T))
                Wtmp[:, 3 * r:3 * r + 3] = (V.T).dot(U.T)
                Err.append(
                    np.linalg.norm((Wtmp[:, 3 * r:3 * r +
                                         3].dot(RS[3 * r:3 * r + 3])) -
                                   RM[3 * c:3 * c + 3]))

            IndSort = np.argsort(Err)
            JntInd.append(list(IndSort[0:JntPrFace]))

            TotalErr = sum([(1 / Err[i]) for i in IndSort[0:JntPrFace]])
            for i in range(JntPrFace):
                r = IndSort[i]
                u = 0
                l = 0
                for j in range(NPs - 1):
                    if AS[r, j] != 0:
                        u += AM[c, j] / AS[r, j]
                        l += 1
                u = u / l
                W[3 * c:3 * c + 3,
                  3 * i:3 * i + 3] = u * Wtmp[:, 3 * r:3 * r + 3]
                Wgts[c, i] = 1 / (Err[r] * TotalErr)
                Theta[3 * i:3 * i + 3] = RS[3 * r:3 * r + 3] * AS[r]
            H[9 * c:9 * c + 9] = Sc[9 * c:9 * c + 9].dot(np.linalg.pinv(Theta))

        ################################################################
        #         Forming matrix for Editing
        ################################################################
        B = sp.lil_matrix((3 * Ncl, 2 * NF))
        for c in range(Ncl):
            for f in Cls[c]:
                B[3 * c:3 * c + 3, 2 * f:2 * f +
                  2] = Bt[f] * np.reshape(Vref[:, f], (3, 2), 'F')

        L = (factor((AA[:(NV - 1), :].dot(B.transpose())).tocsc())).transpose()
        np.savetxt(path + Rigname + '_L.txt', L.toarray(), delimiter=',')
        np.savetxt(path + Rigname + '_RRWght.txt', W, delimiter=',')
        np.savetxt(path + Rigname + '_HRWght.txt', H, delimiter=',')
        np.savetxt(path + Rigname + '_JointClsWeights.txt',
                   Wgts,
                   delimiter=',')
        WriteAsTxt(path + Rigname + '_JointClsRl.txt', JntInd)

        return {'FINISHED'}
예제 #16
0
def choleskySolve(M, b):

    factor = cholesky_AAt(M.T)
    return factor(M.T.dot(b)).toarray()
예제 #17
0
def spsolve_chol(sparse_X, dense_b):

    factor = cholesky_AAt(sparse_X.T)
    return factor(sparse_X.T.dot(dense_b)).toarray()
    def solvePoisson(mesh, densityValues):
        """
        Solve a Poisson problem on the mesh. The results should be stored on the
        vertices in a variable named 'solutionVal'. You will want to make use
        of your buildLaplaceMatrix_dense() function from above.

        densityValues is a dictionary mapping {vertex ==> value} that specifies
        densities. The density is implicitly zero at every vertex not in this
        dictionary.

        When you run this program with 'python Assignment3.py part1 path/to/your/mesh.obj',
        you will get to click on vertices to specify density conditions. See the
        assignment document for more details.
        """
        index_map = mesh.enumerateVertices
        L = buildLaplaceMatrix_sparse(mesh, index_map)
        M = buildMassMatrix_dense(mesh, index_map)  #M <= 2D
        totalArea = mesh.totalArea

        rho = np.zeros((len(mesh.verts), 1), float)
        for key in densityValues:
            #index_val = index_map[key]
            print 'key dual area = ', key.barycentricDualArea
            rho[index_map[key]] = densityValues[key]  #*key.dualArea

        nRows, nCols = np.shape(M)
        totalRho = sum(M.dot(rho))
        #rhoBar = np.ones((nRows,1),float)*(totalRho/totalArea)
        rhoBar = totalRho / totalArea
        rhs = M.dot(rhoBar - rho)
        #rhs = np.matmul(M,(rho-rhoBar) )
        #rhs = np.dot(M,rho)
        #
        # SwissArmyLaplacian,
        #   page 179 Cu = Mf is better conditioned
        # assert(Cu == L) ??
        #sol_vec = np.linalg.solve(L, np.dot(M,rho) )

        #sparse:
        #sol_vec = dsolve.spsolve(L, np.dot(M,rho) , use_umfpack=True)
        # standard:
        #sol_vec = dsolve.spsolve(L, rhs , use_umfpack=True)

        #sparse Cholesky solve:
        llt = skchol.cholesky_AAt(L)  #factor
        sol_vec = llt(rhs)

        #eigen:
        #sol_vec = np.zeros((nRows),float)
        #scipy.sparse.linalg.lobpcg(L,sol_vec,rhs) #@eigensolver

        #sol_vec = dsolve.spsolve(L, rho , use_umfpack=True)
        vert_sol = {}
        for vert in mesh.verts:
            key = index_map[vert]
            #print 'TLM sol_vec = ',sol_vec[key]
            vert.solutionVal = sol_vec[key]
            vert_sol[vert] = sol_vec[key]
            if rho[key]:
                vert.densityVal = rho[key]
            else:
                vert.densityVal = 0.

        return vert_sol
예제 #19
0
Lk = sp.random(3, 3, 0.5, format='csc') + sp.eye(3, 3, format='csc')
K = Lk * Lk.T
assert np.allclose(K.toarray(), K.T.toarray(), 1e-10), 'K not symmetric.'
assert all(np.linalg.eigvals(K.toarray()) > 0), 'K is not positive definite.'

# Lumped mass matrix
m = np.array([1, 2, 3])
M = sp.diags(m, format='csc')
assert np.allclose(M.toarray(), M.T.toarray(), 1e-10), 'M not symmetric.'

#
# alpha = 1
#
Q1 = K
f_Q1 = cholesky(K)
fs_Q1 = cholesky_AAt(Lk)

assert factor_of(f_Q1, K), 'Cannot use cholesky factor to reconstruct matrix.'

assert factor_of(fs_Q1, K), 'Cannot use cholesky factor to reconstruct matrix.'

assert np.allclose(f_Q1.L().toarray(),fs_Q1.L().toarray(),1e-10), \
    'Cholesky factors differ'
#
# alpha = 2
#
Q2 = K * spla.inv(M) * K
f_Q2 = cholesky(Q2)
fs_Q2 = cholesky_AAt(K * sp.diags(1 / np.sqrt(m)))

assert factor_of(f_Q2, Q2), 'Cannot use cholesky factor to reconstruct matrix.'
예제 #20
0
def main():
    ######################
    # Config
    ######################

    # Choose least-squares solver to use:
    #
    #    lsq_solver = "dense"  # LAPACK DGELSD, direct, good for small problems
    #    lsq_solver = "sparse"  # SciPy LSQR, iterative, asymptotically faster, good for large problems
    #    lsq_solver = "optimize"  # general nonlinear optimizer using Trust Region Reflective (trf) algorithm
    #    lsq_solver = "qr"
    #    lsq_solver = "cholesky"
    #    lsq_solver = "sparse_qr"
    lsq_solver = "sparse_qr_solve"

    ######################
    # Load multiscale data
    ######################

    print("Loading measurement data...")

    # measurements are provided on a meshgrid over (Hx, sigxx)

    # data2.mat contains virtual measurements, generated from a multiscale model.

    #    data2 = scipy.io.loadmat("data2.mat")
    #    Hx    = np.squeeze(data2["Hx"])     # 1D array, (M,)
    #    sigxx = np.squeeze(data2["sigxx"])  # 1D array, (N,)
    #    Bx    = data2["Bx"]                 # 2D array, (M, N)
    #    lamxx = data2["lamxx"]              #       --"--
    ##    lamyy = data2["lamyy"]              #       --"--
    ##    lamzz = data2["lamzz"]              #       --"--

    data2 = scipy.io.loadmat("umair_gal_denoised.mat")
    sigxx = -1e6 * np.array([
        0, 1, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80
    ][::-1],
                            dtype=np.float64)
    assert sigxx.shape[0] == 18
    Hx = data2["Hval"][0, :]  # same for all sigma, just take the first row
    Bx = data2["Bval"].T
    lamxx = data2["LHval"].T * 1e-6
    Bx = Bx[::-1, :]
    lamxx = lamxx[::-1, :]

    # HACK, fix later (must decouple number of knots from number of data sites)
    ii = np.arange(Hx.shape[0])
    n_newi = 401
    newii = np.linspace(0, ii[-1], n_newi)
    nsigma = sigxx.shape[0]
    fH = scipy.interpolate.interp1d(ii, Hx)
    newB = np.empty((n_newi, Bx.shape[1]), dtype=np.float64)
    newlam = np.empty((n_newi, lamxx.shape[1]), dtype=np.float64)
    for j in range(nsigma):
        fB = scipy.interpolate.interp1d(ii, Bx[:, j])
        newB[:, j] = fB(newii)

        flam = scipy.interpolate.interp1d(ii, lamxx[:, j])
        newlam[:, j] = flam(newii)
    Hx = fH(newii)
    Bx = newB
    lamxx = newlam

    # Order of spline (as-is! 3 = cubic)
    ordr = 3

    # Auxiliary variables (H, sig_xx, sig_xy)
    Hscale = np.max(Hx)
    sscale = np.max(np.abs(sigxx))
    x = Hx / Hscale
    y = sigxx / sscale
    nx = x.shape[0]  # number of grid points, x axis
    ny = y.shape[0]  # number of grid points, y axis

    # Partial derivatives (B, lam_xx, lam_xy) from multiscale model
    #
    # In the magnetostriction components, the multiscale model produces nonzero lamxx at zero stress.
    # We normalize this away for purposes of performing the curve fit.
    #
    dpsi_dx = Bx * Hscale
    dpsi_dy = (lamxx - lamxx[0, :]) * sscale

    ######################
    # Set up splines
    ######################

    print("Setting up splines...")

    # The evaluation algorithm used in bspline.py uses half-open intervals  t_i <= x < t_{i+1}.
    #
    # This causes havoc for evaluation at the end of each interval, because it is actually the start
    # of the next interval.
    #
    # Especially, the end of the last interval is the start of the next (non-existent) interval.
    #
    # We work around this by using a small epsilon to avoid evaluation exactly at t_{i+1} (for the last interval).
    #
    def marginize_end(x):
        out = x.copy()
        out[-1] += 1e-10 * (x[-1] - x[0])
        return out

    # create knots and spline basis
    xknots = splinelab.aptknt(marginize_end(x), ordr)
    yknots = splinelab.aptknt(marginize_end(y), ordr)
    splx = bspline.Bspline(xknots, ordr)
    sply = bspline.Bspline(yknots, ordr)

    # get number of basis functions (perform dummy evaluation and count)
    nxb = len(splx(0.))
    nyb = len(sply(0.))

    # TODO Check if we need to convert input Bx and sigxx to u,v (what is actually stored in the data files?)

    # Create collocation matrices:
    #
    #   A[i,j] = d**deriv_order B_j(tau[i])
    #
    # where d denotes differentiation and B_j is the jth basis function.
    #
    # We place the collocation sites at the points where we have measurements.
    #
    Au = splx.collmat(x)
    Av = sply.collmat(y)
    Du = splx.collmat(x, deriv_order=1)
    Dv = sply.collmat(y, deriv_order=1)

    ######################
    # Assemble system
    ######################

    print("Assembling system...")

    # Assemble the equation system for fitting against data on the partial derivatives of psi.
    #
    # By writing psi in the spline basis,
    #
    #   psi_{ij}       = A^{u}_{ik} A^{v}_{jl} c_{kl}
    #
    # the quantities to be fitted, which are the partial derivatives of psi, become
    #
    #   B_{ij}         = D^{u}_{ik} A^{v}_{jl} c_{kl}
    #   lambda_{xx,ij} = A^{u}_{ik} D^{v}_{jl} c_{kl}
    #
    # Repeated indices are summed over.
    #
    # Column: kl converted to linear index (k = 0,1,...,nxb-1,  l = 0,1,...,nyb-1)
    # Row:    ij converted to linear index (i = 0,1,...,nx-1,   j = 0,1,...,ny-1)
    #
    # (Paavo's notes, Stresses4.pdf)

    nf = 2  # number of unknown fields
    nr = nx * ny  # equation system rows per unknown field
    A = np.empty((nf * nr, nxb * nyb), dtype=np.float64)  # global matrix
    b = np.empty((nf * nr), dtype=np.float64)  # global RHS

    # zero array element detection tolerance
    tol = 1e-6

    I, J, IJ = util.index.genidx((nx, ny))
    K, L, KL = util.index.genidx((nxb, nyb))

    # loop only over rows of the equation system
    for i, j, ij in zip(I, J, IJ):
        A[nf * ij, KL] = Du[i, K] * Av[j, L]
        A[nf * ij + 1, KL] = Au[i, K] * Dv[j, L]

    b[nf * IJ] = dpsi_dx[I, J]  # RHS for B_x
    b[nf * IJ + 1] = dpsi_dy[I, J]  # RHS for lambda_xx

    #    # the above is equivalent to this much slower version:
    #    #
    #    # equation system row
    #    for j in range(ny):
    #        for i in range(nx):
    #            ij = np.ravel_multi_index( (i,j), (nx,ny) )
    #
    #            # equation system column
    #            for l in range(nyb):
    #                for k in range(nxb):
    #                    kl = np.ravel_multi_index( (k,l), (nxb,nyb) )
    #                    A[nf*ij,  kl] = Du[i,k] * Av[j,l]
    #                    A[nf*ij+1,kl] = Au[i,k] * Dv[j,l]
    #
    #            b[nf*ij]   = dpsi_dx[i,j] if abs(dpsi_dx[i,j]) > tol else 0.  # RHS for B_x
    #            b[nf*ij+1] = dpsi_dy[i,j] if abs(dpsi_dy[i,j]) > tol else 0.  # RHS for lambda_xx

    ######################
    # Solve
    ######################

    # Solve the optimal coefficients.

    # Note that we are constructing a potential function from partial derivatives only,
    # so the solution is unique only up to a global additive shift term.
    #
    # Under the hood, numpy.linalg.lstsq uses LAPACK DGELSD:
    #
    #   http://stackoverflow.com/questions/29372559/what-is-the-difference-between-numpy-linalg-lstsq-and-scipy-linalg-lstsq
    #
    # DGELSD accepts also rank-deficient input (rank(A) < min(nrows,ncols)), returning  arg min( ||x||_2 ) ,
    # so we don't need to do anything special to account for this.
    #
    # Same goes for the sparse LSQR.

    # equilibrate row and column norms
    #
    # See documentation of  scipy.sparse.linalg.lsqr,  it requires this to work properly.
    #
    # https://github.com/Technologicat/python-wlsqm
    #
    print("Equilibrating...")
    S = A.copy(order='F')  # the rescaler requires Fortran memory layout
    A = scipy.sparse.csr_matrix(A)  # save memory (dense "A" no longer needed)

    #    eps = 7./3. - 4./3. - 1  # http://stackoverflow.com/questions/19141432/python-numpy-machine-epsilon
    #    print( S.max() * max(S.shape) * eps )  # default zero singular value detection tolerance in np.linalg.matrix_rank()

    #    import wlsqm.utils.lapackdrivers as wul
    #    rs,cs = wul.do_rescale( S, wul.ScalingAlgo.ALGO_DGEEQU )

    #    # row scaling only (for weighting)
    #    with np.errstate(divide='ignore', invalid='ignore'):
    #        rs = np.where( np.abs(b) > tol, 1./b, 1. )
    #    for i in range(S.shape[0]):
    #        S[i,:] *= rs[i]
    #    cs = 1.

    # scale rows corresponding to Bx
    #
    rs = np.ones_like(b)
    rs[nf * IJ] = 2
    for i in range(S.shape[0]):
        S[i, :] *= rs[i]
    cs = 1.

    #    # It seems this is not needed in the 2D problem (fitting error is slightly smaller without it).
    #
    #    # Additional row scaling.
    #    #
    #    # This equilibrates equation weights, but deteriorates the condition number of the matrix.
    #    #
    #    # Note that in a least-squares problem the row weighting *does* matter, because it affects
    #    # the fitting error contribution from the rows.
    #    #
    #    with np.errstate(divide='ignore', invalid='ignore'):
    #        rs2 = np.where( np.abs(b) > tol, 1./b, 1. )
    #    for i in range(S.shape[0]):
    #        S[i,:] *= rs2[i]
    #    rs *= rs2

    #    a = np.abs(rs2)
    #    print( np.min(a), np.mean(a), np.max(a) )

    #    rs = np.asanyarray(rs)
    #    cs = np.asanyarray(cs)
    #    a = np.abs(rs)
    #    print( np.min(a), np.mean(a), np.max(a) )

    b *= rs  # scale RHS accordingly

    #    colnorms = np.linalg.norm(S, ord=np.inf, axis=0)  # sum over rows    -> column norms
    #    rownorms = np.linalg.norm(S, ord=np.inf, axis=1)  # sum over columns -> row    norms
    #    print( "    rescaled column norms min = %g, avg = %g, max = %g" % (np.min(colnorms), np.mean(colnorms), np.max(colnorms)) )
    #    print( "    rescaled row    norms min = %g, avg = %g, max = %g" % (np.min(rownorms), np.mean(rownorms), np.max(rownorms)) )

    print("Solving with algorithm = '%s'..." % (lsq_solver))
    if lsq_solver == "dense":
        print("    matrix shape %s = %d elements" %
              (S.shape, np.prod(S.shape)))
        ret = numpy.linalg.lstsq(S, b)  # c,residuals,rank,singvals
        c = ret[0]

    elif lsq_solver == "sparse":
        S = scipy.sparse.coo_matrix(S)
        print("    matrix shape %s = %d elements; %d nonzeros (%g%%)" %
              (S.shape, np.prod(
                  S.shape), S.nnz, 100. * S.nnz / np.prod(S.shape)))

        ret = scipy.sparse.linalg.lsqr(S, b)
        c, exit_reason, iters = ret[:3]
        if exit_reason != 2:  # 2 = least-squares solution found
            print("WARNING: solver did not converge (exit_reason = %d)" %
                  (exit_reason))
        print("    sparse solver iterations taken: %d" % (iters))

    elif lsq_solver == "optimize":
        # make sparse matrix (faster for dot products)
        S = scipy.sparse.coo_matrix(S)
        print("    matrix shape %s = %d elements; %d nonzeros (%g%%)" %
              (S.shape, np.prod(
                  S.shape), S.nnz, 100. * S.nnz / np.prod(S.shape)))

        def fitting_error(c):
            return S.dot(c) - b

        ret = scipy.optimize.least_squares(fitting_error,
                                           np.ones(S.shape[1],
                                                   dtype=np.float64),
                                           method="trf",
                                           loss="linear")

        c = ret.x
        if ret.status < 1:
            # status codes: https://docs.scipy.org/doc/scipy-0.18.1/reference/generated/scipy.optimize.least_squares.html
            print("WARNING: solver did not converge (status = %d)" %
                  (ret.status))

    elif lsq_solver == "qr":
        print("    matrix shape %s = %d elements" %
              (S.shape, np.prod(S.shape)))
        # http://glowingpython.blogspot.fi/2012/03/solving-overdetermined-systems-with-qr.html
        Q, R = np.linalg.qr(S)  # qr decomposition of A
        Qb = (Q.T).dot(b)  # computing Q^T*b (project b onto the range of A)
        #        c = np.linalg.solve(R,Qb) # solving R*x = Q^T*b
        c = scipy.linalg.solve_triangular(R, Qb, check_finite=False)

    elif lsq_solver == "cholesky":
        # S is rank-deficient by one, because we are solving a potential based on data on its partial derivatives.
        #
        # Before solving, force S to have full rank by fixing one coefficient.
        #
        S[0, :] = 0.
        S[0, 0] = 1.
        b[0] = 1.
        rs[0] = 1.
        S = scipy.sparse.csr_matrix(S)
        print("    matrix shape %s = %d elements; %d nonzeros (%g%%)" %
              (S.shape, np.prod(
                  S.shape), S.nnz, 100. * S.nnz / np.prod(S.shape)))

        # Be sure to use the new sksparse from
        #
        #   https://github.com/scikit-sparse/scikit-sparse
        #
        # instead of the old scikits.sparse (which will fail with an error).
        #
        # Requires libsuitesparse-dev for CHOLMOD headers.
        #
        from sksparse.cholmod import cholesky_AAt
        # Notice that CHOLMOD computes AA' and we want M'M, so we must set A = M'!
        factor = cholesky_AAt(S.T)
        c = factor.solve_A(S.T * b)

    elif lsq_solver == "sparse_qr":
        # S is rank-deficient by one, because we are solving a potential based on data on its partial derivatives.
        #
        # Before solving, force S to have full rank by fixing one coefficient;
        # otherwise the linear solve step will fail because R will be exactly singular.
        #
        S[0, :] = 0.
        S[0, 0] = 1.
        b[0] = 1.
        rs[0] = 1.
        S = scipy.sparse.coo_matrix(S)
        print("    matrix shape %s = %d elements; %d nonzeros (%g%%)" %
              (S.shape, np.prod(
                  S.shape), S.nnz, 100. * S.nnz / np.prod(S.shape)))

        # pip install sparseqr
        # or https://github.com/yig/PySPQR
        #
        # Works like MATLAB's [Q,R,e] = qr(...):
        #
        # https://se.mathworks.com/help/matlab/ref/qr.html
        #
        # [Q,R,E] = qr(A) or [Q,R,E] = qr(A,'matrix') produces unitary Q, upper triangular R and a permutation matrix E
        # so that A*E = Q*R. The column permutation E is chosen to reduce fill-in in R.
        #
        # [Q,R,e] = qr(A,'vector') returns the permutation information as a vector instead of a matrix.
        # That is, e is a row vector such that A(:,e) = Q*R.
        #
        import sparseqr
        print("    performing sparse QR decomposition...")
        Q, R, E, rank = sparseqr.qr(S)

        # produce reduced QR (for least-squares fitting)
        #
        # - cut away bottom part of R (zeros!)
        # - cut away the corresponding far-right part of Q
        #
        # see
        #    np.linalg.qr
        #    https://andreask.cs.illinois.edu/cs357-s15/public/demos/06-qr-applications/Solving%20Least-Squares%20Problems.html
        #
        #        # inefficient way:
        #        k = min(S.shape)
        #        R = scipy.sparse.csr_matrix( R.A[:k,:] )
        #        Q = scipy.sparse.csr_matrix( Q.A[:,:k] )

        print("    reducing matrices...")
        # somewhat more efficient way:
        k = min(S.shape)
        R = R.tocsr()[:k, :]
        Q = Q.tocsc()[:, :k]

        #        # maybe somewhat efficient way: manipulate data vectors, create new coo matrix
        #        #
        #        # (incomplete, needs work; need to shift indices of rows/cols after the removed ones)
        #        #
        #        k    = min(S.shape)
        #        mask = np.nonzero( R.row < k )[0]
        #        R = scipy.sparse.coo_matrix( ( R.data[mask], (R.row[mask], R.col[mask]) ), shape=(k,k) )
        #        mask = np.nonzero( Q.col < k )[0]
        #        Q = scipy.sparse.coo_matrix( ( Q.data[mask], (Q.row[mask], Q.col[mask]) ), shape=(k,k) )

        print("    solving...")
        Qb = (Q.T).dot(b)
        x = scipy.sparse.linalg.spsolve(R, Qb)
        c = np.empty_like(x)
        c[E] = x[:]  # apply inverse permutation

    elif lsq_solver == "sparse_qr_solve":
        S[0, :] = 0.
        S[0, 0] = 1.
        b[0] = 1.
        rs[0] = 1.
        S = scipy.sparse.coo_matrix(S)
        print("    matrix shape %s = %d elements; %d nonzeros (%g%%)" %
              (S.shape, np.prod(
                  S.shape), S.nnz, 100. * S.nnz / np.prod(S.shape)))

        import sparseqr
        c = sparseqr.solve(S, b)

    else:
        raise ValueError("unknown solver '%s'; valid: 'dense', 'sparse'" %
                         (lsq_solver))

    c *= cs  # undo column scaling in solution

    # now c contains the spline coefficients, c_{kl}, where kl has been raveled into a linear index.

    ######################
    # Save
    ######################

    filename = "tmp_s2d.mat"
    L = locals()
    data = {
        key: L[key]
        for key in ["ordr", "xknots", "yknots", "c", "Hscale", "sscale"]
    }
    scipy.io.savemat(filename, data, format='5', oned_as='row')

    ######################
    # Plot
    ######################

    print("Visualizing...")

    # unpack results onto meshgrid
    #
    fitted = A.dot(
        c
    )  # function values corresponding to each row in the global equation system
    X, Y = np.meshgrid(
        Hx, sigxx,
        indexing='ij')  # indexed like X[i,j]  (i is x index, j is y index)
    Z_Bx = np.empty_like(X)
    Z_lamxx = np.empty_like(X)

    Z_Bx[I, J] = fitted[nf * IJ]
    Z_lamxx[I, J] = fitted[nf * IJ + 1]

    #    # the above is equivalent to:
    #    for ij in range(nr):
    #        i,j = np.unravel_index( ij, (nx,ny) )
    #        Z_Bx[i,j]    = fitted[nf*ij]
    #        Z_lamxx[i,j] = fitted[nf*ij+1]

    data_Bx = {
        "x": (X, r"$H_{x}$"),
        "y": (Y, r"$\sigma_{xx}$"),
        "z": (Z_Bx / Hscale, r"$B_{x}$")
    }

    data_lamxx = {
        "x": (X, r"$H_{x}$"),
        "y": (Y, r"$\sigma_{xx}$"),
        "z": (Z_lamxx / sscale, r"$\lambda_{xx}$")
    }

    def relerr(data, refdata):
        refdata_linview = refdata.reshape(-1)
        return 100. * np.linalg.norm(refdata_linview - data.reshape(-1)
                                     ) / np.linalg.norm(refdata_linview)

    plt.figure(1)
    plt.clf()
    ax = util.plot.plot_wireframe(data_Bx, legend_label="Spline", figno=1)
    ax.plot_wireframe(X, Y, dpsi_dx / Hscale, label="Multiscale", color="r")
    plt.legend(loc="best")
    print("B_x relative error %g%%" % (relerr(Z_Bx, dpsi_dx)))

    plt.figure(2)
    plt.clf()
    ax = util.plot.plot_wireframe(data_lamxx, legend_label="Spline", figno=2)
    ax.plot_wireframe(X, Y, dpsi_dy / sscale, label="Multiscale", color="r")
    plt.legend(loc="best")
    print("lambda_{xx} relative error %g%%" % (relerr(Z_lamxx, dpsi_dy)))

    # match the grid point numbering used in MATLAB version of this script
    #
    def t(A):
        return np.transpose(A, [1, 0])

    dpsi_dx = t(dpsi_dx)
    Z_Bx = t(Z_Bx)
    dpsi_dy = t(dpsi_dy)
    Z_lamxx = t(Z_lamxx)

    plt.figure(3)
    plt.clf()
    ax = plt.subplot(1, 1, 1)
    ax.plot(dpsi_dx.reshape(-1) / Hscale,
            'ro',
            markersize='2',
            label="Multiscale")
    ax.plot(Z_Bx.reshape(-1) / Hscale, 'ko', markersize='2', label="Spline")
    ax.set_xlabel("Grid point number")
    ax.set_ylabel(r"$B_{x}$")
    plt.legend(loc="best")

    plt.figure(4)
    plt.clf()
    ax = plt.subplot(1, 1, 1)
    ax.plot(dpsi_dy.reshape(-1) / sscale,
            'ro',
            markersize='2',
            label="Multiscale")
    ax.plot(Z_lamxx.reshape(-1) / sscale, 'ko', markersize='2', label="Spline")
    ax.set_xlabel("Grid point number")
    ax.set_ylabel(r"$\lambda_{xx}$")
    plt.legend(loc="best")

    print("All done.")
예제 #21
0
def projections(A, method=None, orth_tol=1e-12, max_refin=3):
    """Return three linear operators related with a given matrix A.

    Parameters
    ----------
    A : sparse matrix (or ndarray), shape (m, n)
        Matrix ``A`` used in the projection.
    method : string, optional
        Method used for compute the given linear
        operators. Should be one of:

            - 'NormalEquation': The operators
               will be computed using the
               so-called normal equation approach
               explained in [1]_. In order to do
               so the Cholesky factorization of
               ``(A A.T)`` is computed. Exclusive
               for sparse matrices.
            - 'AugmentedSystem': The operators
               will be computed using the
               so-called augmented system approach
               explained in [1]_. Exclusive
               for sparse matrices.
            - 'QRFactorization': Compute projections
               using QR factorization. Exclusive for
               dense matrices.

    orth_tol : float, optional
        Tolerance for iterative refinements.
    max_refin : int, optional
        Maximum number of iterative refinements

    Returns
    -------
    Z : LinearOperator, shape (n, n)
        Null-space operator. For a given vector ``x``,
        the null space operator is equivalent to apply
        a projection matrix ``P = I - A.T inv(A A.T) A``
        to the vector. It can be shown that this is
        equivalent to project ``x`` into the null space
        of A.
    LS : LinearOperator, shape (m, n)
        Least-Square operator. For a given vector ``x``,
        the least-square operator is equivalent to apply a
        pseudoinverse matrix ``pinv(A.T) = inv(A A.T) A``
        to the vector. It can be shown that this vector
        ``pinv(A.T) x`` is the least_square solution to
        ``A.T y = x``.
    Y : LinearOperator, shape (n, m)
        Row-space operator. For a given vector ``x``,
        the row-space operator is equivalent to apply a
        projection matrix ``Q = A.T inv(A A.T)``
        to the vector.  It can be shown that this
        vector ``y = Q x``  the minimum norm solution
        of ``A y = x``.

    Notes
    -----
    Uses iterative refinements described in [1]
    during the computation of ``Z`` in order to
    cope with the possibility of large roundoff errors.

    References
    ----------
    .. [1] Gould, Nicholas IM, Mary E. Hribar, and Jorge Nocedal.
        "On the solution of equality constrained quadratic
        programming problems arising in optimization."
        SIAM Journal on Scientific Computing 23.4 (2001): 1376-1395.
    """
    m, n = np.shape(A)

    # Check Argument
    if issparse(A):
        if method is None:
            method = "AugmentedSystem"

        if method not in ("NormalEquation", "AugmentedSystem"):
            raise ValueError("Method not allowed for the given matrix.")

    else:
        if method is None:
            method = "QRFactorization"

        if method != "QRFactorization":
            raise ValueError("Method not allowed for the given matrix.")

    if method == 'NormalEquation':
        # Cholesky factorization
        factor = cholesky_AAt(A)

        # z = x - A.T inv(A A.T) A x
        def null_space(x):
            v = factor(A.dot(x))
            z = x - A.T.dot(v)

            # Iterative refinement to improve roundoff
            # errors described in [2]_, algorithm 5.1.
            k = 0
            while orthogonality(A, z) > orth_tol:
                if k >= max_refin:
                    break
                # z_next = z - A.T inv(A A.T) A z
                v = factor(A.dot(z))
                z = z - A.T.dot(v)
                k += 1

            return z

        # z = inv(A A.T) A x
        def least_squares(x):
            return factor(A.dot(x))

        # z = A.T inv(A A.T) x
        def row_space(x):
            return A.T.dot(factor(x))

    elif method == 'AugmentedSystem':
        # Form augmented system
        K = csc_matrix(bmat([[eye(n), A.T], [A, None]]))
        # LU factorization
        # TODO: Use a symmetric indefinite factorization
        #       to solve the system twice as fast (because
        #       of the symmetry).
        factor = linalg.splu(K)

        # z = x - A.T inv(A A.T) A x
        # is computed solving the extended system:
        # [I A.T] * [ z ] = [x]
        # [A  O ]   [aux]   [0]
        def null_space(x):
            # v = [x]
            #     [0]
            v = np.hstack([x, np.zeros(m)])
            # lu_sol = [ z ]
            #          [aux]
            lu_sol = factor.solve(v)
            z = lu_sol[:n]

            # Iterative refinement to improve roundoff
            # errors described in [2]_, algorithm 5.2.
            k = 0
            while orthogonality(A, z) > orth_tol:
                if k >= max_refin:
                    break
                # new_v = [x] - [I A.T] * [ z ]
                #         [0]   [A  O ]   [aux]
                new_v = v - K.dot(lu_sol)
                # [I A.T] * [delta  z ] = new_v
                # [A  O ]   [delta aux]
                lu_update = factor.solve(new_v)
                #  [ z ] += [delta  z ]
                #  [aux]    [delta aux]
                lu_sol += lu_update
                z = lu_sol[:n]
                k += 1

            # return z = x - A.T inv(A A.T) A x
            return z

        # z = inv(A A.T) A x
        # is computed solving the extended system:
        # [I A.T] * [aux] = [x]
        # [A  O ]   [ z ]   [0]
        def least_squares(x):
            # v = [x]
            #     [0]
            v = np.hstack([x, np.zeros(m)])
            # lu_sol = [aux]
            #          [ z ]
            lu_sol = factor.solve(v)
            # return z = inv(A A.T) A x
            return lu_sol[n:m + n]

        # z = A.T inv(A A.T) x
        # is computed solving the extended system:
        # [I A.T] * [ z ] = [0]
        # [A  O ]   [aux]   [x]
        def row_space(x):
            # v = [0]
            #     [x]
            v = np.hstack([np.zeros(n), x])
            # lu_sol = [ z ]
            #          [aux]
            lu_sol = factor.solve(v)
            # return z = A.T inv(A A.T) x
            return lu_sol[:n]

    elif method == "QRFactorization":
        # QRFactorization
        Q, R, P = scipy.linalg.qr(A.T, pivoting=True, mode='economic')

        # z = x - A.T inv(A A.T) A x
        def null_space(x):
            # v = P inv(R) Q.T x
            aux1 = Q.T.dot(x)
            aux2 = scipy.linalg.solve_triangular(R, aux1, lower=False)
            v = np.zeros(m)
            v[P] = aux2
            z = x - A.T.dot(v)

            # Iterative refinement to improve roundoff
            # errors described in [2]_, algorithm 5.1.
            k = 0
            while orthogonality(A, z) > orth_tol:
                if k >= max_refin:
                    break
                # v = P inv(R) Q.T x
                aux1 = Q.T.dot(z)
                aux2 = scipy.linalg.solve_triangular(R, aux1, lower=False)
                v[P] = aux2
                # z_next = z - A.T v
                z = z - A.T.dot(v)
                k += 1

            return z

        # z = inv(A A.T) A x
        def least_squares(x):
            # z = P inv(R) Q.T x
            aux1 = Q.T.dot(x)
            aux2 = scipy.linalg.solve_triangular(R, aux1, lower=False)
            z = np.zeros(m)
            z[P] = aux2
            return z

        # z = A.T inv(A A.T) x
        def row_space(x):
            # z = Q inv(R.T) P.T x
            aux1 = x[P]
            aux2 = scipy.linalg.solve_triangular(R,
                                                 aux1,
                                                 lower=False,
                                                 trans='T')
            z = Q.dot(aux2)
            return z

    Z = LinearOperator((n, n), null_space)
    LS = LinearOperator((m, n), least_squares)
    Y = LinearOperator((n, m), row_space)

    return Z, LS, Y
예제 #22
0
    def execute(self, context):
        global Phi, path,FilePath
        ################# Input from user ###############
        Rigname=context.scene.RigName
        if path[len(path)-len(Rigname)-1:len(path)-1]!=Rigname:
            path=FilePath+Rigname+'/' 
        num_JntPrVec=context.scene.JointPrVec
        FrmPrBn=context.scene.FrmPrBone
        ################################################
        Vrt=np.loadtxt(path+Rigname+'_vertz.txt',delimiter=',')
        Fcs=ReadTxt(path+Rigname+'_Halffacz.txt')
        Nrml=np.loadtxt(path+Rigname+'_Normal.txt',delimiter=',')
        Joints=ReadTxt(path+Rigname+'_Joints.txt')
        Links=ReadTxt(path+Rigname+'_SkelEdgz.txt')
        
        NPs,NV=np.shape(Vrt)
        NPs=NPs//3
        NVec=sum([len(f) for f in Fcs])
        
        CnsVrt=ReadTxt(path+Rigname+'_LBSVrt.txt')[0]
        FrVrt=[]
        for i in range(NV):
            if i not in CnsVrt: 
                FrVrt.append(i)
        WriteAsTxt(path+Rigname+'_FrVrt.txt',FrVrt)
        np.savetxt(path+Rigname+'_RefMesh.txt',Vrt[0:3,:].T,delimiter=',')       
        ########################## Commpute Incident Matrices ###########################################
        print("Computing Incident Matrices.....")
        strtTime=time.time()
        AB,ABc=ConnectionMatrices(Fcs,NV,NVec,CnsVrt,FrVrt)
        Vecs=((AB.transpose()).dot(Vrt[:,FrVrt].T)).T+((ABc.transpose()).dot(Vrt[:,CnsVrt].T)).T
        factor=chmd.cholesky_AAt(AB.tocsc())
        
        ########################## Comute Skeleton Frames ########################################### 
        
        
        VecIndx=[]
        for ln in Links:
            if FrmPrBn==1:
                VecIndx.append(ln)
            else:
                VecIndx.append(ln)
                VecIndx.append([ln[1],ln[0]])
         
        print("Computing Skeleton Frames.....")
        NJ=len(Joints)
          
        
        NFrm=len(VecIndx)
        SFrm=np.zeros([3,3])
        SrFrm=np.zeros([3,4*NFrm])

        SFrmLbs=np.eye(4)
        SrFrmLbs=np.zeros([4,4*NFrm])
        RSLbs=np.zeros((3*(NPs-1),4*NFrm))
        
        A=np.zeros([NJ,3])
        RS=np.zeros((3*(NPs-1),3*NFrm))
        
        for ps in range(NPs):
            
            X=Vrt[3*ps:3*ps+3,:].T
            for r in range(NJ):
                A[r]=np.mean(X[Joints[r]],axis=0)
                  
            if ps==0:
                np.savetxt(path+Rigname+'_RefSkel.txt',A,delimiter=',')
            
            t=0
            for r in range(NFrm):
                
                V=(A[VecIndx[r][0]]-A[VecIndx[r][1]])/np.linalg.norm(A[VecIndx[r][0]]-A[VecIndx[r][1]])
                
                tmp=X[Joints[VecIndx[r][0]][0]]-A[VecIndx[r][0]]
                B=np.cross(V,tmp)/np.linalg.norm(np.cross(V,tmp))
                N=np.cross(B,V)/np.linalg.norm(np.cross(B,V))

                SFrm[:,0]=V
                SFrm[:,1]=B
                SFrm[:,2]=N
                SFrmLbs[0:3,0]=V
                SFrmLbs[0:3,1]=B
                SFrmLbs[0:3,2]=N
                SFrmLbs[0:3,3]=A[VecIndx[r][0]]
                if ps!=0:
                    RS[3*(ps-1):3*(ps-1)+3,3*r:3*r+3]=np.dot(SFrm,SrFrm[:,4*r:4*r+3].T)
                    RSLbs[3*(ps-1):3*(ps-1)+3,4*r:4*r+4]=SFrmLbs[0:3,:].dot(np.linalg.inv(SrFrmLbs[:,4*r:4*r+4]))
                else:
                    SrFrm[:,4*r:4*r+3]=SFrm
                    SrFrm[:,4*r+3]=A[VecIndx[r][0]]
                    SrFrmLbs[:,4*r:4*r+4]=SFrmLbs
        np.savetxt(path+Rigname+'_RefFrames.txt',SrFrm,delimiter=',')
        ############################## LBS on Constrain Vertices ##########################################

        print("Computing Mesh Frames for Constraint vertices .....")
        LBSPhi=np.zeros((4*NFrm,len(CnsVrt)))
        Vn=0
        for v in CnsVrt:
            v0=np.append(Vrt[0:3,v],[1])
            Err=[]
            H=np.zeros((3*(NPs-1),NFrm))
            for f in range(NFrm):
                for p in range(NPs-1):
                    H[3*p:3*p+3,f]=RSLbs[3*p:3*p+3,4*f:4*f+4].dot(v0)
                Err.append(np.linalg.norm(Vrt[3:,v]-H[:,f]))
    
            num_JntPrVrt=3
            IndSort=np.argsort(Err)
            SmlH=H[:,IndSort[0:num_JntPrVrt]]
            wghts=np.linalg.inv(np.dot(SmlH.T,SmlH)).dot(np.dot(SmlH.T,Vrt[3:,v]))
            #print(wghts)
            for i in range(num_JntPrVrt):
                if wghts[i]<0.0:
                    wghts[i]=0.0
            wghts=wghts/np.sum(wghts)
            
            for i in range(num_JntPrVrt):
                r=IndSort[i]
                Xr=SrFrmLbs[:,4*r:4*r+4]
                LBSPhi[4*r:4*r+4,Vn]=wghts[i]*(np.linalg.inv(Xr).dot(v0))
            Vn+=1

        del Vrt, Fcs,A,H
        
        ########################## Compute Mesh Frames ########################################### 
        print("Computing Mesh Frames.....")
        RM=np.zeros((3*(NPs-1),3))
        W=sp.lil_matrix((4*NFrm,NVec))
        Wtmp=np.zeros([3,3*NFrm])
        
        t=0
        MRFrm=np.zeros((3,3))
        MFrm=np.zeros((3,3))

        WghtMtrx=np.zeros((3*(NPs-1),num_JntPrVec))
        for vc in range(NVec):
            Err=[]
            MRFrm[:,2]=Nrml[3*vc:3*vc+3,0]    
            MRFrm[:,0]=Vecs[0:3,vc]
            MRFrm[:,1]=np.cross(MRFrm[:,0],MRFrm[:,2])
            MRFrm=MRFrm/np.linalg.norm(MRFrm,axis=0)
            
            
            for ps in range(1,NPs):
                 
                MFrm[:,2]=Nrml[3*vc:3*vc+3,ps]
                MFrm[:,0]=Vecs[3*ps:3*ps+3,vc]
                MFrm[:,1]=np.cross(MFrm[:,0],MFrm[:,2])
                MFrm=MFrm/np.linalg.norm(MFrm,axis=0)
                RM[3*(ps-1):3*(ps-1)+3]=MFrm.dot(MRFrm.T)
                
              
            for r in range(NFrm):
                U,Lmda,V=np.linalg.svd((RM.T).dot(RS[:,3*r:3*r+3]))
                Wtmp[:,3*r:3*r+3]=(V.T).dot(U.T)
                tmp=(RS[:,3*r:3*r+3].dot(Wtmp[:,3*r:3*r+3]))-RM
                Err.append(np.linalg.norm(tmp))
                
            IndSort=np.argsort(Err)
            TotalErr=sum([(1/Err[i]) for i in IndSort[0:num_JntPrVec]])
            
            for ps in range(NPs-1):
                for i in range(num_JntPrVec):
                    r=IndSort[i]
                    WghtMtrx[3*ps:3*ps+3,i]=(RS[3*ps:3*ps+3,3*r:3*r+3].dot(Wtmp[:,3*r:3*r+3])).dot(Vecs[0:3,vc])
            wghts=ComputeWeights(WghtMtrx,Vecs[3:,vc])        
            for i in range(num_JntPrVec):
                r=IndSort[i]             
                tmp=wghts[i]*((SrFrm[:,4*r:4*r+3].T).dot(Wtmp[:,3*r:3*r+3]))
                W[4*r:4*r+3,vc]=np.reshape(tmp.dot(Vecs[0:3,vc]),(3,1))
                
        print("Computing Matrix.....")
        
        del RM, RS, SrFrm, Vecs, Nrml
        
        ##### New
        Phi=(factor((AB.dot(W.transpose())).tocsc())).transpose()
        K=(factor((AB.dot(ABc.transpose())).tocsc())).transpose()
        print(time.time()-strtTime)
        del W
        tmp=Phi.toarray()-LBSPhi.dot(K.toarray())
        Phi=np.zeros((4*NFrm,NV))
        t=0
        for i in range(NV):
            if i in CnsVrt:
                Phi[:,i]=LBSPhi[:,t]
                t+=1
            else:
                Phi[:,i]=tmp[:,FrVrt.index(i)]
        np.savetxt(path+Rigname+'_PhiSingle.txt',Phi,delimiter=',')
        
        return{'FINISHED'}
예제 #23
0
def test_cholesky_matrix_market():
    for problem in ("well1033", "illc1033", "well1850", "illc1850"):
        X = mm_matrix(problem)
        y = mm_matrix(problem + "_rhs1")
        answer = np.linalg.lstsq(X.todense(), y)[0]
        XtX = (X.T * X).tocsc()
        Xty = X.T * y
        for mode in ("auto", "simplicial", "supernodal"):
            assert_allclose(cholesky(XtX, mode=mode)(Xty), answer)
            assert_allclose(cholesky_AAt(X.T, mode=mode)(Xty), answer)
            assert_allclose(cholesky(XtX, mode=mode).solve_A(Xty), answer)
            assert_allclose(cholesky_AAt(X.T, mode=mode).solve_A(Xty), answer)

            f1 = analyze(XtX, mode=mode)
            f2 = f1.cholesky(XtX)
            assert_allclose(f2(Xty), answer)
            assert_raises(CholmodError, f1, Xty)
            assert_raises(CholmodError, f1.solve_A, Xty)
            assert_raises(CholmodError, f1.solve_LDLt, Xty)
            assert_raises(CholmodError, f1.solve_LD, Xty)
            assert_raises(CholmodError, f1.solve_DLt, Xty)
            assert_raises(CholmodError, f1.solve_L, Xty)
            assert_raises(CholmodError, f1.solve_D, Xty)
            assert_raises(CholmodError, f1.apply_P, Xty)
            assert_raises(CholmodError, f1.apply_Pt, Xty)
            f1.P()
            assert_raises(CholmodError, f1.L)
            assert_raises(CholmodError, f1.LD)
            assert_raises(CholmodError, f1.L_D)
            assert_raises(CholmodError, f1.L_D)
            f1.cholesky_inplace(XtX)
            assert_allclose(f1(Xty), answer)

            f3 = analyze_AAt(X.T, mode=mode)
            f4 = f3.cholesky(XtX)
            assert_allclose(f4(Xty), answer)
            assert_raises(CholmodError, f3, Xty)
            f3.cholesky_AAt_inplace(X.T)
            assert_allclose(f3(Xty), answer)

            print(problem, mode)
            for f in (f1, f2, f3, f4):
                pXtX = XtX.todense()[f.P()[:, np.newaxis],
                                     f.P()[np.newaxis, :]]
                assert_allclose(np.prod(f.D()),
                                np.linalg.det(XtX.todense()))
                assert_allclose((f.L() * f.L().T).todense(),
                                pXtX)
                L, D = f.L_D()
                assert_allclose((L * D * L.T).todense(),
                                pXtX)

                b = np.arange(XtX.shape[0])[:, np.newaxis]
                assert_allclose(f.solve_A(b),
                                np.dot(XtX.todense().I, b))
                assert_allclose(f(b),
                                np.dot(XtX.todense().I, b))
                assert_allclose(f.solve_LDLt(b),
                                np.dot((L * D * L.T).todense().I, b))
                assert_allclose(f.solve_LD(b),
                                np.dot((L * D).todense().I, b))
                assert_allclose(f.solve_DLt(b),
                                np.dot((D * L.T).todense().I, b))
                assert_allclose(f.solve_L(b),
                                np.dot(L.todense().I, b))
                assert_allclose(f.solve_Lt(b),
                                np.dot(L.T.todense().I, b))
                assert_allclose(f.solve_D(b),
                                np.dot(D.todense().I, b))

                assert_allclose(f.apply_P(b), b[f.P(), :])
                assert_allclose(f.apply_P(b), b[f.P(), :])
                # Pt is the inverse of P, and argsort inverts permutation
                # vectors:
                assert_allclose(f.apply_Pt(b), b[np.argsort(f.P()), :])
                assert_allclose(f.apply_Pt(b), b[np.argsort(f.P()), :])