void dLCP::transfer_i_from_C_to_N (int i, void *tmpbuf) { { int *C = m_C; // remove a row/column from the factorization, and adjust the // indexes (black magic!) int last_idx = -1; const int nC = m_nC; int j = 0; for ( ; j<nC; ++j) { if (C[j]==nC-1) { last_idx = j; } if (C[j]==i) { dLDLTRemove (m_A,C,m_L,m_d,m_n,nC,j,m_nskip,tmpbuf); int k; if (last_idx == -1) { for (k=j+1 ; k<nC; ++k) { if (C[k]==nC-1) { break; } } dIASSERT (k < nC); } else { k = last_idx; } C[k] = C[j]; if (j < (nC-1)) memmove (C+j,C+j+1,(nC-j-1)*sizeof(int)); break; } } dIASSERT (j < nC); swapProblem (m_A,m_x,m_b,m_w,m_lo,m_hi,m_p,m_state,m_findex,m_n,i,nC-1,m_nskip,1); m_nN++; m_nC = nC - 1; // nC value is outdated after this line } # ifdef DEBUG_LCP checkFactorization (m_A,m_L,m_d,m_nC,m_C,m_nskip); # endif }
void dLCP::transfer_i_from_C_to_N (int i) { // remove a row/column from the factorization, and adjust the // indexes (black magic!) int j,k; for (j=0; j<nC; j++) if (C[j]==i) { dLDLTRemove (A,C,L,d,n,nC,j,nskip); for (k=0; k<nC; k++) if (C[k]==nC-1) { C[k] = C[j]; if (j < (nC-1)) memmove (C+j,C+j+1,(nC-j-1)*sizeof(int)); break; } dIASSERT (k < nC); break; } dIASSERT (j < nC); swapProblem (A,x,b,w,lo,hi,p,state,findex,n,i,nC-1,nskip,1); nC--; nN++; # ifdef DEBUG_LCP checkFactorization (A,L,d,nC,C,nskip); # endif }
void testLDLTRemove() { int i,j,r,p[MSIZE]; dReal A[MSIZE4*MSIZE], L[MSIZE4*MSIZE], d[MSIZE], L2[MSIZE4*MSIZE], d2[MSIZE], DL2[MSIZE4*MSIZE], Atest1[MSIZE4*MSIZE], Atest2[MSIZE4*MSIZE], diff, maxdiff; HEADER; // make array of A row pointers dReal *Arows[MSIZE]; for (i=0; i<MSIZE; i++) Arows[i] = A+i*MSIZE4; // fill permutation vector for (i=0; i<MSIZE; i++) p[i]=i; dMakeRandomMatrix (A,MSIZE,MSIZE,1.0); dMultiply2 (L,A,A,MSIZE,MSIZE,MSIZE); memcpy (A,L,MSIZE4*MSIZE*sizeof(dReal)); dFactorLDLT (L,d,MSIZE,MSIZE4); maxdiff = 1e10; for (r=0; r<MSIZE; r++) { // get Atest1 = A with row/column r removed memcpy (Atest1,A,MSIZE4*MSIZE*sizeof(dReal)); dRemoveRowCol (Atest1,MSIZE,MSIZE4,r); // test that the row/column removal worked int bad = 0; for (i=0; i<MSIZE; i++) { for (j=0; j<MSIZE; j++) { if (i != r && j != r) { int ii = i; int jj = j; if (ii >= r) ii--; if (jj >= r) jj--; if (A[i*MSIZE4+j] != Atest1[ii*MSIZE4+jj]) bad = 1; } } } if (bad) printf ("\trow/col removal FAILED for row %d\n",r); // zero out last row/column of Atest1 for (i=0; i<MSIZE; i++) { Atest1[(MSIZE-1)*MSIZE4+i] = 0; Atest1[i*MSIZE4+MSIZE-1] = 0; } // get L2*D2*L2' = adjusted factorization to remove that row memcpy (L2,L,MSIZE4*MSIZE*sizeof(dReal)); memcpy (d2,d,MSIZE*sizeof(dReal)); dLDLTRemove (/*A*/ Arows,p,L2,d2,MSIZE,MSIZE,r,MSIZE4); // get Atest2 = L2*D2*L2' dClearUpperTriangle (L2,MSIZE); for (i=0; i<(MSIZE-1); i++) L2[i*MSIZE4+i] = 1.0; for (i=0; i<MSIZE; i++) L2[(MSIZE-1)*MSIZE4+i] = 0; d2[MSIZE-1] = 1; dSetZero (DL2,MSIZE4*MSIZE); for (i=0; i<(MSIZE-1); i++) { for (j=0; j<MSIZE-1; j++) DL2[i*MSIZE4+j] = L2[i*MSIZE4+j] / d2[j]; } dMultiply2 (Atest2,L2,DL2,MSIZE,MSIZE,MSIZE); diff = dMaxDifference(Atest1,Atest2,MSIZE,MSIZE); if (diff < maxdiff) maxdiff = diff; /* dPrintMatrix (Atest1,MSIZE,MSIZE); printf ("\n"); dPrintMatrix (Atest2,MSIZE,MSIZE); printf ("\n"); */ } printf ("\tmaximum difference = %.6e - %s\n",maxdiff, maxdiff > tol ? "FAILED" : "passed"); }