41 #ifndef KLU2_FACTOR_HPP
42 #define KLU2_FACTOR_HPP
44 #include "klu2_internal.h"
46 #include "klu2_memory.hpp"
47 #include "klu2_scale.hpp"
54 template <
typename Entry,
typename Int>
61 KLU_symbolic<Entry, Int> *Symbolic,
64 KLU_numeric<Entry, Int> *Numeric,
65 KLU_common<Entry, Int> *Common
70 Int *P, *Q, *R, *Pnum, *Offp, *Offi, *Pblock, *Pinv, *Iwork,
71 *Lip, *Uip, *Llen, *Ulen ;
72 Entry *Offx, *X, s, *Udiag ;
74 Int k1, k2, nk, k, block, oldcol, pend, oldrow, n, lnz, unz, p, newrow,
75 nblocks, poff, nzoff, lnz_block, unz_block,
scale, max_lnz_block,
88 nblocks = Symbolic->nblocks ;
89 nzoff = Symbolic->nzoff ;
91 Pnum = Numeric->Pnum ;
92 Offp = Numeric->Offp ;
93 Offi = Numeric->Offi ;
94 Offx = (Entry *) Numeric->Offx ;
98 Llen = Numeric->Llen ;
99 Ulen = Numeric->Ulen ;
100 LUbx = (Unit **) Numeric->LUbx ;
101 Udiag = (Entry *) Numeric->Udiag ;
104 Pinv = Numeric->Pinv ;
105 X = (Entry *) Numeric->Xwork ;
106 Iwork = Numeric->Iwork ;
108 Pblock = Iwork + 5*((size_t) Symbolic->maxblock) ;
109 Common->nrealloc = 0 ;
110 scale = Common->scale ;
118 for (k = 0 ; k < n ; k++)
123 for (k = 0 ; k < n ; k++)
125 ASSERT (P [k] >= 0 && P [k] < n) ;
129 for (k = 0 ; k < n ; k++) ASSERT (Pinv [k] != EMPTY) ;
134 Common->noffdiag = 0 ;
151 KLU_scale (
scale, n, Ap, Ai, Ax, Rs, Pnum, Common) ;
152 if (Common->status < KLU_OK)
162 for (k = 0 ; k < n ; k++) PRINTF ((
"Rs [%d] %g\n", k, Rs [k])) ;
170 for (block = 0 ; block < nblocks ; block++)
180 PRINTF ((
"FACTOR BLOCK %d, k1 %d k2-1 %d nk %d\n", block, k1,k2-1,nk)) ;
191 pend = Ap [oldcol+1] ;
197 for (p = Ap [oldcol] ; p < pend ; p++)
200 newrow = Pinv [oldrow] ;
203 Offi [poff] = oldrow ;
204 Offx [poff] = Ax [p] ;
209 ASSERT (newrow == k1) ;
210 PRINTF ((
"singleton block %d", block)) ;
211 PRINT_ENTRY (Ax [p]) ;
223 for (p = Ap [oldcol] ; p < pend ; p++)
226 newrow = Pinv [oldrow] ;
229 Offi [poff] = oldrow ;
231 SCALE_DIV_ASSIGN (Offx [poff], Ax [p], Rs [oldrow]) ;
236 ASSERT (newrow == k1) ;
237 PRINTF ((
"singleton block %d ", block)) ;
238 PRINT_ENTRY (Ax[p]) ;
239 SCALE_DIV_ASSIGN (s, Ax [p], Rs [oldrow]) ;
249 Common->status = KLU_SINGULAR ;
250 Common->numerical_rank = k1 ;
251 Common->singular_col = oldcol ;
252 if (Common->halt_if_singular)
275 lsize = -(Common->initmem) ;
279 lsize = Common->initmem_amd * Lnz [block] + nk ;
283 Numeric->LUsize [block] = KLU_kernel_factor (nk, Ap, Ai, Ax, Q,
284 lsize, &LUbx [block], Udiag + k1, Llen + k1, Ulen + k1,
285 Lip + k1, Uip + k1, Pblock, &lnz_block, &unz_block,
286 X, Iwork, k1, Pinv, Rs, Offp, Offi, Offx, Common) ;
288 if (Common->status < KLU_OK ||
289 (Common->status == KLU_SINGULAR && Common->halt_if_singular))
295 PRINTF ((
"\n----------------------- L %d:\n", block)) ;
296 ASSERT (KLU_valid_LU (nk, TRUE, Lip+k1, Llen+k1, LUbx [block])) ;
297 PRINTF ((
"\n----------------------- U %d:\n", block)) ;
298 ASSERT (KLU_valid_LU (nk, FALSE, Uip+k1, Ulen+k1, LUbx [block])) ;
306 max_lnz_block = MAX (max_lnz_block, lnz_block) ;
307 max_unz_block = MAX (max_unz_block, unz_block) ;
309 if (Lnz [block] == EMPTY)
312 Lnz [block] = MAX (lnz_block, unz_block) ;
319 PRINTF ((
"Pnum, 1-based:\n")) ;
320 for (k = 0 ; k < nk ; k++)
322 ASSERT (k + k1 < n) ;
323 ASSERT (Pblock [k] + k1 < n) ;
324 Pnum [k + k1] = P [Pblock [k] + k1] ;
325 PRINTF ((
"Pnum (%d + %d + 1 = %d) = %d + 1 = %d\n",
326 k, k1, k+k1+1, Pnum [k+k1], Pnum [k+k1]+1)) ;
332 ASSERT (nzoff == Offp [n]) ;
333 PRINTF ((
"\n------------------- Off diagonal entries:\n")) ;
334 ASSERT (KLU_valid (n, Offp, Offi, Offx)) ;
338 Numeric->max_lnz_block = max_lnz_block ;
339 Numeric->max_unz_block = max_unz_block ;
343 for (k = 0 ; k < n ; k++)
348 for (k = 0 ; k < n ; k++)
350 ASSERT (Pnum [k] >= 0 && Pnum [k] < n) ;
351 Pinv [Pnum [k]] = k ;
354 for (k = 0 ; k < n ; k++) ASSERT (Pinv [k] != EMPTY) ;
360 for (k = 0 ; k < n ; k++)
364 X [k] = Rs [Pnum [k]] ;
366 for (k = 0 ; k < n ; k++)
368 Rs [k] = REAL (X [k]) ;
372 PRINTF ((
"\n------------------- Off diagonal entries, old:\n")) ;
373 ASSERT (KLU_valid (n, Offp, Offi, Offx)) ;
376 for (p = 0 ; p < nzoff ; p++)
378 ASSERT (Offi [p] >= 0 && Offi [p] < n) ;
379 Offi [p] = Pinv [Offi [p]] ;
382 PRINTF ((
"\n------------------- Off diagonal entries, new:\n")) ;
383 ASSERT (KLU_valid (n, Offp, Offi, Offx)) ;
387 PRINTF ((
"\n ############# KLU_BTF_FACTOR done, nblocks %d\n",nblocks));
388 Entry ss, *Udiag = Numeric->Udiag ;
389 for (block = 0 ; block < nblocks && Common->status == KLU_OK ; block++)
394 PRINTF ((
"\n======================KLU_factor output: k1 %d k2 %d nk %d\n",k1,k2,nk)) ;
397 PRINTF ((
"singleton ")) ;
404 Int *Lip, *Uip, *Llen, *Ulen ;
406 Lip = Numeric->Lip + k1 ;
407 Llen = Numeric->Llen + k1 ;
408 LU = (Unit *) Numeric->LUbx [block] ;
409 PRINTF ((
"\n---- L block %d\n", block));
410 ASSERT (KLU_valid_LU (nk, TRUE, Lip, Llen, LU)) ;
411 Uip = Numeric->Uip + k1 ;
412 Ulen = Numeric->Ulen + k1 ;
413 PRINTF ((
"\n---- U block %d\n", block)) ;
414 ASSERT (KLU_valid_LU (nk, FALSE, Uip, Ulen, LU)) ;
427 template <
typename Entry,
typename Int>
428 KLU_numeric<Entry, Int> *KLU_factor
436 KLU_symbolic<Entry, Int> *Symbolic,
438 KLU_common<Entry, Int> *Common
441 Int n, nzoff, nblocks, maxblock, k, ok = TRUE ;
443 KLU_numeric<Entry, Int> *Numeric ;
444 size_t n1, nzoff1, s, b6, n3 ;
450 Common->status = KLU_OK ;
451 Common->numerical_rank = EMPTY ;
452 Common->singular_col = EMPTY ;
459 if (Symbolic == NULL)
461 Common->status = KLU_INVALID ;
466 nzoff = Symbolic->nzoff ;
467 nblocks = Symbolic->nblocks ;
468 maxblock = Symbolic->maxblock ;
470 PRINTF ((
"KLU_factor: n %d nzoff %d nblocks %d maxblock %d\n",
471 n, nzoff, nblocks, maxblock)) ;
477 Common->initmem_amd = MAX (1.0, Common->initmem_amd) ;
478 Common->initmem = MAX (1.0, Common->initmem) ;
479 Common->tol = MIN (Common->tol, 1.0) ;
480 Common->tol = MAX (0.0, Common->tol) ;
481 Common->memgrow = MAX (1.0, Common->memgrow) ;
488 n1 = ((size_t) n) + 1 ;
489 nzoff1 = ((size_t) nzoff) + 1 ;
491 Numeric = (KLU_numeric<Entry, Int> *) KLU_malloc (
sizeof (KLU_numeric<Entry, Int>), 1, Common) ;
492 if (Common->status < KLU_OK)
495 Common->status = KLU_OUT_OF_MEMORY ;
499 Numeric->nblocks = nblocks ;
500 Numeric->nzoff = nzoff ;
501 Numeric->Pnum = (Int *) KLU_malloc (n,
sizeof (Int), Common) ;
502 Numeric->Offp = (Int *) KLU_malloc (n1,
sizeof (Int), Common) ;
503 Numeric->Offi = (Int *) KLU_malloc (nzoff1,
sizeof (Int), Common) ;
504 Numeric->Offx = KLU_malloc (nzoff1,
sizeof (Entry), Common) ;
506 Numeric->Lip = (Int *) KLU_malloc (n,
sizeof (Int), Common) ;
507 Numeric->Uip = (Int *) KLU_malloc (n,
sizeof (Int), Common) ;
508 Numeric->Llen = (Int *) KLU_malloc (n,
sizeof (Int), Common) ;
509 Numeric->Ulen = (Int *) KLU_malloc (n,
sizeof (Int), Common) ;
511 Numeric->LUsize = (
size_t *) KLU_malloc (nblocks,
sizeof (
size_t), Common) ;
513 Numeric->LUbx = (
void **) KLU_malloc (nblocks,
sizeof (Unit *), Common) ;
514 if (Numeric->LUbx != NULL)
516 for (k = 0 ; k < nblocks ; k++)
518 Numeric->LUbx [k] = NULL ;
522 Numeric->Udiag = KLU_malloc (n,
sizeof (Entry), Common) ;
524 if (Common->scale > 0)
526 Numeric->Rs = (
double *) KLU_malloc (n,
sizeof (
double), Common) ;
534 Numeric->Pinv = (Int *) KLU_malloc (n,
sizeof (Int), Common) ;
543 s = KLU_mult_size_t (n,
sizeof (Entry), &ok) ;
544 n3 = KLU_mult_size_t (n, 3 *
sizeof (Entry), &ok) ;
545 b6 = KLU_mult_size_t (maxblock, 6 *
sizeof (Int), &ok) ;
546 Numeric->worksize = KLU_add_size_t (s, MAX (n3, b6), &ok) ;
547 Numeric->Work = KLU_malloc (Numeric->worksize, 1, Common) ;
548 Numeric->Xwork = Numeric->Work ;
549 Numeric->Iwork = (Int *) ((Entry *) Numeric->Xwork + n) ;
550 if (!ok || Common->status < KLU_OK)
553 Common->status = ok ? KLU_OUT_OF_MEMORY : KLU_TOO_LARGE ;
554 KLU_free_numeric (&Numeric, Common) ;
562 factor2 (Ap, Ai, (Entry *) Ax, Symbolic, Numeric, Common) ;
568 if (Common->status < KLU_OK)
571 KLU_free_numeric (&Numeric, Common) ;
573 else if (Common->status == KLU_SINGULAR)
575 if (Common->halt_if_singular)
580 KLU_free_numeric (&Numeric, Common) ;
583 else if (Common->status == KLU_OK)
586 Common->numerical_rank = n ;
587 Common->singular_col = n ;
void scale(ArrayView< Scalar1 > vals, size_t l, size_t ld, ArrayView< Scalar2 > s)
Scales a 1-D representation of a multivector.