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