42 #ifndef KLU2_KERNEL_HPP
43 #define KLU2_KERNEL_HPP
45 #include "klu2_internal.h"
46 #include "klu2_memory.hpp"
54 template <
typename Int>
80 Int i, pos, jnew, head, l_length ;
87 ASSERT (Flag [j] != k) ;
93 ASSERT (jnew >= 0 && jnew < k) ;
99 PRINTF ((
"[ start dfs at %d : new %d\n", j, jnew)) ;
102 (Lpend [jnew] == EMPTY) ? Llen [jnew] : Lpend [jnew] ;
107 Li = (Int *) (LU + Lip [jnew]) ;
108 for (pos = --Ap_pos [head] ; pos >= 0 ; --pos)
119 Ap_pos [head] = pos ;
144 PRINTF ((
" end dfs at %d ] head : %d\n", j, head)) ;
148 *plength = l_length ;
159 template <
typename Int>
160 static Int lsolve_symbolic
195 Int i, p, pend, oldcol, kglobal, top, l_length ;
199 Lik = (Int *) (LU + lup);
206 oldcol = Q [kglobal] ;
207 pend = Ap [oldcol+1] ;
208 for (p = Ap [oldcol] ; p < pend ; p++)
210 i = PSinv [Ai [p]] - k1 ;
211 if (i < 0) continue ;
214 PRINTF ((
"\n ===== DFS at node %d in b, inew: %d\n", i, Pinv [i])) ;
219 top = dfs (i, k, Pinv, Llen, Lip, Stack, Flag,
220 Lpend, top, LU, Lik, &l_length, Ap_pos) ;
233 Llen [k] = l_length ;
246 template <
typename Entry,
typename Int>
247 static void construct_column
274 Int i, p, pend, oldcol, kglobal, poff, oldrow ;
281 poff = Offp [kglobal] ;
282 oldcol = Q [kglobal] ;
283 pend = Ap [oldcol+1] ;
288 for (p = Ap [oldcol] ; p < pend ; p++)
291 i = PSinv [oldrow] - k1 ;
296 Offi [poff] = oldrow ;
310 for (p = Ap [oldcol] ; p < pend ; p++)
313 i = PSinv [oldrow] - k1 ;
315 SCALE_DIV (aik, Rs [oldrow]) ;
319 Offi [poff] = oldrow ;
331 Offp [kglobal+1] = poff ;
344 template <
typename Entry,
typename Int>
345 static void lsolve_numeric
367 Int p, s, j, jnew, len ;
370 for (s = top ; s < n ; s++)
377 GET_POINTER (LU, Lip, Llen, Li, Lx, jnew, len) ;
378 ASSERT (Lip [jnew] <= Lip [jnew+1]) ;
379 for (p = 0 ; p < len ; p++)
382 MULT_SUB (X [Li [p]], Lx [p], xj) ;
394 template <
typename Entry,
typename Int>
413 KLU_common<Entry, Int> *Common
416 Entry x, pivot, *Lx ;
417 double abs_pivot, xabs ;
418 Int p, i, ppivrow, pdiag, pivrow, *Li, last_row_index, firstrow, len ;
424 if (Common->halt_if_singular)
428 for (firstrow = *p_firstrow ; firstrow < n ; firstrow++)
430 PRINTF ((
"check %d\n", firstrow)) ;
431 if (Pinv [firstrow] < 0)
435 PRINTF ((
"Got pivotal row: %d\n", pivrow)) ;
439 ASSERT (pivrow >= 0 && pivrow < n) ;
444 *p_firstrow = firstrow ;
452 GET_POINTER (LU, Lip, Llen, Li, Lx, k, len) ;
453 last_row_index = Li [i] ;
457 GET_POINTER (LU, Lip, Llen, Li, Lx, k, len) ;
460 for (p = 0 ; p < len ; p++)
478 if (xabs > abs_pivot)
486 KLU2_ABS (xabs, X [last_row_index]) ;
487 if (xabs > abs_pivot)
494 if (last_row_index == diagrow)
496 if (xabs >= tol * abs_pivot)
502 else if (pdiag != EMPTY)
505 KLU2_ABS (xabs, Lx [pdiag]) ;
506 if (xabs >= tol * abs_pivot)
514 if (ppivrow != EMPTY)
516 pivrow = Li [ppivrow] ;
517 pivot = Lx [ppivrow] ;
519 Li [ppivrow] = last_row_index ;
520 Lx [ppivrow] = X [last_row_index] ;
524 pivrow = last_row_index ;
525 pivot = X [last_row_index] ;
527 CLEAR (X [last_row_index]) ;
531 *p_abs_pivot = abs_pivot ;
532 ASSERT (pivrow >= 0 && pivrow < n) ;
534 if (IS_ZERO (pivot) && Common->halt_if_singular)
541 for (p = 0 ; p < Llen [k] ; p++)
544 DIV (Lx [p], Lx [p], pivot) ;
556 template <
typename Entry,
typename Int>
581 Int p, i, j, p2, phead, ptail, llen, ulen ;
584 GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, ulen) ;
588 for (p = 0 ; p < ulen ; p++)
592 PRINTF ((
"%d is pruned: %d. Lpend[j] %d Lip[j+1] %d\n",
593 j, Lpend [j] != EMPTY, Lpend [j], Lip [j+1])) ;
594 if (Lpend [j] == EMPTY)
597 GET_POINTER (LU, Lip, Llen, Li, Lx, j, llen) ;
598 for (p2 = 0 ; p2 < llen ; p2++)
600 if (pivrow == Li [p2])
604 PRINTF ((
"==== PRUNE: col j %d of L\n", j)) ;
607 for (p3 = 0 ; p3 < Llen [j] ; p3++)
609 PRINTF ((
"before: %i pivotal: %d\n", Li [p3],
610 Pinv [Li [p3]] >= 0)) ;
619 while (phead < ptail)
631 Li [phead] = Li [ptail] ;
634 Lx [phead] = Lx [ptail] ;
650 for (p3 = 0 ; p3 < Llen [j] ; p3++)
652 if (p3 == Lpend [j]) PRINTF ((
"----\n")) ;
653 PRINTF ((
"after: %i pivotal: %d\n", Li [p3],
654 Pinv [Li [p3]] >= 0)) ;
671 template <
typename Entry,
typename Int>
716 KLU_common<Entry, Int> *Common
720 double abs_pivot, xsize, nunits, tol, memgrow ;
724 Int k, p, i, j, pivrow = 0, kbar, diagrow, firstrow, lup, top,
scale, len ;
731 ASSERT (Common != NULL) ;
732 scale = Common->scale ;
734 memgrow = Common->memgrow ;
743 PRINTF ((
"input: lusize %d \n", lusize)) ;
744 ASSERT (lusize > 0) ;
754 for (k = 0 ; k < n ; k++)
767 for (k = 0 ; k < n ; k++)
770 Pinv [k] = FLIP (k) ;
781 for (k = 0 ; k < n ; k++)
783 PRINTF ((
"Initial P [%d] = %d\n", k, P [k])) ;
791 for (k = 0 ; k < n ; k++)
794 PRINTF ((
"\n\n==================================== k: %d\n", k)) ;
801 nunits = DUNITS (Int, n - k) + DUNITS (Int, k) +
802 DUNITS (Entry, n - k) + DUNITS (Entry, k) ;
805 PRINTF ((
"lup %d lusize %g lup+nunits: %g\n", lup, (
double) lusize,
807 xsize = ((double) lup) + nunits ;
808 if (xsize > (
double) lusize)
811 xsize = (memgrow * ((double) lusize) + 4*n + 1) ;
812 if (INT_OVERFLOW (xsize))
814 PRINTF ((
"Matrix is too large (Int overflow)\n")) ;
815 Common->status = KLU_TOO_LARGE ;
818 newlusize = (size_t) (memgrow * lusize + 2*n + 1) ;
820 LU = (Unit *) KLU_realloc (newlusize, lusize,
sizeof (Unit), LU, Common) ;
823 if (Common->status == KLU_OUT_OF_MEMORY)
825 PRINTF ((
"Matrix is too large (LU)\n")) ;
829 PRINTF ((
"inc LU to %d done\n", lusize)) ;
843 for (i = 0 ; i < n ; i++)
845 ASSERT (Flag [i] < k) ;
847 ASSERT (IS_ZERO (X [i])) ;
851 top = lsolve_symbolic (n, k, Ap, Ai, Q, Pinv, Stack, Flag,
852 Lpend, Ap_pos, LU, lup, Llen, Lip, k1, PSinv) ;
855 PRINTF ((
"--- in U:\n")) ;
856 for (p = top ; p < n ; p++)
858 PRINTF ((
"pattern of X for U: %d : %d pivot row: %d\n",
859 p, Stack [p], Pinv [Stack [p]])) ;
860 ASSERT (Flag [Stack [p]] == k) ;
862 PRINTF ((
"--- in L:\n")) ;
863 Li = (Int *) (LU + Lip [k]);
864 for (p = 0 ; p < Llen [k] ; p++)
866 PRINTF ((
"pattern of X in L: %d : %d pivot row: %d\n",
867 p, Li [p], Pinv [Li [p]])) ;
868 ASSERT (Flag [Li [p]] == k) ;
871 for (i = 0 ; i < n ; i++)
873 ASSERT (Flag [i] <= k) ;
874 if (Flag [i] == k) p++ ;
882 construct_column <Entry> (k, Ap, Ai, Ax, Q, X,
883 k1, PSinv, Rs,
scale, Offp, Offi, Offx) ;
889 lsolve_numeric <Entry> (Pinv, LU, Stack, Lip, top, n, Llen, X) ;
892 for (p = top ; p < n ; p++)
894 PRINTF ((
"X for U %d : ", Stack [p])) ;
895 PRINT_ENTRY (X [Stack [p]]) ;
897 Li = (Int *) (LU + Lip [k]) ;
898 for (p = 0 ; p < Llen [k] ; p++)
900 PRINTF ((
"X for L %d : ", Li [p])) ;
901 PRINT_ENTRY (X [Li [p]]) ;
911 PRINTF ((
"k %d, diagrow = %d, UNFLIP (diagrow) = %d\n",
912 k, diagrow, UNFLIP (diagrow))) ;
915 if (!lpivot <Entry> (diagrow, &pivrow, &pivot, &abs_pivot, tol, X, LU, Lip,
916 Llen, k, n, Pinv, &firstrow, Common))
919 Common->status = KLU_SINGULAR ;
920 if (Common->numerical_rank == EMPTY)
922 Common->numerical_rank = k+k1 ;
923 Common->singular_col = Q [k+k1] ;
925 if (Common->halt_if_singular)
934 PRINTF ((
"\nk %d : Pivot row %d : ", k, pivrow)) ;
935 PRINT_ENTRY (pivot) ;
936 ASSERT (pivrow >= 0 && pivrow < n) ;
937 ASSERT (Pinv [pivrow] < 0) ;
940 Uip [k] = Lip [k] + UNITS (Int, Llen [k]) + UNITS (Entry, Llen [k]) ;
944 lup += UNITS (Int, Llen [k]) + UNITS (Entry, Llen [k]) ;
949 GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, len) ;
950 for (p = top, i = 0 ; p < n ; p++, i++)
959 lup += UNITS (Int, Ulen [k]) + UNITS (Entry, Ulen [k]) ;
968 ASSERT (UNFLIP (Pinv [diagrow]) < n) ;
969 ASSERT (P [UNFLIP (Pinv [diagrow])] == diagrow) ;
971 if (pivrow != diagrow)
975 PRINTF ((
">>>>>>>>>>>>>>>>> pivrow %d k %d off-diagonal\n",
977 if (Pinv [diagrow] < 0)
983 kbar = FLIP (Pinv [pivrow]) ;
985 Pinv [diagrow] = FLIP (kbar) ;
992 for (i = 0 ; i < n ; i++) { ASSERT (IS_ZERO (X [i])) ;}
993 GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, len) ;
994 for (p = 0 ; p < len ; p++)
996 PRINTF ((
"Column %d of U: %d : ", k, Ui [p])) ;
997 PRINT_ENTRY (Ux [p]) ;
999 GET_POINTER (LU, Lip, Llen, Li, Lx, k, len) ;
1000 for (p = 0 ; p < len ; p++)
1002 PRINTF ((
"Column %d of L: %d : ", k, Li [p])) ;
1003 PRINT_ENTRY (Lx [p]) ;
1011 prune<Entry> (Lpend, Pinv, k, pivrow, LU, Uip, Lip, Ulen, Llen) ;
1013 *lnz += Llen [k] + 1 ;
1014 *unz += Ulen [k] + 1 ;
1021 for (p = 0 ; p < n ; p++)
1023 Li = (Int *) (LU + Lip [p]) ;
1024 for (i = 0 ; i < Llen [p] ; i++)
1026 Li [i] = Pinv [Li [i]] ;
1031 for (i = 0 ; i < n ; i++)
1033 PRINTF ((
"P [%d] = %d Pinv [%d] = %d\n", i, P [i], i, Pinv [i])) ;
1035 for (i = 0 ; i < n ; i++)
1037 ASSERT (Pinv [i] >= 0 && Pinv [i] < n) ;
1038 ASSERT (P [i] >= 0 && P [i] < n) ;
1039 ASSERT (P [Pinv [i]] == i) ;
1040 ASSERT (IS_ZERO (X [i])) ;
1049 ASSERT ((
size_t) newlusize <= lusize) ;
1052 LU = (Unit *) KLU_realloc (newlusize, lusize,
sizeof (Unit), LU, Common) ;
1054 return (newlusize) ;
void scale(ArrayView< Scalar1 > vals, size_t l, size_t ld, ArrayView< Scalar2 > s)
Scales a 1-D representation of a multivector.