46 Int i, pos, jnew, head, l_length ;
59 ASSERT (jnew >= 0 && jnew < k) ;
65 PRINTF ((
"[ start dfs at %d : new %d\n", j, jnew)) ;
68 (Lpend [jnew] ==
EMPTY) ? Llen [jnew] : Lpend [jnew] ;
73 Li = (
Int *) (LU + Lip [jnew]) ;
74 for (pos = --Ap_pos [head] ; pos >= 0 ; --pos)
110 PRINTF ((
" end dfs at %d ] head : %d\n", j, head)) ;
114 *plength = l_length ;
160 Int i, p, pend, oldcol, kglobal, top, l_length ;
164 Lik = (
Int *) (LU + lup);
171 oldcol = Q [kglobal] ;
172 pend = Ap [oldcol+1] ;
173 for (p = Ap [oldcol] ; p < pend ; p++)
175 i = PSinv [Ai [p]] - k1 ;
176 if (i < 0) continue ;
179 PRINTF ((
"\n ===== DFS at node %d in b, inew: %d\n", i, Pinv [i])) ;
184 top =
dfs (i, k, Pinv, Llen, Lip, Stack, Flag,
185 Lpend, top, LU, Lik, &l_length, Ap_pos) ;
198 Llen [k] = l_length ;
238 Int i, p, pend, oldcol, kglobal, poff, oldrow ;
245 poff = Offp [kglobal] ;
246 oldcol = Q [kglobal] ;
247 pend = Ap [oldcol+1] ;
252 for (p = Ap [oldcol] ; p < pend ; p++)
255 i = PSinv [oldrow] - k1 ;
260 Offi [poff] = oldrow ;
274 for (p = Ap [oldcol] ; p < pend ; p++)
277 i = PSinv [oldrow] - k1 ;
283 Offi [poff] = oldrow ;
295 Offp [kglobal+1] = poff ;
330 Int p, s, j, jnew, len ;
333 for (s = top ; s < n ; s++)
341 ASSERT (Lip [jnew] <= Lip [jnew+1]) ;
342 for (p = 0 ; p < len ; p++)
378 Entry x, pivot, *Lx ;
379 double abs_pivot, xabs ;
380 Int p, i, ppivrow, pdiag, pivrow, *Li, last_row_index, firstrow, len ;
386 if (Common->halt_if_singular)
390 for (firstrow = *p_firstrow ; firstrow < n ; firstrow++)
392 PRINTF ((
"check %d\n", firstrow)) ;
393 if (Pinv [firstrow] < 0)
397 PRINTF ((
"Got pivotal row: %d\n", pivrow)) ;
401 ASSERT (pivrow >= 0 && pivrow < n) ;
406 *p_firstrow = firstrow ;
415 last_row_index = Li [i] ;
422 for (p = 0 ; p < len ; p++)
440 if (xabs > abs_pivot)
448 ABS (xabs, X [last_row_index]) ;
449 if (xabs > abs_pivot)
456 if (last_row_index == diagrow)
458 if (xabs >= tol * abs_pivot)
464 else if (pdiag !=
EMPTY)
467 ABS (xabs, Lx [pdiag]) ;
468 if (xabs >= tol * abs_pivot)
476 if (ppivrow !=
EMPTY)
478 pivrow = Li [ppivrow] ;
479 pivot = Lx [ppivrow] ;
481 Li [ppivrow] = last_row_index ;
482 Lx [ppivrow] = X [last_row_index] ;
486 pivrow = last_row_index ;
487 pivot = X [last_row_index] ;
489 CLEAR (X [last_row_index]) ;
493 *p_abs_pivot = abs_pivot ;
494 ASSERT (pivrow >= 0 && pivrow < n) ;
496 if (
IS_ZERO (pivot) && Common->halt_if_singular)
503 for (p = 0 ; p < Llen [k] ; p++)
506 DIV (Lx [p], Lx [p], pivot) ;
542 Int p, i, j, p2, phead, ptail, llen, ulen ;
546 for (p = 0 ; p < ulen ; p++)
550 PRINTF ((
"%d is pruned: %d. Lpend[j] %d Lip[j+1] %d\n",
551 j, Lpend [j] !=
EMPTY, Lpend [j], Lip [j+1])) ;
552 if (Lpend [j] ==
EMPTY)
556 for (p2 = 0 ; p2 < llen ; p2++)
558 if (pivrow == Li [p2])
562 PRINTF ((
"==== PRUNE: col j %d of L\n", j)) ;
565 for (p3 = 0 ; p3 < Llen [j] ; p3++)
567 PRINTF ((
"before: %i pivotal: %d\n", Li [p3],
568 Pinv [Li [p3]] >= 0)) ;
577 while (phead < ptail)
589 Li [phead] = Li [ptail] ;
592 Lx [phead] = Lx [ptail] ;
608 for (p3 = 0 ; p3 < Llen [j] ; p3++)
610 if (p3 == Lpend [j])
PRINTF ((
"----\n")) ;
611 PRINTF ((
"after: %i pivotal: %d\n", Li [p3],
612 Pinv [Li [p3]] >= 0)) ;
677 double abs_pivot, xsize, nunits,
tol,
memgrow ;
681 Int k, p, i, j, pivrow, kbar, diagrow, firstrow, lup, top,
scale, len ;
689 scale = Common->scale ;
691 memgrow = Common->memgrow ;
699 PRINTF ((
"input: lusize %d \n", lusize)) ;
710 for (k = 0 ; k < n ; k++)
723 for (k = 0 ; k < n ; k++)
726 Pinv [k] =
FLIP (k) ;
737 for (k = 0 ; k < n ; k++)
739 PRINTF ((
"Initial P [%d] = %d\n", k, P [k])) ;
747 for (k = 0 ; k < n ; k++)
750 PRINTF ((
"\n\n==================================== k: %d\n", k)) ;
761 PRINTF ((
"lup %d lusize %g lup+nunits: %g\n", lup, (
double) lusize,
763 xsize = ((double) lup) + nunits ;
764 if (xsize > (
double) lusize)
767 xsize = (memgrow * ((double) lusize) + 4*n + 1) ;
770 PRINTF ((
"Matrix is too large (Int overflow)\n")) ;
774 newlusize = memgrow * lusize + 2*n + 1 ;
781 PRINTF ((
"Matrix is too large (LU)\n")) ;
785 PRINTF ((
"inc LU to %d done\n", lusize)) ;
799 for (i = 0 ; i < n ; i++)
808 Lpend, Ap_pos, LU, lup, Llen, Lip, k1, PSinv) ;
811 PRINTF ((
"--- in U:\n")) ;
812 for (p = top ; p < n ; p++)
814 PRINTF ((
"pattern of X for U: %d : %d pivot row: %d\n",
815 p, Stack [p], Pinv [Stack [p]])) ;
816 ASSERT (Flag [Stack [p]] == k) ;
818 PRINTF ((
"--- in L:\n")) ;
819 Li = (
Int *) (LU + Lip [k]);
820 for (p = 0 ; p < Llen [k] ; p++)
822 PRINTF ((
"pattern of X in L: %d : %d pivot row: %d\n",
823 p, Li [p], Pinv [Li [p]])) ;
824 ASSERT (Flag [Li [p]] == k) ;
827 for (i = 0 ; i < n ; i++)
830 if (Flag [i] == k) p++ ;
839 k1, PSinv, Rs, scale, Offp, Offi, Offx) ;
848 for (p = top ; p < n ; p++)
850 PRINTF ((
"X for U %d : ", Stack [p])) ;
853 Li = (
Int *) (LU + Lip [k]) ;
854 for (p = 0 ; p < Llen [k] ; p++)
856 PRINTF ((
"X for L %d : ", Li [p])) ;
867 PRINTF ((
"k %d, diagrow = %d, UNFLIP (diagrow) = %d\n",
868 k, diagrow,
UNFLIP (diagrow))) ;
871 if (!
lpivot (diagrow, &pivrow, &pivot, &abs_pivot, tol, X, LU, Lip,
872 Llen, k, n, Pinv, &firstrow, Common))
876 if (Common->numerical_rank ==
EMPTY)
878 Common->numerical_rank = k+k1 ;
879 Common->singular_col = Q [k+k1] ;
881 if (Common->halt_if_singular)
890 PRINTF ((
"\nk %d : Pivot row %d : ", k, pivrow)) ;
892 ASSERT (pivrow >= 0 && pivrow < n) ;
893 ASSERT (Pinv [pivrow] < 0) ;
906 for (p = top, i = 0 ; p < n ; p++, i++)
927 if (pivrow != diagrow)
931 PRINTF ((
">>>>>>>>>>>>>>>>> pivrow %d k %d off-diagonal\n",
933 if (Pinv [diagrow] < 0)
939 kbar =
FLIP (Pinv [pivrow]) ;
941 Pinv [diagrow] =
FLIP (kbar) ;
950 for (p = 0 ; p < len ; p++)
952 PRINTF ((
"Column %d of U: %d : ", k, Ui [p])) ;
956 for (p = 0 ; p < len ; p++)
958 PRINTF ((
"Column %d of L: %d : ", k, Li [p])) ;
967 prune (Lpend, Pinv, k, pivrow, LU, Uip, Lip, Ulen, Llen) ;
969 *lnz += Llen [k] + 1 ;
970 *unz += Ulen [k] + 1 ;
977 for (p = 0 ; p < n ; p++)
979 Li = (
Int *) (LU + Lip [p]) ;
980 for (i = 0 ; i < Llen [p] ; i++)
982 Li [i] = Pinv [Li [i]] ;
987 for (i = 0 ; i < n ; i++)
989 PRINTF ((
"P [%d] = %d Pinv [%d] = %d\n", i, P [i], i, Pinv [i])) ;
991 for (i = 0 ; i < n ; i++)
993 ASSERT (Pinv [i] >= 0 && Pinv [i] < n) ;
994 ASSERT (P [i] >= 0 && P [i] < n) ;
995 ASSERT (P [Pinv [i]] == i) ;
1005 ASSERT ((
size_t) newlusize <= lusize) ;
1010 return (newlusize) ;
static Int dfs(Int j, Int k, Int Pinv[], Int Llen[], Int Lip[], Int Stack[], Int Flag[], Int Lpend[], Int top, Unit LU[], Int *Lik, Int *plength, Int Ap_pos[])
static Int lsolve_symbolic(Int n, Int k, Int Ap[], Int Ai[], Int Q[], Int Pinv[], Int Stack[], Int Flag[], Int Lpend[], Int Ap_pos[], Unit LU[], Int lup, Int Llen[], Int Lip[], Int k1, Int PSinv[])
#define GET_POINTER(LU, Xip, Xlen, Xi, Xx, k, xlen)
static void lsolve_numeric(Int Pinv[], Unit *LU, Int Stack[], Int Lip[], Int top, Int n, Int Llen[], Entry X[])
static Int lpivot(Int diagrow, Int *p_pivrow, Entry *p_pivot, double *p_abs_pivot, double tol, Entry X[], Unit *LU, Int Lip[], Int Llen[], Int k, Int n, Int Pinv[], Int *p_firstrow, KLU_common *Common)
#define KLU_OUT_OF_MEMORY
static void prune(Int Lpend[], Int Pinv[], Int k, Int pivrow, Unit *LU, Int Uip[], Int Lip[], Int Ulen[], Int Llen[])
size_t KLU_kernel(Int n, Int Ap[], Int Ai[], Entry Ax[], Int Q[], size_t lusize, Int Pinv[], Int P[], Unit **p_LU, Entry Udiag[], Int Llen[], Int Ulen[], Int Lip[], Int Uip[], Int *lnz, Int *unz, Entry X[], Int Stack[], Int Flag[], Int Ap_pos[], Int Lpend[], Int k1, Int PSinv[], double Rs[], Int Offp[], Int Offi[], Entry Offx[], KLU_common *Common)
#define ASSERT(expression)
#define MULT_SUB(c, a, b)
static void construct_column(Int k, Int Ap[], Int Ai[], Entry Ax[], Int Q[], Entry X[], Int k1, Int PSinv[], double Rs[], Int scale, Int Offp[], Int Offi[], Entry Offx[])