46 #ifndef KLU2_DIAGNOSTICS_HPP 
   47 #define KLU2_DIAGNOSTICS_HPP 
   49 #include "klu2_internal.h" 
   50 #include "klu2_tsolve.hpp" 
   61 template <
typename Entry, 
typename Int>
 
   67     KLU_symbolic<Entry, Int> *Symbolic,
 
   68     KLU_numeric<Entry, Int> *Numeric,
 
   69     KLU_common<Entry, Int> *Common
 
   72     double temp, max_ai, max_ui, min_block_rgrowth ;
 
   74     Int *Q, *Ui, *Uip, *Ulen, *Pinv ;
 
   76     Entry *Aentry, *Ux, *Ukk ;
 
   78     Int i, newrow, oldrow, k1, k2, nk, j, oldcol, k, pend, len ;
 
   89     if (Symbolic == NULL || Ap == NULL || Ai == NULL || Ax == NULL)
 
   91         Common->status = KLU_INVALID ;
 
   99         Common->status = KLU_SINGULAR ;
 
  102     Common->status = KLU_OK ;
 
  108     Aentry = (Entry *) Ax ;
 
  109     Pinv = Numeric->Pinv ;
 
  112     Common->rgrowth = 1 ;
 
  114     for (i = 0 ; i < Symbolic->nblocks ; i++)
 
  116         k1 = Symbolic->R[i] ;
 
  117         k2 = Symbolic->R[i+1] ;
 
  123         LU = (Unit *) Numeric->LUbx[i] ;
 
  124         Uip = Numeric->Uip + k1 ;
 
  125         Ulen = Numeric->Ulen + k1 ;
 
  126         Ukk = ((Entry *) Numeric->Udiag) + k1 ;
 
  127         min_block_rgrowth = 1 ;
 
  128         for (j = 0 ; j < nk ; j++)
 
  133             pend = Ap [oldcol + 1] ;
 
  134             for (k = Ap [oldcol] ; k < pend ; k++)
 
  137                 newrow = Pinv [oldrow] ;
 
  142                 ASSERT (newrow < k2) ;
 
  146                     SCALE_DIV_ASSIGN (aik, Aentry [k], Rs [newrow]) ;
 
  153                 KLU2_ABS (temp, aik) ;
 
  160             GET_POINTER (LU, Uip, Ulen, Ui, Ux, j, len) ;
 
  161             for (k = 0 ; k < len ; k++)
 
  164                 KLU2_ABS (temp, Ux [k]) ;
 
  171             KLU2_ABS (temp, Ukk [j]) ;
 
  178             if (SCALAR_IS_ZERO (max_ui))
 
  182             temp = max_ai / max_ui ;
 
  183             if (temp < min_block_rgrowth)
 
  185                 min_block_rgrowth = temp ;
 
  189         if (min_block_rgrowth < Common->rgrowth)
 
  191             Common->rgrowth = min_block_rgrowth ;
 
  207 template <
