1
1
/* ========================================================================== */
2
/* === klu_factor =========================================================== */
2
/* === KLU_factor =========================================================== */
3
3
/* ========================================================================== */
5
/* Factor the matrix, after ordering and analyzing it with klu_analyze
6
* or klu_analyze_given.
5
/* Factor the matrix, after ordering and analyzing it with KLU_analyze
6
* or KLU_analyze_given.
9
9
#include "klu_internal.h"
11
11
/* ========================================================================== */
12
/* === klu_factor2 ========================================================== */
12
/* === KLU_factor2 ========================================================== */
13
13
/* ========================================================================== */
15
static void klu_factor2
17
17
/* inputs, not modified */
18
int Ap [ ], /* size n+1, column pointers */
19
int Ai [ ], /* size nz, row indices */
18
Int Ap [ ], /* size n+1, column pointers */
19
Int Ai [ ], /* size nz, row indices */
21
klu_symbolic *Symbolic,
21
KLU_symbolic *Symbolic,
23
23
/* inputs, modified on output: */
30
int *P, *Q, *R, *Pnum, *Offp, *Offi, *Pblock, *Pinv, *Iwork ;
31
int **Lbip, **Ubip, **Lblen, **Ublen ;
32
Entry *Offx, *Singleton, *X, s ;
33
Unit **LUbx, **Udiag ;
34
int k1, k2, nk, k, block, oldcol, pend, oldrow, n, lnz, unz, p, newrow,
30
Int *P, *Q, *R, *Pnum, *Offp, *Offi, *Pblock, *Pinv, *Iwork,
31
*Lip, *Uip, *Llen, *Ulen ;
32
Entry *Offx, *X, s, *Udiag ;
34
Int k1, k2, nk, k, block, oldcol, pend, oldrow, n, lnz, unz, p, newrow,
35
35
nblocks, poff, nzoff, lnz_block, unz_block, scale, max_lnz_block,
110
/* use Pnum as workspace */
103
/* use Pnum as workspace. NOTE: scale factors are not yet permuted
104
* according to the final pivot row ordering, so Rs [oldrow] is the
105
* scale factor for A (oldrow,:), for the user's matrix A. Pnum is
106
* used as workspace in KLU_scale. When the factorization is done,
107
* the scale factors are permuted according to the final pivot row
108
* permutation, so that Rs [k] is the scale factor for the kth row of
109
* A(p,q) where p and q are the final row and column permutations. */
111
110
KLU_scale (scale, n, Ap, Ai, (double *) Ax, Rs, Pnum, Common) ;
112
111
if (Common->status < KLU_OK)
235
238
lsize = Common->initmem_amd * Lnz [block] + nk ;
238
/* allocates 5 arrays:
239
* Lbip [block], Ubip [block], Lblen [block], Ublen [block],
241
KLU_kernel_factor (nk, Ap, Ai, Ax, Q, lsize,
242
&LUbx [block], Udiag [block], Lblen [block], Ublen [block],
243
Lbip [block], Ubip [block], Pblock, &lnz_block, &unz_block,
245
/* BTF and scale-related arguments: */
246
k1, Pinv, Rs, Offp, Offi, Offx, Common) ;
241
/* allocates 1 arrays: LUbx [block] */
242
Numeric->LUsize [block] = KLU_kernel_factor (nk, Ap, Ai, Ax, Q,
243
lsize, &LUbx [block], Udiag + k1, Llen + k1, Ulen + k1,
244
Lip + k1, Uip + k1, Pblock, &lnz_block, &unz_block,
245
X, Iwork, k1, Pinv, Rs, Offp, Offi, Offx, Common) ;
248
247
if (Common->status < KLU_OK ||
249
248
(Common->status == KLU_SINGULAR && Common->halt_if_singular))
255
254
PRINTF (("\n----------------------- L %d:\n", block)) ;
256
ASSERT (KLU_valid_LU (nk, TRUE, Lbip [block],
257
Lblen [block], LUbx [block])) ;
255
ASSERT (KLU_valid_LU (nk, TRUE, Lip+k1, Llen+k1, LUbx [block])) ;
258
256
PRINTF (("\n----------------------- U %d:\n", block)) ;
259
ASSERT (KLU_valid_LU (nk, FALSE, Ubip [block],
260
Ublen [block], LUbx [block])) ;
257
ASSERT (KLU_valid_LU (nk, FALSE, Uip+k1, Ulen+k1, LUbx [block])) ;
262
259
/* -------------------------------------------------------------- */
263
260
/* get statistics */
349
344
PRINTF (("\n ############# KLU_BTF_FACTOR done, nblocks %d\n",nblocks));
350
Entry *singleton = Numeric->Singleton ;
345
Entry ss, *Udiag = Numeric->Udiag ;
351
346
for (block = 0 ; block < nblocks && Common->status == KLU_OK ; block++)
354
349
k2 = R [block+1] ;
356
PRINTF (("\n======================klu_factor output: k1 %d k2 %d nk %d\n",k1,k2,nk)) ;
351
PRINTF (("\n======================KLU_factor output: k1 %d k2 %d nk %d\n",k1,k2,nk)) ;
359
354
PRINTF (("singleton ")) ;
360
355
/* ENTRY_PRINT (singleton [block]) ; */
361
PRINT_ENTRY (singleton [block]) ;
365
int *Lip, *Uip, *Llen, *Ulen ;
361
Int *Lip, *Uip, *Llen, *Ulen ;
368
Llen = Lblen [block] ;
363
Lip = Numeric->Lip + k1 ;
364
Llen = Numeric->Llen + k1 ;
369
365
LU = (Unit *) Numeric->LUbx [block] ;
370
366
PRINTF (("\n---- L block %d\n", block));
371
367
ASSERT (KLU_valid_LU (nk, TRUE, Lip, Llen, LU)) ;
373
Ulen = Ublen [block] ;
368
Uip = Numeric->Uip + k1 ;
369
Ulen = Numeric->Ulen + k1 ;
374
370
PRINTF (("\n---- U block %d\n", block)) ;
375
371
ASSERT (KLU_valid_LU (nk, FALSE, Uip, Ulen, LU)) ;
383
/* ========================================================================== */
384
/* === CLEAR_PTR ============================================================ */
385
/* ========================================================================== */
387
/* Set an array of pointers to NULL */
389
#define CLEAR_PTR(Ptr,size) \
394
for (ii = 0 ; ii < size ; ii++) \
402
/* ========================================================================== */
403
/* === klu_factor =========================================================== */
404
/* ========================================================================== */
406
klu_numeric *KLU_factor /* returns NULL if error, or a valid
407
klu_numeric object if successful */
380
/* ========================================================================== */
381
/* === KLU_factor =========================================================== */
382
/* ========================================================================== */
384
KLU_numeric *KLU_factor /* returns NULL if error, or a valid
385
KLU_numeric object if successful */
409
387
/* --- inputs --- */
410
int Ap [ ], /* size n+1, column pointers */
411
int Ai [ ], /* size nz, row indices */
388
Int Ap [ ], /* size n+1, column pointers */
389
Int Ai [ ], /* size nz, row indices */
413
klu_symbolic *Symbolic,
391
KLU_symbolic *Symbolic,
414
392
/* -------------- */
418
int n, nzoff, nblocks, maxblock, block, k1, k2, nk, ok = TRUE ;
420
int **Lbip, **Ubip, **Lblen, **Ublen ;
421
klu_numeric *Numeric ;
423
size_t n1, nzoff1, nunits, s, b6, n3, nk1 ;
396
Int n, nzoff, nblocks, maxblock, k, ok = TRUE ;
398
KLU_numeric *Numeric ;
399
size_t n1, nzoff1, s, b6, n3 ;
425
401
if (Common == NULL)
457
433
Common->initmem = MAX (1.0, Common->initmem) ;
458
434
Common->tol = MIN (Common->tol, 1.0) ;
459
435
Common->tol = MAX (0.0, Common->tol) ;
460
Common->growth = MAX (1.0, Common->growth) ;
436
Common->memgrow = MAX (1.0, Common->memgrow) ;
462
438
/* ---------------------------------------------------------------------- */
463
439
/* allocate the Numeric object */
464
440
/* ---------------------------------------------------------------------- */
466
/* this will not cause size_t overflow (already checked by klu_symbolic) */
442
/* this will not cause size_t overflow (already checked by KLU_symbolic) */
467
443
n1 = ((size_t) n) + 1 ;
468
444
nzoff1 = ((size_t) nzoff) + 1 ;
470
Numeric = klu_malloc (sizeof (klu_numeric), 1, Common) ;
446
Numeric = KLU_malloc (sizeof (KLU_numeric), 1, Common) ;
471
447
if (Common->status < KLU_OK)
473
449
/* out of memory */
474
450
Common->status = KLU_OUT_OF_MEMORY ;
477
454
Numeric->nblocks = nblocks ;
478
Numeric->Pnum = klu_malloc (n, sizeof (int), Common) ;
479
Numeric->Offp = klu_malloc (n1, sizeof (int), Common) ;
480
Numeric->Offi = klu_malloc (nzoff1, sizeof (int), Common) ;
481
Numeric->Offx = klu_malloc (nzoff1, sizeof (Entry), Common) ;
482
Numeric->Singleton = klu_malloc (nblocks, sizeof (Entry), Common) ;
484
Numeric->Lbip = klu_malloc (nblocks, sizeof (int *), Common) ;
485
Numeric->Ubip = klu_malloc (nblocks, sizeof (int *), Common) ;
486
Numeric->Lblen = klu_malloc (nblocks, sizeof (int *), Common) ;
487
Numeric->Ublen = klu_malloc (nblocks, sizeof (int *), Common) ;
488
Numeric->LUbx = klu_malloc (nblocks, sizeof (Unit *), Common) ;
489
Numeric->Udiag = klu_malloc (nblocks, sizeof (Unit *), Common) ;
455
Numeric->nzoff = nzoff ;
456
Numeric->Pnum = KLU_malloc (n, sizeof (Int), Common) ;
457
Numeric->Offp = KLU_malloc (n1, sizeof (Int), Common) ;
458
Numeric->Offi = KLU_malloc (nzoff1, sizeof (Int), Common) ;
459
Numeric->Offx = KLU_malloc (nzoff1, sizeof (Entry), Common) ;
461
Numeric->Lip = KLU_malloc (n, sizeof (Int), Common) ;
462
Numeric->Uip = KLU_malloc (n, sizeof (Int), Common) ;
463
Numeric->Llen = KLU_malloc (n, sizeof (Int), Common) ;
464
Numeric->Ulen = KLU_malloc (n, sizeof (Int), Common) ;
466
Numeric->LUsize = KLU_malloc (nblocks, sizeof (size_t), Common) ;
468
Numeric->LUbx = KLU_malloc (nblocks, sizeof (Unit *), Common) ;
469
if (Numeric->LUbx != NULL)
471
for (k = 0 ; k < nblocks ; k++)
473
Numeric->LUbx [k] = NULL ;
477
Numeric->Udiag = KLU_malloc (n, sizeof (Entry), Common) ;
491
479
if (Common->scale > 0)
493
Numeric->Rs = klu_malloc (n, sizeof (double), Common) ;
481
Numeric->Rs = KLU_malloc (n, sizeof (double), Common) ;
498
486
Numeric->Rs = NULL ;
501
Numeric->Pinv = klu_malloc (n, sizeof (int), Common) ;
503
/* allocate permanent workspace for factorization and solve.
504
* Note that the solver will use an Xwork of size 4n, whereas
505
* the factorization codes use an Xwork of size n and integer space
506
* (Iwork) of size 6n. klu_condest uses an Xwork of size 2n. */
508
s = klu_mult_size_t (n, sizeof (Entry), &ok) ;
509
n3 = klu_mult_size_t (n, 3 * sizeof (Entry), &ok) ;
510
b6 = klu_mult_size_t (maxblock, 6 * sizeof (int), &ok) ;
511
Numeric->worksize = klu_add_size_t (s, MAX (n3, b6), &ok) ;
514
/* problem too large (almost impossible to happen here) */
515
Common->status = KLU_TOO_LARGE ;
516
KLU_free_numeric (&Numeric, Common) ;
521
Numeric->worksize = n * sizeof (Entry) +
522
MAX (n * 3 *sizeof (Entry), 6*maxblock * sizeof (int)) ;
525
Numeric->Work = klu_malloc (Numeric->worksize, 1, Common) ;
489
Numeric->Pinv = KLU_malloc (n, sizeof (Int), Common) ;
491
/* allocate permanent workspace for factorization and solve. Note that the
492
* solver will use an Xwork of size 4n, whereas the factorization codes use
493
* an Xwork of size n and integer space (Iwork) of size 6n. KLU_condest
494
* uses an Xwork of size 2n. Total size is:
496
* n*sizeof(Entry) + max (6*maxblock*sizeof(Int), 3*n*sizeof(Entry))
498
s = KLU_mult_size_t (n, sizeof (Entry), &ok) ;
499
n3 = KLU_mult_size_t (n, 3 * sizeof (Entry), &ok) ;
500
b6 = KLU_mult_size_t (maxblock, 6 * sizeof (Int), &ok) ;
501
Numeric->worksize = KLU_add_size_t (s, MAX (n3, b6), &ok) ;
502
Numeric->Work = KLU_malloc (Numeric->worksize, 1, Common) ;
526
503
Numeric->Xwork = Numeric->Work ;
527
Numeric->Iwork = (int *) ((Entry *) Numeric->Xwork + n) ;
529
if (Common->status < KLU_OK)
504
Numeric->Iwork = (Int *) ((Entry *) Numeric->Xwork + n) ;
505
if (!ok || Common->status < KLU_OK)
507
/* out of memory or problem too large */
508
Common->status = ok ? KLU_OUT_OF_MEMORY : KLU_TOO_LARGE ;
532
509
KLU_free_numeric (&Numeric, Common) ;
536
/* clear the pointer arrays, so that klu_free_numeric works OK */
537
CLEAR_PTR (Numeric->Lbip, nblocks) ;
538
CLEAR_PTR (Numeric->Ubip, nblocks) ;
539
CLEAR_PTR (Numeric->Lblen, nblocks) ;
540
CLEAR_PTR (Numeric->Ublen, nblocks) ;
541
CLEAR_PTR (Numeric->LUbx, nblocks) ;
542
CLEAR_PTR (Numeric->Udiag, nblocks) ;
544
/* allocate the column pointer arrays for each block */
545
Lbip = Numeric->Lbip ;
546
Ubip = Numeric->Ubip ;
547
Lblen = Numeric->Lblen ;
548
Ublen = Numeric->Ublen ;
549
Udiag = (Unit **) Numeric->Udiag ;
551
for (block = 0 ; block < nblocks ; block++)
556
nk1 = ((size_t) nk) + 1 ; /* cannot overflow */
559
nunits = UNITS (Entry, nk) ;
560
Lbip [block] = klu_malloc (nk1, sizeof (int), Common) ;
561
Ubip [block] = klu_malloc (nk1, sizeof (int), Common) ;
562
Lblen [block] = klu_malloc (nk1, sizeof (int), Common) ;
563
Ublen [block] = klu_malloc (nk1, sizeof (int), Common) ;
564
Udiag [block] = klu_malloc (nunits, sizeof (Unit), Common) ;
565
if (Common->status < KLU_OK)
568
KLU_free_numeric (&Numeric, Common) ;
574
513
/* ---------------------------------------------------------------------- */
575
514
/* factorize the blocks */
576
515
/* ---------------------------------------------------------------------- */
578
klu_factor2 (Ap, Ai, (Entry *) Ax, Symbolic, Numeric, Common) ;
517
factor2 (Ap, Ai, (Entry *) Ax, Symbolic, Numeric, Common) ;
580
519
/* ---------------------------------------------------------------------- */
581
520
/* return or free the Numeric object */