22 #ifndef KLU2_DIAGNOSTICS_HPP
23 #define KLU2_DIAGNOSTICS_HPP
25 #include "klu2_internal.h"
26 #include "klu2_tsolve.hpp"
37 template <
typename Entry,
typename Int>
43 KLU_symbolic<Entry, Int> *Symbolic,
44 KLU_numeric<Entry, Int> *Numeric,
45 KLU_common<Entry, Int> *Common
48 double temp, max_ai, max_ui, min_block_rgrowth ;
50 Int *Q, *Ui, *Uip, *Ulen, *Pinv ;
52 Entry *Aentry, *Ux, *Ukk ;
54 Int i, newrow, oldrow, k1, k2, nk, j, oldcol, k, pend, len ;
65 if (Symbolic == NULL ||
Ap == NULL ||
Ai == NULL || Ax == NULL)
67 Common->status = KLU_INVALID ;
75 Common->status = KLU_SINGULAR ;
78 Common->status = KLU_OK ;
84 Aentry = (Entry *) Ax ;
85 Pinv = Numeric->Pinv ;
90 for (i = 0 ; i < Symbolic->nblocks ; i++)
93 k2 = Symbolic->R[i+1] ;
99 LU = (Unit *) Numeric->LUbx[i] ;
100 Uip = Numeric->Uip + k1 ;
101 Ulen = Numeric->Ulen + k1 ;
102 Ukk = ((Entry *) Numeric->Udiag) + k1 ;
103 min_block_rgrowth = 1 ;
104 for (j = 0 ; j < nk ; j++)
109 pend =
Ap [oldcol + 1] ;
110 for (k =
Ap [oldcol] ; k < pend ; k++)
113 newrow = Pinv [oldrow] ;
118 ASSERT (newrow < k2) ;
122 SCALE_DIV_ASSIGN (aik, Aentry [k], Rs [newrow]) ;
129 KLU2_ABS (temp, aik) ;
136 GET_POINTER (LU, Uip, Ulen, Ui, Ux, j, len) ;
137 for (k = 0 ; k < len ; k++)
140 KLU2_ABS (temp, Ux [k]) ;
147 KLU2_ABS (temp, Ukk [j]) ;
154 if (SCALAR_IS_ZERO (max_ui))
158 temp = max_ai / max_ui ;
159 if (temp < min_block_rgrowth)
161 min_block_rgrowth = temp ;
165 if (min_block_rgrowth < Common->rgrowth)
167 Common->rgrowth = min_block_rgrowth ;
183 template <
typename Entry,
typename Int>
188 KLU_symbolic<Entry, Int> *Symbolic,
189 KLU_numeric<Entry, Int> *Numeric,
190 KLU_common<Entry, Int> *Common
193 double xj, Xmax, csum, anorm, ainv_norm, est_old, est_new, abs_value ;
194 Entry *Udiag, *Aentry, *X, *S ;
196 Int nblocks, i, j, jmax, jnew, pend, n ;
209 if (Symbolic == NULL || Ap == NULL || Ax == NULL)
211 Common->status = KLU_INVALID ;
218 Common->condest = 1 / abs_value ;
219 Common->status = KLU_SINGULAR ;
222 Common->status = KLU_OK ;
229 nblocks = Symbolic->nblocks ;
231 Udiag = (Entry *) Numeric->Udiag ;
237 for (i = 0 ; i < n ; i++)
239 KLU2_ABS (abs_value, Udiag [i]) ;
240 if (SCALAR_IS_ZERO (abs_value))
242 Common->condest = 1 / abs_value ;
243 Common->status = KLU_SINGULAR ;
253 Aentry = (Entry *) Ax ;
254 for (i = 0 ; i < n ; i++)
258 for (j = Ap [i] ; j < pend ; j++)
260 KLU2_ABS (abs_value, Aentry [j]) ;
274 X = (Entry *) Numeric->Xwork ;
278 for (i = 0 ; i < n ; i++)
284 X [i] = 1.0 / ((double) n) ;
289 for (i = 0 ; i < 5 ; i++)
294 for (j = 0 ; j < n ; j++)
304 KLU_solve (Symbolic, Numeric, n, 1, (
double *) X, Common) ;
305 est_old = ainv_norm ;
308 for (j = 0 ; j < n ; j++)
311 KLU2_ABS (abs_value, X [j]) ;
312 ainv_norm += abs_value ;
318 for (j = 0 ; j < n ; j++)
320 double s = (X [j] >= 0) ? 1 : -1 ;
321 if (s != (Int) REAL (S [j]))
328 if (i > 0 && (ainv_norm <= est_old || unchanged))
333 for (j = 0 ; j < n ; j++)
335 if (IS_NONZERO (X [j]))
337 KLU2_ABS (abs_value, X [j]) ;
338 SCALE_DIV_ASSIGN (S [j], X [j], abs_value) ;
349 if (i > 0 && ainv_norm <= est_old)
355 for (j = 0 ; j < n ; j++)
362 KLU_tsolve (Symbolic, Numeric, n, 1, X, Common) ;
365 KLU_tsolve (Symbolic, Numeric, n, 1, (
double *) X, 1, Common) ;
371 for (j = 0 ; j < n ; j++)
374 KLU2_ABS (xj, X [j]) ;
381 if (i > 0 && jnew == jmax)
394 for (j = 0 ; j < n ; j++)
401 X [j] = 1 + ((double) j) / ((double) (n-1)) ;
407 X [j] = -1 - ((double) j) / ((double) (n-1)) ;
411 KLU_solve (Symbolic, Numeric, n, 1, (
double *) X, Common) ;
414 for (j = 0 ; j < n ; j++)
417 KLU2_ABS (abs_value, X [j]) ;
418 est_new += abs_value ;
420 est_new = 2 * est_new / (3 * n) ;
421 ainv_norm = MAX (est_new, ainv_norm) ;
427 Common->condest = ainv_norm * anorm ;
438 template <
typename Entry,
typename Int>
441 KLU_symbolic<Entry, Int> *Symbolic,
442 KLU_numeric<Entry, Int> *Numeric,
443 KLU_common<Entry, Int> *Common
447 Int *R, *Ui, *Uip, *Llen, *Ulen ;
450 Int k, ulen, p, n, nk, block, nblocks, k1 ;
460 Common->flops = AMESOS2_KLU2_EMPTY ;
461 if (Numeric == NULL || Symbolic == NULL)
463 Common->status = KLU_INVALID ;
466 Common->status = KLU_OK ;
474 nblocks = Symbolic->nblocks ;
480 LUbx = (Unit **) Numeric->LUbx ;
486 for (block = 0 ; block < nblocks ; block++)
489 nk = R [block+1] - k1 ;
492 Llen = Numeric->Llen + k1 ;
493 Uip = Numeric->Uip + k1 ;
494 Ulen = Numeric->Ulen + k1 ;
496 for (k = 0 ; k < nk ; k++)
499 GET_I_POINTER (LU, Uip, Ui, k) ;
501 for (p = 0 ; p < ulen ; p++)
503 flops += 2 * Llen [Ui [p]] ;
510 Common->flops = flops ;
524 template <
typename Entry,
typename Int>
527 KLU_symbolic<Entry, Int> *Symbolic,
528 KLU_numeric<Entry, Int> *Numeric,
529 KLU_common<Entry, Int> *Common
532 double ukk, umin = 0, umax = 0 ;
544 if (Symbolic == NULL)
546 Common->status = KLU_INVALID ;
552 Common->status = KLU_SINGULAR ;
555 Common->status = KLU_OK ;
562 Udiag = (Entry *) Numeric->Udiag ;
563 for (j = 0 ; j < n ; j++)
566 KLU2_ABS (ukk, Udiag [j]) ;
567 if (SCALAR_IS_NAN (ukk) || SCALAR_IS_ZERO (ukk))
571 Common->status = KLU_SINGULAR ;
583 umin = MIN (umin, ukk) ;
584 umax = MAX (umax, ukk) ;
588 Common->rcond = umin / umax ;
589 if (SCALAR_IS_NAN (Common->rcond) || SCALAR_IS_ZERO (Common->rcond))
593 Common->status = KLU_SINGULAR ;
int Ap[]
Column offsets.
Definition: klu2_simple.cpp:52
int Ai[]
Row values.
Definition: klu2_simple.cpp:54