typename Entry, 
typename Int>
 
  212     KLU_symbolic<Entry, Int> *Symbolic,
 
  213     KLU_numeric<Entry, Int> *Numeric,
 
  214     KLU_common<Entry, Int> *Common
 
  217     double xj, Xmax, csum, anorm, ainv_norm, est_old, est_new, abs_value ;
 
  218     Entry *Udiag, *Aentry, *X, *S ;
 
  220     Int nblocks, i, j, jmax, jnew, pend, n ;
 
  233     if (Symbolic == NULL || Ap == NULL || Ax == NULL)
 
  235         Common->status = KLU_INVALID ;
 
  242         Common->condest = 1 / abs_value ;
 
  243         Common->status = KLU_SINGULAR ;
 
  246     Common->status = KLU_OK ;
 
  253     nblocks = Symbolic->nblocks ;
 
  255     Udiag = (Entry *) Numeric->Udiag ;
 
  261     for (i = 0 ; i < n ; i++)
 
  263         KLU2_ABS (abs_value, Udiag [i]) ;
 
  264         if (SCALAR_IS_ZERO (abs_value))
 
  266             Common->condest = 1 / abs_value ;
 
  267             Common->status = KLU_SINGULAR ;
 
  277     Aentry = (Entry *) Ax ;
 
  278     for (i = 0 ; i < n ; i++)
 
  282         for (j = Ap [i] ; j < pend ; j++)
 
  284             KLU2_ABS (abs_value, Aentry [j]) ;
 
  298     X = (Entry *) Numeric->Xwork ;  
 
  302     for (i = 0 ; i < n ; i++)
 
  308         X [i] = 1.0 / ((double) n) ;
 
  313     for (i = 0 ; i < 5 ; i++)
 
  318             for (j = 0 ; j < n ; j++)
 
  328         KLU_solve (Symbolic, Numeric, n, 1, (
double *) X, Common) ;
 
  329         est_old = ainv_norm ;
 
  332         for (j = 0 ; j < n ; j++)
 
  335             KLU2_ABS (abs_value, X [j]) ;
 
  336             ainv_norm += abs_value ;
 
  342         for (j = 0 ; j < n ; j++)
 
  344             double s = (X [j] >= 0) ? 1 : -1 ;
 
  345             if (s != (Int) REAL (S [j]))
 
  352         if (i > 0 && (ainv_norm <= est_old || unchanged))
 
  357         for (j = 0 ; j < n ; j++)
 
  359             if (IS_NONZERO (X [j]))
 
  361                 KLU2_ABS (abs_value, X [j]) ;
 
  362                 SCALE_DIV_ASSIGN (S [j], X [j], abs_value) ;
 
  373         if (i > 0 && ainv_norm <= est_old)
 
  379         for (j = 0 ; j < n ; j++)
 
  386         KLU_tsolve (Symbolic, Numeric, n, 1, X, Common) ;
 
  389         KLU_tsolve (Symbolic, Numeric, n, 1, (
double *) X, 1, Common) ;
 
  395         for (j = 0 ; j < n ; j++)
 
  398             KLU2_ABS (xj, X [j]) ;
 
  405         if (i > 0 && jnew == jmax)
 
  418     for (j = 0 ; j < n ; j++)
 
  425             X [j] = 1 + ((double) j) / ((double) (n-1)) ;
 
  431             X [j] = -1 - ((double) j) / ((double) (n-1)) ;
 
  435     KLU_solve (Symbolic, Numeric, n, 1, (
double *) X, Common) ;
 
  438     for (j = 0 ; j < n ; j++)
 
  441         KLU2_ABS (abs_value, X [j]) ;
 
  442         est_new += abs_value ;
 
  444     est_new = 2 * est_new / (3 * n) ;
 
  445     ainv_norm = MAX (est_new, ainv_norm) ;
 
  451     Common->condest = ainv_norm * anorm ;
 
  462 template <
typename Entry, 
typename Int>
 
  465     KLU_symbolic<Entry, Int> *Symbolic,
 
  466     KLU_numeric<Entry, Int> *Numeric,
 
  467     KLU_common<Entry, Int> *Common
 
  471     Int *R, *Ui, *Uip, *Llen, *Ulen ;
 
  474     Int k, ulen, p, n, nk, block, nblocks, k1 ;
 
  484     Common->flops = EMPTY ;
 
  485     if (Numeric == NULL || Symbolic == NULL)
 
  487         Common->status = KLU_INVALID ;
 
  490     Common->status = KLU_OK ;
 
  498     nblocks = Symbolic->nblocks ;
 
  504     LUbx = (Unit **) Numeric->LUbx ;
 
  510     for (block = 0 ; block < nblocks ; block++)
 
  513         nk = R [block+1] - k1 ;
 
  516             Llen = Numeric->Llen + k1 ;
 
  517             Uip  = Numeric->Uip  + k1 ;
 
  518             Ulen = Numeric->Ulen + k1 ;
 
  520             for (k = 0 ; k < nk ; k++)
 
  523                 GET_I_POINTER (LU, Uip, Ui, k) ;
 
  525                 for (p = 0 ; p < ulen ; p++)
 
  527                     flops += 2 * Llen [Ui [p]] ;
 
  534     Common->flops = flops ;
 
  548 template <
typename Entry, 
typename Int>
 
  551     KLU_symbolic<Entry, Int> *Symbolic,     
 
  552     KLU_numeric<Entry, Int> *Numeric,       
 
  553     KLU_common<Entry, Int> *Common          
 
  556     double ukk, umin = 0, umax = 0 ;
 
  568     if (Symbolic == NULL)
 
  570         Common->status = KLU_INVALID ;
 
  576         Common->status = KLU_SINGULAR ;
 
  579     Common->status = KLU_OK ;
 
  586     Udiag = (Entry *) Numeric->Udiag ;
 
  587     for (j = 0 ; j < n ; j++)
 
  590         KLU2_ABS (ukk, Udiag [j]) ;
 
  591         if (SCALAR_IS_NAN (ukk) || SCALAR_IS_ZERO (ukk))
 
  595             Common->status = KLU_SINGULAR ;
 
  607             umin = MIN (umin, ukk) ;
 
  608             umax = MAX (umax, ukk) ;
 
  612     Common->rcond = umin / umax ;
 
  613     if (SCALAR_IS_NAN (Common->rcond) || SCALAR_IS_ZERO (Common->rcond))
 
  617         Common->status = KLU_SINGULAR ;