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 ;