//--------------------------------------------------------- int CS_Chol::chol(CSd& A, int order, double dummy) //--------------------------------------------------------- { // Perform Cholesky factorization using // appropriate AMD re-ordering mode: //--------------------------------------- // 0: natural: C = A (no reordering) // 1: Chol : C = A+A' // 2: LU : C = A'*A (drop dense rows) // 3: QR : C = A'*A // 4: Chol#2 : C = A (A is symmetric) //--------------------------------------- // clear existing system if (S) { delete S; S = NULL; } if (N) { delete N; N = NULL; } // check matrix input if (!A.ok()) {umERROR("CS_Chol::chol", "empty matrix"); return 0;} if (!A.is_csc()) {umERROR("CS_Chol::chol", "expected csc form"); return 0;} if (!A.is_square()) {umERROR("CS_Chol::chol", "matrix must be square"); return 0;} umLOG(1, "\nCS_Chol:chol -- starting symbolic phase\n"); try { // ordering and symbolic analysis S = CS_schol(order, A); if (!S) { umERROR("CS_Chol::chol", "error building symbolic info"); return -1;} } catch(...) { umERROR("CS_Chol:chol", "exception in symbolic phase"); return -1; } umLOG(1, "CS_Chol:chol -- symbolic phase complete\n"); umLOG(1, "CS_Chol:chol -- size of full Cholesky L = %1.0lf\n\n", S->lnz); try { // numeric Cholesky factorization N = CS_chol(A, S, true); // take ownership of A's data if (!N) { umERROR("CS_Chol::chol", "error building numeric data"); return -2;} } catch(...) { umERROR("CS_Chol:chol", "exception in numeric phase"); return -2; } return 1; }
//--------------------------------------------------------- int CS_LU::lu(const CSd& A, int order, double tol) //--------------------------------------------------------- { // Perform LU factorization using // appropriate AMD re-ordering mode: //--------------------------------------- // 0: natural: C = A (no reordering) // 1: Chol : C = A+A' // 2: LU : C = A'*A (drop dense rows) // 3: QR : C = A'*A // 4: Chol#2 : C = A (A is symmetric) //--------------------------------------- // clear existing system if (S) { delete S; S = NULL; } if (N) { delete N; N = NULL; } // check matrix input if (!A.ok()) {umERROR("CS_LU::lu", "empty matrix"); return 0;} if (!A.is_csc()) {umERROR("CS_LU::lu", "expected csc form"); return 0;} if (!A.is_square()) {umERROR("CS_LU::lu", "matrix must be square"); return 0;} try { // ordering and symbolic analysis S = CS_sqr(order, A, 0); if (!S) { umERROR("CS_LU::lu", "error building symbolic info"); return -1;} } catch(...) { umERROR("CS_LU::lu", "exception in symbolic phase"); return -1; } try { // numeric LU factorization N = CS_lu(A, S, tol); if (!N) { umERROR("CS_LU::lu", "error building numeric data"); return -2;} } catch(...) { umERROR("CS_LU::lu", "exception in numeric phase"); return -2; } return 1; }
//--------------------------------------------------------- int CS_PCG::cholinc(CSd &sp, double droptol) //--------------------------------------------------------- { m_droptol = droptol; // take ownership of input matrix this->A.own(sp); #if (OUT_TO_MATLAB) { FILE* fp=fopen("z_A1.dat", "w"); A.write_ML(fp); fclose(fp); } #endif // check system if (!A.ok()) { umERROR("CS_PCG::cholinc", "empty coefficient matrix."); } if (!A.is_square()) { umERROR("CS_PCG::cholinc", "Matrix must be square."); } // new factorization: invalidate previous factor and solution m_oldsol = false; m_factor = false; // 1. find fill-reducing ordering // 2. permute system (tril(A)) // 3. build incomplete Cholesky preconditioner stopwatch timer; timer.start(); double t1=0.0,t2=0.0; if (1) { int n = A.n, modified_flag = 0; //double unit = (n-1.)+n; double unit = A.P[n]; umLOG(1, "\n -----------------------------------------------\n"); umLOG(1, " ==> CS_PCG fac: incomplete Cholesky factorization\n"); #if (APPLY_PERM) //----------------------------------- // 1. find fill-reducing ordering //----------------------------------- t1=timer.read(); CS_symamd(A,perm,pinv); t2=timer.read(); if (!perm.ok()) { umERROR("CS_PCG::cholinc", "symamd failed\n"); return -1; } else { umLOG(1, "\tOrdering time = %10.3lf seconds\n", t2-t1); } #endif #if (APPLY_PERM) //----------------------------------- // 2. permute system (tril(A)) //----------------------------------- // FIXME: transpose // CS_symperm expects triu(A) // CS_symamd returns tril(A) #if (1) umLOG(1, "\ttransposing A before symperm... "); t1 = timer.read(); A.transpose(1); umLOG(1, "(%.3lf secs)\n",timer.read()-t1); #endif // uses inverse permutation //PAPT = taucs_dccs_permute_symmetrically(A, pinv.data()); t1=timer.read(); CSd PAPT = CS_symperm(A, pinv, 1); t2=timer.read(); if (!PAPT.ok()) { umERROR("CS_PCG::cholinc", "symperm failed\n"); return -1; } else { umLOG(1, "\tPermute time = %10.3lf seconds\n",t2-t1); } #if (OUT_TO_MATLAB) { FILE* fp=fopen("z_PAPT1.dat", "w"); PAPT.write_ML(fp); fclose(fp); } #endif // output #endif // perm #if (APPLY_PERM) //----------------------------------- // 3. calc cholinc preconditioner //----------------------------------- // FIXME: undo transpose // CS_Cholinc expects tril(PAPT) #if (1) umLOG(1, "\ttransposing PAP' before factorize... "); t1=timer.read(); PAPT.transpose(1); umLOG(1, "(%.3lf secs)\n",timer.read()-t1); #endif #if (OUT_TO_MATLAB) { FILE* fp=fopen("z_PAPT2.dat", "w"); PAPT.write_ML(fp); fclose(fp); } #endif // output #endif // perm t1 = timer.read(); //this->L = CS_Cholinc(PAPT,droptol,modified_flag); this->L = CS_Cholinc(this->A,droptol,modified_flag); t2 = timer.read(); if (!this->L.ok()) { umERROR("CS_PCG::cholinc", "factor_llt failed\n"); return -1; } double curr = L.P[n]; umLOG(1, " ==> CS_PCG fac: nnz(A): %11.0lf\n" " nnz(L): %11.0lf d.tol %0.1e\n" " fillin: %11.0lf ratio %0.3lf\n" " time: %11.2lf seconds\n", unit, curr, droptol, curr-unit, curr/unit, t2-t1); umLOG(1, " -----------------------------------------------\n\n"); } #if (OUT_TO_MATLAB) { FILE* fp=fopen("z_L.dat", "w"); this->L.write_ML(fp); fclose(fp); } umERROR("Nigel", "Compare with Matlab"); #endif m_factor = true; // cholinc() factor is now ready return 0; }