18 #ifndef KLU2_KERNEL_HPP
19 #define KLU2_KERNEL_HPP
21 #include "klu2_internal.h"
22 #include "klu2_memory.hpp"
30 template <
typename Int>
56 Int i, pos, jnew, head, l_length ;
63 ASSERT (Flag [j] != k) ;
69 ASSERT (jnew >= 0 && jnew < k) ;
75 PRINTF ((
"[ start dfs at %d : new %d\n", j, jnew)) ;
78 (Lpend [jnew] == AMESOS2_KLU2_EMPTY) ? Llen [jnew] : Lpend [jnew] ;
83 Li = (Int *) (LU + Lip [jnew]) ;
84 for (pos = --Ap_pos [head] ; pos >= 0 ; --pos)
120 PRINTF ((
" end dfs at %d ] head : %d\n", j, head)) ;
124 *plength = l_length ;
135 template <
typename Int>
136 static Int lsolve_symbolic
171 Int i, p, pend, oldcol, kglobal, top, l_length ;
175 Lik = (Int *) (LU + lup);
182 oldcol = Q [kglobal] ;
183 pend = Ap [oldcol+1] ;
184 for (p = Ap [oldcol] ; p < pend ; p++)
186 i = PSinv [Ai [p]] - k1 ;
187 if (i < 0) continue ;
190 PRINTF ((
"\n ===== DFS at node %d in b, inew: %d\n", i, Pinv [i])) ;
195 top = dfs (i, k, Pinv, Llen, Lip, Stack, Flag,
196 Lpend, top, LU, Lik, &l_length, Ap_pos) ;
209 Llen [k] = l_length ;
222 template <
typename Entry,
typename Int>
223 static void construct_column
250 Int i, p, pend, oldcol, kglobal, poff, oldrow ;
257 poff = Offp [kglobal] ;
258 oldcol = Q [kglobal] ;
259 pend = Ap [oldcol+1] ;
264 for (p = Ap [oldcol] ; p < pend ; p++)
267 i = PSinv [oldrow] - k1 ;
272 Offi [poff] = oldrow ;
286 for (p = Ap [oldcol] ; p < pend ; p++)
289 i = PSinv [oldrow] - k1 ;
291 SCALE_DIV (aik, Rs [oldrow]) ;
295 Offi [poff] = oldrow ;
307 Offp [kglobal+1] = poff ;
320 template <
typename Entry,
typename Int>
321 static void lsolve_numeric
343 Int p, s, j, jnew, len ;
346 for (s = top ; s < n ; s++)
353 GET_POINTER (LU, Lip, Llen, Li, Lx, jnew, len) ;
354 ASSERT (Lip [jnew] <= Lip [jnew+1]) ;
355 for (p = 0 ; p < len ; p++)
358 MULT_SUB (X [Li [p]], Lx [p], xj) ;
370 template <
typename Entry,
typename Int>
389 KLU_common<Entry, Int> *Common
392 Entry x, pivot, *Lx ;
393 double abs_pivot, xabs ;
394 Int p, i, ppivrow, pdiag, pivrow, *Li, last_row_index, firstrow, len ;
396 pivrow = AMESOS2_KLU2_EMPTY ;
400 if (Common->halt_if_singular)
404 for (firstrow = *p_firstrow ; firstrow < n ; firstrow++)
406 PRINTF ((
"check %d\n", firstrow)) ;
407 if (Pinv [firstrow] < 0)
411 PRINTF ((
"Got pivotal row: %d\n", pivrow)) ;
415 ASSERT (pivrow >= 0 && pivrow < n) ;
420 *p_firstrow = firstrow ;
424 pdiag = AMESOS2_KLU2_EMPTY ;
425 ppivrow = AMESOS2_KLU2_EMPTY ;
426 abs_pivot = AMESOS2_KLU2_EMPTY ;
428 GET_POINTER (LU, Lip, Llen, Li, Lx, k, len) ;
429 last_row_index = Li [i] ;
433 GET_POINTER (LU, Lip, Llen, Li, Lx, k, len) ;
436 for (p = 0 ; p < len ; p++)
454 if (xabs > abs_pivot)
462 KLU2_ABS (xabs, X [last_row_index]) ;
463 if (xabs > abs_pivot)
466 ppivrow = AMESOS2_KLU2_EMPTY ;
470 if (last_row_index == diagrow)
472 if (xabs >= tol * abs_pivot)
475 ppivrow = AMESOS2_KLU2_EMPTY ;
478 else if (pdiag != AMESOS2_KLU2_EMPTY)
481 KLU2_ABS (xabs, Lx [pdiag]) ;
482 if (xabs >= tol * abs_pivot)
490 if (ppivrow != AMESOS2_KLU2_EMPTY)
492 pivrow = Li [ppivrow] ;
493 pivot = Lx [ppivrow] ;
495 Li [ppivrow] = last_row_index ;
496 Lx [ppivrow] = X [last_row_index] ;
500 pivrow = last_row_index ;
501 pivot = X [last_row_index] ;
503 CLEAR (X [last_row_index]) ;
507 *p_abs_pivot = abs_pivot ;
508 ASSERT (pivrow >= 0 && pivrow < n) ;
510 if (IS_ZERO (pivot) && Common->halt_if_singular)
517 for (p = 0 ; p < Llen [k] ; p++)
520 DIV (Lx [p], Lx [p], pivot) ;
532 template <
typename Entry,
typename Int>
557 Int p, i, j, p2, phead, ptail, llen, ulen ;
560 GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, ulen) ;
564 for (p = 0 ; p < ulen ; p++)
568 PRINTF ((
"%d is pruned: %d. Lpend[j] %d Lip[j+1] %d\n",
569 j, Lpend [j] != AMESOS2_KLU2_EMPTY, Lpend [j], Lip [j+1])) ;
570 if (Lpend [j] == AMESOS2_KLU2_EMPTY)
573 GET_POINTER (LU, Lip, Llen, Li, Lx, j, llen) ;
574 for (p2 = 0 ; p2 < llen ; p2++)
576 if (pivrow == Li [p2])
580 PRINTF ((
"==== PRUNE: col j %d of L\n", j)) ;
583 for (p3 = 0 ; p3 < Llen [j] ; p3++)
585 PRINTF ((
"before: %i pivotal: %d\n", Li [p3],
586 Pinv [Li [p3]] >= 0)) ;
595 while (phead < ptail)
607 Li [phead] = Li [ptail] ;
610 Lx [phead] = Lx [ptail] ;
626 for (p3 = 0 ; p3 < Llen [j] ; p3++)
628 if (p3 == Lpend [j]) PRINTF ((
"----\n")) ;
629 PRINTF ((
"after: %i pivotal: %d\n", Li [p3],
630 Pinv [Li [p3]] >= 0)) ;
647 template <
typename Entry,
typename Int>
692 KLU_common<Entry, Int> *Common
696 double abs_pivot, xsize, nunits, tol, memgrow ;
700 Int k, p, i, j, pivrow = 0, kbar, diagrow, firstrow, lup, top,
scale, len ;
707 ASSERT (Common != NULL) ;
708 scale = Common->scale ;
710 memgrow = Common->memgrow ;
719 PRINTF ((
"input: lusize %d \n", lusize)) ;
720 ASSERT (lusize > 0) ;
730 for (k = 0 ; k < n ; k++)
734 Flag [k] = AMESOS2_KLU2_EMPTY ;
735 Lpend [k] = AMESOS2_KLU2_EMPTY ;
743 for (k = 0 ; k < n ; k++)
746 Pinv [k] = FLIP (k) ;
757 for (k = 0 ; k < n ; k++)
759 PRINTF ((
"Initial P [%d] = %d\n", k, P [k])) ;
767 for (k = 0 ; k < n ; k++)
770 PRINTF ((
"\n\n==================================== k: %d\n", k)) ;
777 nunits = DUNITS (Int, n - k) + DUNITS (Int, k) +
778 DUNITS (Entry, n - k) + DUNITS (Entry, k) ;
781 PRINTF ((
"lup %d lusize %g lup+nunits: %g\n", lup, (
double) lusize,
783 xsize = ((double) lup) + nunits ;
784 if (xsize > (
double) lusize)
787 xsize = (memgrow * ((double) lusize) + 4*n + 1) ;
788 if (INT_OVERFLOW (xsize))
790 PRINTF ((
"Matrix is too large (Int overflow)\n")) ;
791 Common->status = KLU_TOO_LARGE ;
794 newlusize = (size_t) (memgrow * lusize + 2*n + 1) ;
796 LU = (Unit *) KLU_realloc (newlusize, lusize,
sizeof (Unit), LU, Common) ;
799 if (Common->status == KLU_OUT_OF_MEMORY)
801 PRINTF ((
"Matrix is too large (LU)\n")) ;
805 PRINTF ((
"inc LU to %d done\n", lusize)) ;
819 for (i = 0 ; i < n ; i++)
821 ASSERT (Flag [i] < k) ;
823 ASSERT (IS_ZERO (X [i])) ;
827 top = lsolve_symbolic (n, k, Ap, Ai, Q, Pinv, Stack, Flag,
828 Lpend, Ap_pos, LU, lup, Llen, Lip, k1, PSinv) ;
831 PRINTF ((
"--- in U:\n")) ;
832 for (p = top ; p < n ; p++)
834 PRINTF ((
"pattern of X for U: %d : %d pivot row: %d\n",
835 p, Stack [p], Pinv [Stack [p]])) ;
836 ASSERT (Flag [Stack [p]] == k) ;
838 PRINTF ((
"--- in L:\n")) ;
839 Li = (Int *) (LU + Lip [k]);
840 for (p = 0 ; p < Llen [k] ; p++)
842 PRINTF ((
"pattern of X in L: %d : %d pivot row: %d\n",
843 p, Li [p], Pinv [Li [p]])) ;
844 ASSERT (Flag [Li [p]] == k) ;
847 for (i = 0 ; i < n ; i++)
849 ASSERT (Flag [i] <= k) ;
850 if (Flag [i] == k) p++ ;
858 construct_column <Entry> (k,
Ap,
Ai, Ax, Q, X,
859 k1, PSinv, Rs,
scale, Offp, Offi, Offx) ;
865 lsolve_numeric <Entry> (Pinv, LU, Stack, Lip, top, n, Llen, X) ;
868 for (p = top ; p < n ; p++)
870 PRINTF ((
"X for U %d : ", Stack [p])) ;
871 PRINT_ENTRY (X [Stack [p]]) ;
873 Li = (Int *) (LU + Lip [k]) ;
874 for (p = 0 ; p < Llen [k] ; p++)
876 PRINTF ((
"X for L %d : ", Li [p])) ;
877 PRINT_ENTRY (X [Li [p]]) ;
887 PRINTF ((
"k %d, diagrow = %d, UNFLIP (diagrow) = %d\n",
888 k, diagrow, UNFLIP (diagrow))) ;
891 if (!lpivot <Entry> (diagrow, &pivrow, &pivot, &abs_pivot, tol, X, LU, Lip,
892 Llen, k, n, Pinv, &firstrow, Common))
895 Common->status = KLU_SINGULAR ;
896 if (Common->numerical_rank == AMESOS2_KLU2_EMPTY)
898 Common->numerical_rank = k+k1 ;
899 Common->singular_col = Q [k+k1] ;
901 if (Common->halt_if_singular)
910 PRINTF ((
"\nk %d : Pivot row %d : ", k, pivrow)) ;
911 PRINT_ENTRY (pivot) ;
912 ASSERT (pivrow >= 0 && pivrow < n) ;
913 ASSERT (Pinv [pivrow] < 0) ;
916 Uip [k] = Lip [k] + UNITS (Int, Llen [k]) + UNITS (Entry, Llen [k]) ;
920 lup += UNITS (Int, Llen [k]) + UNITS (Entry, Llen [k]) ;
925 GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, len) ;
926 for (p = top, i = 0 ; p < n ; p++, i++)
935 lup += UNITS (Int, Ulen [k]) + UNITS (Entry, Ulen [k]) ;
944 ASSERT (UNFLIP (Pinv [diagrow]) < n) ;
945 ASSERT (P [UNFLIP (Pinv [diagrow])] == diagrow) ;
947 if (pivrow != diagrow)
951 PRINTF ((
">>>>>>>>>>>>>>>>> pivrow %d k %d off-diagonal\n",
953 if (Pinv [diagrow] < 0)
959 kbar = FLIP (Pinv [pivrow]) ;
961 Pinv [diagrow] = FLIP (kbar) ;
968 for (i = 0 ; i < n ; i++) { ASSERT (IS_ZERO (X [i])) ;}
969 GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, len) ;
970 for (p = 0 ; p < len ; p++)
972 PRINTF ((
"Column %d of U: %d : ", k, Ui [p])) ;
973 PRINT_ENTRY (Ux [p]) ;
975 GET_POINTER (LU, Lip, Llen, Li, Lx, k, len) ;
976 for (p = 0 ; p < len ; p++)
978 PRINTF ((
"Column %d of L: %d : ", k, Li [p])) ;
979 PRINT_ENTRY (Lx [p]) ;
987 prune<Entry> (Lpend, Pinv, k, pivrow, LU, Uip, Lip, Ulen, Llen) ;
989 *lnz += Llen [k] + 1 ;
990 *unz += Ulen [k] + 1 ;
997 for (p = 0 ; p < n ; p++)
999 Li = (Int *) (LU + Lip [p]) ;
1000 for (i = 0 ; i < Llen [p] ; i++)
1002 Li [i] = Pinv [Li [i]] ;
1007 for (i = 0 ; i < n ; i++)
1009 PRINTF ((
"P [%d] = %d Pinv [%d] = %d\n", i, P [i], i, Pinv [i])) ;
1011 for (i = 0 ; i < n ; i++)
1013 ASSERT (Pinv [i] >= 0 && Pinv [i] < n) ;
1014 ASSERT (P [i] >= 0 && P [i] < n) ;
1015 ASSERT (P [Pinv [i]] == i) ;
1016 ASSERT (IS_ZERO (X [i])) ;
1025 ASSERT ((
size_t) newlusize <= lusize) ;
1028 LU = (Unit *) KLU_realloc (newlusize, lusize,
sizeof (Unit), LU, Common) ;
1030 return (newlusize) ;
void scale(ArrayView< Scalar1 > vals, size_t l, size_t ld, ArrayView< Scalar2 > s)
Scales a 1-D representation of a multivector.
int Ap[]
Column offsets.
Definition: klu2_simple.cpp:52
int Ai[]
Row values.
Definition: klu2_simple.cpp:54