56 Int i, pos, jnew, head, llen ;
70 jnew = (phase1 && j < npiv) ? (Pinv [j]) : (j) ;
80 Pstack [head] = (Lprune [jnew] ==
EMPTY) ?
81 (Llen [jnew]) : (Lprune [jnew]) ;
86 Lj = (
Int *) (LU + Lip [jnew]) ;
87 for (pos = --Pstack [head] ; pos > 0 ; --pos)
99 if (i < npiv && (!phase1 || Pinv [i] >= 0))
105 Pstack [head] = pos ;
184 Int i, p, p2, pend, top, llen, ulen, lup ;
195 Li = (
Int *) (LU + lup) ;
198 for (p = Ap [kcol] ; p < pend ; p++)
210 i = (i < npiv) ? Pinv [i] : i ;
211 if (i >= nfound) continue ;
217 if (i < npiv && (!phase1 || Pinv [i] >= 0))
219 top =
dfs (npiv, i, mark, Pinv, Llen, Lip, phase1, Stack, Flag,
220 Lprune, top, LU, Li, &llen, Pstack) ;
240 lup += ((llen + 1) / 2) + llen ;
250 Ui = (
Int *) (LU + lup) ;
254 lup += ((ulen + 1) / 2) + ulen ;
257 for (p = top, p2 = 0 ; p < n ; p++, p2++)
259 Ui [p2] = Stack [p] ;
296 for (p = Ap [kcol] ; p < pend ; p++)
298 X [Ai [p]] = Ax [p] ;
305 for (p = Ap [kcol] ; p < pend ; p++)
308 i = (i < npiv) ? Pinv [i] : i ;
353 Int p, s, j, jnew, llen, ulen ;
356 Ui = (
Int *) (LU + Uip [k]) ;
362 for (s = 0 ; s < ulen ; s++)
368 jnew = (phase1 && j < npiv) ? (Pinv [j]) : j ;
374 GET_COLUMN (Lip, Llen, LU, jnew, Li, Lx, llen) ;
378 llen = Lphase_len [jnew] ;
380 for (p = 1 ; p < llen ; p++)
383 X [Li [p]] -= Lx [p] * xj ;
435 lsolve_symbolic (n, k, mark, kcol, Ap, Ai, Pinv, phase1, nfound, npiv,
436 Stack, Flag, Lprune, Pstack, LU, lup, Llen, Ulen, Lip, Uip) ;
449 Pinv, LU, Uip, Lip, Ulen, Llen, k, phase1, Lphase_len, X) ;
461 for (p = 0 ; p < ulen ; p++)
464 ASSERT (i >= 0 && i < npiv) ;
465 ASSERT (Pinv [i] >= 0 && Pinv [i] < npiv) ;
474 for (p = 0 ; p < ulen ; p++)
477 ASSERT (i >= 0 && i < nfound) ;
509 double x, pivot, abs_pivot, max_entry ;
511 Int p, i, ppivrow, pdiag, pivrow, pivot_found, llen ;
525 for (p = 0 ; p < llen ; p++)
542 if (x > abs_pivot && i < npiv)
549 max_entry =
MAX (max_entry, x) ;
555 x = fabs (Lx [pdiag]) ;
556 if (x >= tol_diag * max_entry)
573 if (abs_pivot < tol_offdiag * max_entry)
580 pivot_found = (ppivrow !=
EMPTY && abs_pivot > 0) ;
585 pivrow = Li [ppivrow] ;
586 pivot = Lx [ppivrow] ;
587 Li [ppivrow] = Li [0] ;
588 Lx [ppivrow] = Lx [0] ;
592 ASSERT (pivrow >= 0 && pivrow < npiv) ;
596 for (p = 1 ; p < Llen [k] ; p++)
603 *p_abs_pivot = abs_pivot ;
606 return (pivot_found) ;
634 Int p, i, j, p2, phead, ptail, ulen, llen ;
644 for (p = 0 ; p < ulen ; p++)
647 ASSERT (j >= 0 && j < k) ;
648 if (Lprune [j] ==
EMPTY)
653 for (p2 = 0 ; p2 < Llen [j] ; p2++)
655 if (pivrow == Li [p2])
662 while (phead < ptail)
665 if (i < npiv && Pinv [i] >= 0)
674 Li [phead] = Li [ptail] ;
677 Lx [phead] = Lx [ptail] ;
714 double pivot, abs_pivot, umin, umax, ujk, x, tol_diag, tol_offdiag, growth ;
715 double *Lx, *Ux, *LU, *S, *Sx, *Ax, *X ;
716 Int *Li, *Ui, *Si, *Qinv, *L1_len, *Ap, *Ai, *Llen, *Ulen, *Lip, *Uip, *
P,
717 *Q, *Pinv, *Sip, *Slen, *Flag, *Queue, *Iwork, *Stack, *Pstack,
719 Int k, p, i, j, pivrow, kbar, diagrow, noffdiag, lup, mark, unpruned,
720 phead, ptail, sp, slen, llen, ulen, p2, pend, ngrow, qhead, qtail, sn,
721 found, kcol, second_try, nfound, n, npiv, lnz, unz, snz, lup_orig ;
722 size_t lusize, ssize ;
737 Llen = LUnode->
llen ;
738 Ulen = LUnode->
ulen ;
743 npiv = LUnode->PK_NPIV ;
748 Pinv = LUnode->
Pinv ;
750 Qinv = LUnode->
Qinv ;
773 Lprune = Iwork + 2*n ;
786 npiv =
MAX (0,
MIN (npiv, n)) ;
801 for (k = 0 ; k < n ; k++)
823 for (k = 0 ; k < npiv ; k++)
826 Pinv [k] =
FLIP (k) ;
838 for (k = 0 ; k < npiv ; k++)
849 for (k = 0 ; k < npiv ; k++)
852 PR1 ((Common->
file,
"\n\n==========================L,U1: k: "ID"\n", k));
860 if (lup + ngrow > (
Int) lusize)
862 size_t new = (growth * lusize + ngrow + 2) ;
863 PR1 ((Common->
file,
"growing LU from "ID" to "ID"\n", lusize,
new)) ;
864 LU =
CHOLMOD (realloc) (
new,
sizeof (double), LU, &lusize, cm) ;
882 while (!found && qhead != qtail)
889 kcol = Queue [qhead] ;
890 qhead = (qhead + 1) % (npiv + 1) ;
891 second_try = (kcol < 0) ;
900 n, k, kcol, Ap, Ai, Ax, LU, &lup, Lip, Uip,
901 Llen, Ulen, Llen, Pinv, Stack, Lprune, Pstack, Flag, mark, X) ;
909 PR1 ((Common->
file,
"k "ID", diagrow = "ID", UNFLIP(diagrow) = "ID"\n",
910 k, diagrow,
UNFLIP (diagrow))) ;
913 found =
lpivot (diagrow, &pivrow, &pivot, &abs_pivot, tol_diag,
914 tol_offdiag, X, LU, Lip, Llen, k, npiv) ;
924 PR1 ((Common->
file,
"requeue kcol "ID
" for 2nd try\n", kcol));
925 Queue [qtail] =
FLIP (kcol) ;
926 qtail = (qtail + 1) % (npiv + 1) ;
930 PR1 ((Common->
file,
"discarding kcol "ID
"\n", kcol)) ;
932 PR1 ((Common->
file,
"restore lup, "ID
" to "ID
"\n", lup_orig, lup)) ;
938 Q [nfound++] = kcol ;
939 PR1 ((Common->
file,
"found kcol: "ID
" nfound "ID
"\n", kcol, nfound));
958 PR1 ((Common->
file,
"\nk "ID": pivcol "ID" pivrow "ID": %g\n",
959 k, kcol, pivrow, pivot)) ;
960 ASSERT (pivrow >= 0 && pivrow < npiv) ;
961 ASSERT (Pinv [pivrow] < 0) ;
972 else if (abs_pivot < umin)
976 else if (abs_pivot > umax)
986 PR1 ((Common->
file,
"k "ID
" Ulen[k] "ID
"\n", k, Ulen [k])) ;
989 Ux [ulen-1] = pivot ;
990 PR1 ((Common->
file,
"pivot: Ui "ID
" Ux %g\n", Ui [ulen-1], Ux [ulen-1])) ;
998 ASSERT (P [kbar] == diagrow) ;
1000 if (pivrow != diagrow)
1007 PR1 ((Common->
file,
">>>>>>>>>>>>>>>> pivrow "ID
" k "ID
" off-diagonal\n",
1009 if (Pinv [diagrow] < 0)
1015 kbar =
FLIP (Pinv [pivrow]) ;
1016 P [kbar] = diagrow ;
1017 Pinv [diagrow] =
FLIP (kbar) ;
1024 for (p = 0 ; p < ulen ; p++)
1026 PR2 ((Common->
file,
"Column "ID
" of U: "ID
": %g\n", k, Ui [p], Ux [p])) ;
1028 GET_COLUMN (Lip, Llen, LU, k, Li, Lx, llen) ;
1029 for (p = 0 ; p < llen ; p++)
1031 PR2 ((Common->
file,
"Column "ID
" of L: "ID
": %g\n", k, Li [p], Lx [p])) ;
1039 prune (npiv, Lprune, Pinv, k, pivrow, LU, Uip, Lip, Ulen, Llen) ;
1046 LUnode->
umin = umin ;
1047 LUnode->
umax = umax ;
1048 LUnode->PK_NFOUND = nfound ;
1051 PR1 ((Common->
file,
"noffdiag "ID"\n", noffdiag)) ;
1052 PR1 ((Common->
file,
"umin %g umax %g condest %g\n", umin, umax, umax/umin));
1062 DEBUG (
for (i = 0 ; i < n ; i++)
ASSERT (Flag [i] < mark)) ;
1065 for (i = 0 ; i < npiv ; i++)
1075 for (j = 0 ; j < npiv ; j++)
1079 for (k = 0 ; k < nfound ; k++)
1081 PR2 ((Common->
file,
"k "ID" Q [k] "ID" npiv "ID"\n", k, Q [k], npiv)) ;
1082 ASSERT (Q [k] >= 0 && Q [k] < npiv) ;
1087 for (j = 0 ; j < npiv ; j++)
1089 if (Qinv [j] ==
EMPTY)
1099 for (i = 0 ; i < npiv ; i++)
1101 if (i == nfound)
PR1 ((Common->
file,
"-------- nfound = "ID"\n", nfound)) ;
1102 if (i == npiv )
PR1 ((Common->
file,
"-------- npiv = "ID"\n", npiv )) ;
1103 PR2 ((Common->
file,
"P["ID"] = "ID" Pinv["ID"] = "ID"\n", i, P[i], i, Pinv[i])) ;
1104 PR2 ((Common->
file,
"Q["ID
"] = "ID
" Qinv["ID
"] = "ID
"\n", i, Q[i], i, Qinv[i])) ;
1115 for (j = 0 ; j < nfound ; j++)
1117 GET_COLUMN (Lip, Llen, LU, j, Li, Lx, llen) ;
1120 for (p = 0 ; p < llen ; p++)
1129 unpruned = (Lprune [j] ==
EMPTY) ;
1131 phead = (unpruned) ? 1 : (Lprune [j]) ;
1136 for (p = 0 ; p < phead ; p++)
1138 ASSERT (Li [p] < nfound) ;
1143 while (phead < ptail)
1155 Li [phead] = Li [ptail] ;
1158 Lx [phead] = Lx [ptail] ;
1163 L1_len [j] = ptail ;
1168 Lprune [j] = L1_len [j] ;
1173 for (p = 0 ; p < Lprune [j] ; p++)
1175 ASSERT (Li [p] < nfound) ;
1177 ASSERT (Lprune [j] <= L1_len [j]) ;
1178 for ( ; p < L1_len [j] ; p++)
1180 ASSERT (Li [p] < nfound) ;
1182 for ( ; p < Llen [j] ; p++)
1184 ASSERT (Li [p] >= nfound) ;
1199 for (k = nfound ; k < n ; k++)
1201 PR1 ((Common->
file,
"\n\n=============================U2: k: "ID"\n", k));
1209 if (lup + ngrow > (
Int) lusize)
1211 size_t new = (growth * lusize + ngrow + 2) ;
1212 LU =
CHOLMOD (realloc) (
new,
sizeof (double), LU, &lusize, cm) ;
1214 LUnode->
lusize = lusize ;
1227 kcol = (k < npiv) ? Q [k] : k ;
1234 n, k, kcol, Ap, Ai, Ax, LU, &lup, Lip, Uip,
1235 Llen, Ulen, L1_len, Pinv, Stack, Lprune, Pstack, Flag, mark, X) ;
1237 PR2 ((Common->
file,
"lup is now "ID"\n", lup)) ;
1240 GET_COLUMN (Uip, Ulen, LU, k, Ui, Ux, ulen) ;
1241 for (p = 0 ; p < ulen ; p++)
1243 PR2 ((Common->
file,
"Column "ID" of U2: "ID": %g\n", k, Ui[p], Ux[p])) ;
1259 LU =
CHOLMOD (realloc) (lup,
sizeof (double), LU, &lusize, cm) ;
1261 LUnode->
lusize = lusize ;
1270 LUnode->PK_SSIZE = ssize ;
1271 PR1 ((Common->
file,
"allocate S, : ssize "ID" sn "ID" \n", ssize, sn)) ;
1273 S =
CHOLMOD (malloc) (ssize,
sizeof (double), cm) ;
1274 Sip =
CHOLMOD (malloc) (sn,
sizeof (
Int), cm) ;
1275 Slen =
CHOLMOD (malloc) (sn,
sizeof (
Int), cm) ;
1278 LUnode->
slen = Slen ;
1279 LUnode->PK_SSIZE = ssize ;
1280 LUnode->PK_SN = sn ;
1289 ngrow = (3 * (n - nfound) / 2) + 2 ;
1293 for (k = nfound ; k < n ; k++)
1295 PR2 ((Common->
file,
"\n\n========================== S: k: "ID
" sk: "ID
"\n",
1297 DEBUG (
for (i = 0 ; i < n ; i++)
ASSERT (Flag [i] < mark)) ;
1303 if (sp + ngrow > (
Int) ssize)
1305 size_t new = (growth * ssize + ngrow + 2) ;
1306 PR1 ((Common->
file,
"proc "ID
" growing S from "ID
" to "ID
"\n",
1307 Common->
myid, ssize,
new)) ;
1308 S =
CHOLMOD (realloc) (
new,
sizeof (double), S, &ssize, cm) ;
1310 LUnode->PK_SSIZE = ssize ;
1323 Sip [k - nfound] = sp ;
1324 Si = (
Int *) (S + sp) ;
1330 kcol = (k < npiv) ? Q [k] : k ;
1332 DEBUG (
for (i = 0 ; i < n ; i++)
ASSERT (X [i] == 0)) ;
1335 pend = Ap [kcol+1] ;
1336 for (p = Ap [kcol] ; p < pend ; p++)
1339 i = (i < npiv) ? Pinv [i] : i ;
1342 PR3 ((Common->
file,
"S: Entry in A: "ID
" %g\n", i, Ax [p])) ;
1345 Si [slen++] = i - nfound ;
1354 GET_COLUMN (Uip, Ulen, LU, k, Ui, Ux, ulen) ;
1355 PR2 ((Common->
file,
"Multiply L2 by U2(:,"ID
") :\n", k)) ;
1358 for (p = 0 ; p < ulen ; p++)
1362 ASSERT (j >= 0 && j < nfound) ;
1364 PR2 ((Common->
file,
"U("ID
","ID
") = %g\n", j, k, ujk)) ;
1365 GET_COLUMN (Lip, Llen, LU, j, Li, Lx, llen) ;
1366 for (p2 = L1_len [j] ; p2 < llen ; p2++)
1369 ASSERT (i >= nfound && i < n) ;
1370 PR3 ((Common->
file,
" L("ID
","ID
") = %g\n", i, j, Lx [p2])) ;
1371 if (Flag [i] < mark)
1373 PR3 ((Common->
file,
" new entry in Si, slen "ID
"\n",slen));
1374 Si [slen++] = i - nfound ;
1377 X [i] -= Lx [p2] * ujk ;
1391 Slen [k - nfound] = slen ;
1392 PR2 ((Common->
file,
"Slen ["ID
"] = "ID
"\n", k - nfound, Slen [k - nfound]));
1394 sp += ((slen + 1) / 2) ;
1395 Sx = (
double *) (S + sp) ;
1402 PR2 ((Common->
file,
"snz so far: "ID
". Final col of S(:,"ID
")=\n", snz, k));
1403 for (p = 0 ; p < slen ; p++)
1405 i = Si [p] + nfound ;
1408 PR3 ((Common->
file,
" S("ID
","ID
") = %g\n", i-nfound, k-nfound, Sx[p]));
1410 DEBUG (
for (i = 0 ; i < n ; i++)
ASSERT (X [i] == 0)) ;
1420 PR0 ((Common->
file,
"Final ssize = "ID
" sn = "ID
" snz: "ID
"\n", sp, sn, snz)) ;
1421 S =
CHOLMOD (realloc) (sp,
sizeof (double), S, &ssize, cm) ;
1423 LUnode->PK_SNZ = snz ;
1424 LUnode->PK_SSIZE = ssize ;
static void prune(Int npiv, Int Lprune[], Int Pinv[], Int k, Int pivrow, double *LU, Int Uip[], Int Lip[], Int Ulen[], Int Llen[])
static void construct_column(Int kcol, Int Ap[], Int Ai[], double Ax[], Int phase1, Int nfound, Int npiv, Int Pinv[], double X[])
#define PARAKLETE_ERROR(status, message)
#define GET_COLUMN(Ap, Anz, Aix, j, Ai, Ax, len)
#define ASSERT(expression)
static void lsolve(Int phase1, Int nfound, Int npiv, Int n, Int k, Int kcol, Int Ap[], Int Ai[], double Ax[], double *LU, Int *lup, Int Lip[], Int Uip[], Int Llen[], Int Ulen[], Int Lphase_len[], Int Pinv[], Int Stack[], Int Lprune[], Int Pstack[], Int Flag[], Int mark, double X[])
static Int dfs(Int npiv, Int j, Int mark, Int Pinv[], Int Llen[], Int Lip[], Int phase1, Int Stack[], Int Flag[], Int Lprune[], Int top, double LU[], Int Li[], Int *plength, Int Pstack[])
Int amesos_paraklete_kernel(cholmod_sparse *A, paraklete_node *LUnode, paraklete_common *Common)
int CHOLMOD() allocate_work(size_t nrow, size_t iworksize, size_t xworksize, cholmod_common *Common)
static void lsolve_symbolic(Int n, Int k, Int mark, Int kcol, Int Ap[], Int Ai[], Int Pinv[], Int phase1, Int nfound, Int npiv, Int Stack[], Int Flag[], Int Lprune[], Int Pstack[], double LU[], Int *plu, Int Llen[], Int Ulen[], Int Lip[], Int Uip[])
static Int lpivot(Int diagrow, Int *p_pivrow, double *p_pivot, double *p_abs_pivot, double tol_diag, double tol_offdiag, double X[], double *LU, Int Lip[], Int Llen[], Int k, Int npiv)
static void lsolve_numeric(Int npiv, Int Pinv[], double *LU, Int Uip[], Int Lip[], Int Ulen[], Int Llen[], Int k, Int phase1, Int Lphase_len[], double X[])