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.