1
/* ========================================================================== */
2
/* === UMF_assemble ========================================================= */
3
/* ========================================================================== */
5
/* -------------------------------------------------------------------------- */
6
/* UMFPACK Version 4.1 (Apr. 30, 2003), Copyright (c) 2003 by Timothy A. */
7
/* Davis. All Rights Reserved. See ../README for License. */
8
/* email: davis@cise.ufl.edu CISE Department, Univ. of Florida. */
9
/* web: http://www.cise.ufl.edu/research/sparse/umfpack */
10
/* -------------------------------------------------------------------------- */
12
/* Degree update and numerical assembly. This is compiled twice (with and
13
* without FIXQ) for each real/complex int/long version, for a total of 8
16
#include "umf_internal.h"
17
#include "umf_mem_free_tail_block.h"
19
/* ========================================================================== */
20
/* === row_assemble ========================================================= */
21
/* ========================================================================== */
23
PRIVATE void row_assemble
31
Int tpi, e, *E, *Fcpos, *Frpos, *Row_degree, *Row_tuples, *Row_tlen, rdeg0,
32
f, nrows, ncols, *Rows, *Cols, col, ncolsleft, j ;
33
Tuple *tp, *tp1, *tp2, *tpend ;
36
Entry *S, *Fcblock, *Frow ;
40
Col_degree = Numeric->Cperm ;
43
Row_tuples = Numeric->Uip ;
44
tpi = Row_tuples [row] ;
47
Memory = Numeric->Memory ;
51
Row_degree = Numeric->Rperm ;
52
Row_tlen = Numeric->Uilen ;
54
Memory = Numeric->Memory ;
56
Fcblock = Work->Fcblock ;
59
DEBUG6 (("SCAN2-row: "ID"\n", row)) ;
60
UMF_dump_rowcol (0, Numeric, Work, row, FALSE) ;
63
ASSERT (NON_PIVOTAL_ROW (row)) ;
65
tp = (Tuple *) (Memory + tpi) ;
68
tpend = tp + Row_tlen [row] ;
69
for ( ; tp < tpend ; tp++)
72
ASSERT (e > 0 && e <= Work->nel) ;
73
if (!E [e]) continue ; /* element already deallocated */
77
p += UNITS (Element, 1) ;
79
Rows = Cols + ep->ncols ;
80
if (Rows [f] == EMPTY) continue ; /* row already assembled */
81
ASSERT (row == Rows [f] && row >= 0 && row < Work->n_row) ;
83
if (ep->rdeg == rdeg0)
85
/* ------------------------------------------------------ */
86
/* this is an old Lson - assemble just one row */
87
/* ------------------------------------------------------ */
89
/* flag the row as assembled from the Lson */
95
p += UNITS (Int, ncols + nrows) ;
96
S = ((Entry *) p) + f ;
98
DEBUG6 (("Old LSON: "ID"\n", e)) ;
100
UMF_dump_element (Numeric, Work, e, FALSE) ;
103
ncolsleft = ep->ncolsleft ;
105
Frow = Fcblock + Frpos [row] ;
106
DEBUG6 (("LSON found (in scan2-row): "ID"\n", e)) ;
108
Row_degree [row] -= ncolsleft ;
110
if (ncols == ncolsleft)
112
/* -------------------------------------------------- */
113
/* no columns assembled out this Lson yet */
114
/* -------------------------------------------------- */
117
for (j = 0 ; j < ncols ; j++)
120
ASSERT (col >= 0 && col < Work->n_col) ;
122
Col_degree [col] -- ;
124
/* Frow [Fcpos [col]] += *S ; */
125
ASSEMBLE (Frow [Fcpos [col]], *S) ;
132
/* -------------------------------------------------- */
133
/* some columns have been assembled out of this Lson */
134
/* -------------------------------------------------- */
137
for (j = 0 ; j < ncols ; j++)
142
ASSERT (col < Work->n_col) ;
144
Col_degree [col] -- ;
146
/* Frow [Fcpos [col]] += *S ; */
147
ASSEMBLE (Frow [Fcpos [col]], *S) ;
154
ASSERT (ep->nrowsleft > 0) ;
158
*tp2++ = *tp ; /* leave the tuple in the list */
161
Row_tlen [row] = tp2 - tp1 ;
164
DEBUG7 (("row assembled in scan2-row: "ID"\n", row)) ;
165
UMF_dump_rowcol (0, Numeric, Work, row, FALSE) ;
166
DEBUG7 (("Current frontal matrix: (scan 1b)\n")) ;
167
UMF_dump_current_front (Numeric, Work, TRUE) ;
171
/* ========================================================================== */
172
/* === col_assemble ========================================================= */
173
/* ========================================================================== */
175
PRIVATE void col_assemble
178
NumericType *Numeric,
183
Int tpi, e, *E, *Fcpos, *Frpos, *Row_degree, *Col_tuples, *Col_tlen, cdeg0,
184
f, nrows, ncols, *Rows, *Cols, row, nrowsleft, i ;
185
Tuple *tp, *tp1, *tp2, *tpend ;
188
Entry *S, *Fcblock, *Fcol ;
190
#if !defined (FIXQ) || !defined (NDEBUG)
192
Col_degree = Numeric->Cperm ;
195
Col_tuples = Numeric->Lip ;
196
tpi = Col_tuples [col] ;
199
Memory = Numeric->Memory ;
201
Fcpos = Work->Fcpos ;
202
Frpos = Work->Frpos ;
203
Row_degree = Numeric->Rperm ;
204
Col_tlen = Numeric->Lilen ;
206
Memory = Numeric->Memory ;
207
cdeg0 = Work->cdeg0 ;
208
Fcblock = Work->Fcblock ;
210
DEBUG6 (("SCAN2-col: "ID"\n", col)) ;
212
UMF_dump_rowcol (1, Numeric, Work, col, FALSE) ;
215
ASSERT (NON_PIVOTAL_COL (col)) ;
216
tp = (Tuple *) (Memory + tpi) ;
219
tpend = tp + Col_tlen [col] ;
220
for ( ; tp < tpend ; tp++)
223
ASSERT (e > 0 && e <= Work->nel) ;
224
if (!E [e]) continue ; /* element already deallocated */
228
p += UNITS (Element, 1) ;
231
if (Cols [f] == EMPTY) continue ; /* col already assembled */
232
ASSERT (col == Cols [f] && col >= 0 && col < Work->n_col) ;
234
if (ep->cdeg == cdeg0)
236
/* ------------------------------------------------------ */
237
/* this is an old Uson - assemble just one col */
238
/* ------------------------------------------------------ */
240
/* flag the col as assembled from the Uson */
245
Rows = Cols + ncols ;
246
p += UNITS (Int, ncols + nrows) ;
247
S = ((Entry *) p) + f * nrows ;
249
DEBUG6 (("Old USON: "ID"\n", e)) ;
251
UMF_dump_element (Numeric, Work, e, FALSE) ;
254
nrowsleft = ep->nrowsleft ;
256
Fcol = Fcblock + Fcpos [col] ;
257
DEBUG6 (("USON found (in scan2-col): "ID"\n", e)) ;
259
Col_degree [col] -= nrowsleft ;
261
if (nrows == nrowsleft)
263
/* -------------------------------------------------- */
264
/* no rows assembled out of this Uson yet */
265
/* -------------------------------------------------- */
268
for (i = 0 ; i < nrows ; i++)
271
ASSERT (row >= 0 && row < Work->n_row) ;
273
/* Fcol [Frpos [row]] += S [i] ; */
274
ASSEMBLE (Fcol [Frpos [row]], S [i]) ;
279
/* -------------------------------------------------- */
280
/* some rows have been assembled out of this Uson */
281
/* -------------------------------------------------- */
284
for (i = 0 ; i < nrows ; i++)
289
ASSERT (row < Work->n_row) ;
291
/* Fcol [Frpos [row]] += S [i] ; */
292
ASSEMBLE (Fcol [Frpos [row]], S [i]) ;
297
ASSERT (ep->ncolsleft > 0) ;
301
*tp2++ = *tp ; /* leave the tuple in the list */
304
Col_tlen [col] = tp2 - tp1 ;
307
DEBUG7 (("Column assembled in scan2-col: "ID"\n", col)) ;
308
UMF_dump_rowcol (1, Numeric, Work, col, FALSE) ;
309
DEBUG7 (("Current frontal matrix: after scan2-col\n")) ;
310
UMF_dump_current_front (Numeric, Work, TRUE) ;
316
/* ========================================================================== */
317
/* === UMF_assemble / UMF_assemble_fixq ===================================== */
318
/* ========================================================================== */
321
GLOBAL void UMF_assemble
323
GLOBAL void UMF_assemble_fixq
326
NumericType *Numeric,
330
/* ---------------------------------------------------------------------- */
331
/* local variables */
332
/* ---------------------------------------------------------------------- */
334
Int e, i, row, col, i2, nrows, ncols, f, tpi, extcdeg, extrdeg, rdeg0,
335
cdeg0, son_list, next, nrows_to_assemble,
336
ncols_to_assemble, ngetrows, j, j2,
337
nrowsleft, /* number of rows remaining in S */
338
ncolsleft, /* number of columns remaining in S */
339
prior_Lson, prior_Uson, *E, *Cols, *Rows, *Wm, *Woo,
340
*Row_tuples, *Row_degree, *Row_tlen,
341
*Col_tuples, *Col_tlen ;
344
Tuple *tp, *tp1, *tp2, *tpend ;
346
*S, /* a pointer into the contribution block of a son */
347
*Fcblock, /* current contribution block */
348
*Fcol ; /* a column of FC */
351
fnrows, /* number of rows in contribution block in F */
352
fncols ; /* number of columns in contribution block in F */
354
#if !defined (FIXQ) || !defined (NDEBUG)
360
n_row = Work->n_row ;
361
n_col = Work->n_col ;
362
DEBUG3 (("::Assemble SCANS 1-4\n")) ;
363
UMF_dump_current_front (Numeric, Work, TRUE) ;
366
#if !defined (FIXQ) || !defined (NDEBUG)
367
Col_degree = Numeric->Cperm ; /* not updated if FIXQ is true */
370
/* ---------------------------------------------------------------------- */
372
/* ---------------------------------------------------------------------- */
374
fncols = Work->fncols ;
375
fnrows = Work->fnrows ;
376
Fcpos = Work->Fcpos ;
377
Frpos = Work->Frpos ;
378
Row_degree = Numeric->Rperm ;
379
Row_tuples = Numeric->Uip ;
380
Row_tlen = Numeric->Uilen ;
381
Col_tuples = Numeric->Lip ;
382
Col_tlen = Numeric->Lilen ;
384
Memory = Numeric->Memory ;
387
rdeg0 = Work->rdeg0 ;
388
cdeg0 = Work->cdeg0 ;
391
DEBUG6 (("============================================\n")) ;
392
DEBUG6 (("Degree update, assembly.\n")) ;
393
DEBUG6 (("pivot row pattern: fncols="ID"\n", fncols)) ;
394
for (j = 0 ; j < fncols ; j++)
396
col = Work->Fcols [j] ;
397
DEBUG6 ((ID" ", col)) ;
398
ASSERT (Fcpos [col] == j * Work->fnr_curr) ;
399
ASSERT (NON_PIVOTAL_COL (col)) ;
401
ASSERT (Fcpos [Work->pivcol] >= 0) ;
402
DEBUG6 (("pivcol: "ID" pos "ID" fnr_curr "ID" fncols "ID"\n",
403
Work->pivcol, Fcpos [Work->pivcol], Work->fnr_curr, fncols)) ;
404
ASSERT (Fcpos [Work->pivcol] < fncols * Work->fnr_curr) ;
405
DEBUG6 (("\npivot col pattern: fnrows="ID"\n", fnrows)) ;
406
for (i = 0 ; i < fnrows ; i++)
408
row = Work->Frows [i] ;
409
DEBUG6 ((ID" ", row)) ;
410
ASSERT (Frpos [row] == i) ;
411
ASSERT (NON_PIVOTAL_ROW (row)) ;
414
ASSERT (Frpos [Work->pivrow] >= 0) ;
415
ASSERT (Frpos [Work->pivrow] < fnrows) ;
416
ASSERT (Work->Flublock == (Entry *) (Numeric->Memory + E [0])) ;
417
ASSERT (Work->Fcblock == Work->Flublock + Work->nb *
418
(Work->nb + Work->fnr_curr + Work->fnc_curr)) ;
421
Fcblock = Work->Fcblock ;
423
/* ---------------------------------------------------------------------- */
424
/* determine the largest actual frontal matrix size (for Info only) */
425
/* ---------------------------------------------------------------------- */
427
ASSERT (fnrows == Work->fnrows_new + 1) ;
428
ASSERT (fncols == Work->fncols_new + 1) ;
430
Numeric->maxnrows = MAX (Numeric->maxnrows, fnrows) ;
431
Numeric->maxncols = MAX (Numeric->maxncols, fncols) ;
433
/* this is safe from integer overflow, since the current frontal matrix
434
* is already allocated. */
435
Numeric->maxfrsize = MAX (Numeric->maxfrsize, fnrows * fncols) ;
437
/* ---------------------------------------------------------------------- */
438
/* assemble from prior elements into the current frontal matrix */
439
/* ---------------------------------------------------------------------- */
441
DEBUG2 (("New assemble start [prior_element:"ID"\n", Work->prior_element)) ;
443
/* Currently no rows or columns are marked. No elements are scanned, */
444
/* that is, (ep->next == EMPTY) is true for all elements */
446
son_list = 0 ; /* start creating son_list [ */
448
/* ---------------------------------------------------------------------- */
449
/* determine if most recent element is Lson or Uson of current front */
450
/* ---------------------------------------------------------------------- */
452
if (!Work->do_extend)
454
prior_Uson = ( Work->pivcol_in_front && !Work->pivrow_in_front) ;
455
prior_Lson = (!Work->pivcol_in_front && Work->pivrow_in_front) ;
456
if (prior_Uson || prior_Lson)
458
e = Work->prior_element ;
464
ep->next = son_list ;
467
DEBUG2 (("e "ID" is Prior son "ID" "ID"\n",
468
e, prior_Uson, prior_Lson)) ;
469
UMF_dump_element (Numeric, Work, e, FALSE) ;
475
Work->prior_element = EMPTY ;
477
/* ---------------------------------------------------------------------- */
478
/* SCAN1-row: scan the element lists of each new row in the pivot col */
479
/* and compute the external column degree for each frontal */
480
/* ---------------------------------------------------------------------- */
482
for (i2 = Work->fscan_row ; i2 < fnrows ; i2++)
485
row = Work->NewRows [i2] ;
486
if (row < 0) row = FLIP (row) ;
487
ASSERT (row >= 0 && row < n_row) ;
489
DEBUG6 (("SCAN1-row: "ID"\n", row)) ;
491
UMF_dump_rowcol (0, Numeric, Work, row, FALSE) ;
494
ASSERT (NON_PIVOTAL_ROW (row)) ;
495
tpi = Row_tuples [row] ;
497
tp = (Tuple *) (Memory + tpi) ;
500
tpend = tp + Row_tlen [row] ;
501
for ( ; tp < tpend ; tp++)
504
ASSERT (e > 0 && e <= Work->nel) ;
505
if (!E [e]) continue ; /* element already deallocated */
509
p += UNITS (Element, 1) ;
510
Rows = ((Int *) p) + ep->ncols ;
511
if (Rows [f] == EMPTY) continue ; /* row already assembled */
512
ASSERT (row == Rows [f]) ;
514
if (ep->cdeg < cdeg0)
516
/* first time seen in scan1-row */
517
ep->cdeg = ep->nrowsleft + cdeg0 ;
518
DEBUG6 (("e "ID" First seen: cdeg: "ID" ", e, ep->cdeg-cdeg0)) ;
519
ASSERT (ep->ncolsleft > 0 && ep->nrowsleft > 0) ;
522
ep->cdeg-- ; /* decrement external column degree */
523
DEBUG6 (("e "ID" New ext col deg: "ID"\n", e, ep->cdeg - cdeg0)) ;
525
/* this element is not yet in the new son list */
526
if (ep->cdeg == cdeg0 && ep->next == EMPTY)
528
/* A new LUson or Uson has been found */
529
ep->next = son_list ;
533
ASSERT (ep->cdeg >= cdeg0) ;
534
*tp2++ = *tp ; /* leave the tuple in the list */
536
Row_tlen [row] = tp2 - tp1 ;
539
/* ---------------------------------------------------------------------- */
540
/* SCAN1-col: scan the element lists of each new col in the pivot row */
541
/* and compute the external row degree for each frontal */
542
/* ---------------------------------------------------------------------- */
544
for (j2 = Work->fscan_col ; j2 < fncols ; j2++)
547
col = Work->NewCols [j2] ;
548
if (col < 0) col = FLIP (col) ;
549
ASSERT (col >= 0 && col < n_col) ;
551
DEBUG6 (("SCAN 1-col: "ID"\n", col)) ;
553
UMF_dump_rowcol (1, Numeric, Work, col, FALSE) ;
556
ASSERT (NON_PIVOTAL_COL (col)) ;
557
tpi = Col_tuples [col] ;
559
tp = (Tuple *) (Memory + tpi) ;
562
tpend = tp + Col_tlen [col] ;
563
for ( ; tp < tpend ; tp++)
566
ASSERT (e > 0 && e <= Work->nel) ;
567
if (!E [e]) continue ; /* element already deallocated */
571
p += UNITS (Element, 1) ;
573
if (Cols [f] == EMPTY) continue ; /* column already assembled */
574
ASSERT (col == Cols [f]) ;
576
if (ep->rdeg < rdeg0)
578
/* first time seen in scan1-col */
579
ep->rdeg = ep->ncolsleft + rdeg0 ;
580
DEBUG6 (("e "ID" First seen: rdeg: "ID" ", e, ep->rdeg-rdeg0)) ;
581
ASSERT (ep->ncolsleft > 0 && ep->nrowsleft > 0) ;
584
ep->rdeg-- ; /* decrement external row degree */
585
DEBUG6 (("e "ID" New ext row degree: "ID"\n", e, ep->rdeg-rdeg0)) ;
587
if (ep->rdeg == rdeg0 && ep->next == EMPTY)
589
/* A new LUson or Lson has been found */
590
ep->next = son_list ;
594
ASSERT (ep->rdeg >= rdeg0) ;
595
*tp2++ = *tp ; /* leave the tuple in the list */
597
Col_tlen [col] = tp2 - tp1 ;
600
/* ---------------------------------------------------------------------- */
601
/* assemble new sons via full scans */
602
/* ---------------------------------------------------------------------- */
606
for (e = son_list ; e > 0 ; e = next)
608
ASSERT (e > 0 && e <= Work->nel && E [e]) ;
610
DEBUG2 (("New son: "ID"\n", e)) ;
612
UMF_dump_element (Numeric, Work, e, FALSE) ;
614
GET_ELEMENT (ep, p, Cols, Rows, ncols, nrows, S) ;
615
nrowsleft = ep->nrowsleft ;
616
ncolsleft = ep->ncolsleft ;
620
extrdeg = (ep->rdeg < rdeg0) ? ncolsleft : (ep->rdeg - rdeg0) ;
621
extcdeg = (ep->cdeg < cdeg0) ? nrowsleft : (ep->cdeg - cdeg0) ;
622
ncols_to_assemble = ncolsleft - extrdeg ;
623
nrows_to_assemble = nrowsleft - extcdeg ;
624
DEBUG2 (("extrdeg "ID" extcdeg "ID"\n", extrdeg, extcdeg)) ;
626
if (extrdeg == 0 && extcdeg == 0)
629
/* -------------------------------------------------------------- */
630
/* this is an LUson - assemble an entire contribution block */
631
/* -------------------------------------------------------------- */
633
DEBUG6 (("LUson found: "ID"\n", e)) ;
635
if (nrows == nrowsleft)
637
/* ---------------------------------------------------------- */
638
/* no rows assembled out of this LUson yet */
639
/* ---------------------------------------------------------- */
641
/* compute the compressed column offset vector*/
642
/* [ use Wm [0..nrows-1] for offsets */
644
for (i = 0 ; i < nrows ; i++)
647
Row_degree [row] -= ncolsleft ;
648
Wm [i] = Frpos [row] ;
651
if (ncols == ncolsleft)
653
/* ------------------------------------------------------ */
654
/* no rows or cols assembled out of LUson yet */
655
/* ------------------------------------------------------ */
657
for (j = 0 ; j < ncols ; j++)
661
Col_degree [col] -= nrowsleft ;
663
Fcol = Fcblock + Fcpos [col] ;
665
for (i = 0 ; i < nrows ; i++)
667
/* Fcol [Wm [i]] += S [i] ; */
668
ASSEMBLE (Fcol [Wm [i]], S [i]) ;
677
/* ------------------------------------------------------ */
678
/* only cols have been assembled out of LUson */
679
/* ------------------------------------------------------ */
681
for (j = 0 ; j < ncols ; j++)
687
Col_degree [col] -= nrowsleft ;
689
Fcol = Fcblock + Fcpos [col] ;
691
for (i = 0 ; i < nrows ; i++)
693
/* Fcol [Wm [i]] += S [i] ; */
694
ASSEMBLE (Fcol [Wm [i]], S [i]) ;
701
/* ] done using Wm [0..nrows-1] for offsets */
705
/* ---------------------------------------------------------- */
706
/* some rows have been assembled out of this LUson */
707
/* ---------------------------------------------------------- */
709
/* compute the compressed column offset vector*/
710
/* [ use Woo,Wm [0..nrowsleft-1] for offsets */
712
for (i = 0 ; i < nrows ; i++)
717
Row_degree [row] -= ncolsleft ;
719
Wm [ngetrows++] = Frpos [row] ;
722
ASSERT (ngetrows == nrowsleft) ;
724
if (ncols == ncolsleft)
726
/* ------------------------------------------------------ */
727
/* only rows have been assembled out of this LUson */
728
/* ------------------------------------------------------ */
730
for (j = 0 ; j < ncols ; j++)
734
Col_degree [col] -= nrowsleft ;
736
Fcol = Fcblock + Fcpos [col] ;
738
for (i = 0 ; i < nrowsleft ; i++)
740
/* Fcol [Wm [i]] += S [Woo [i]] ; */
741
ASSEMBLE (Fcol [Wm [i]], S [Woo [i]]) ;
749
/* ------------------------------------------------------ */
750
/* both rows and columns have been assembled out of LUson */
751
/* ------------------------------------------------------ */
753
for (j = 0 ; j < ncols ; j++)
759
Col_degree [col] -= nrowsleft ;
761
Fcol = Fcblock + Fcpos [col] ;
763
for (i = 0 ; i < nrowsleft ; i++)
765
/* Fcol [Wm [i]] += S [Woo [i]] ; */
766
ASSEMBLE (Fcol [Wm [i]], S [Woo [i]]) ;
773
/* ] done using Woo,Wm [0..nrowsleft-1] */
776
/* deallocate the element: remove from ordered list */
777
UMF_mem_free_tail_block (Numeric, E [e]) ;
781
else if (extcdeg == 0)
784
/* -------------------------------------------------------------- */
785
/* this is a Uson - assemble all possible columns */
786
/* -------------------------------------------------------------- */
788
DEBUG6 (("New USON: "ID"\n", e)) ;
789
ASSERT (extrdeg > 0) ;
791
DEBUG6 (("New uson "ID" cols to do "ID"\n", e, ncols_to_assemble)) ;
793
if (ncols_to_assemble > 0)
797
if (ncols_to_assemble * 16 < ncols && nrows == 1)
799
/* this is a tall and thin frontal matrix consisting of
800
* only one column (most likely an original column). Do
801
* not assemble it. It cannot be the pivot column, since
802
* the pivot column element would be an LU son, not an Lson,
803
* of the current frontal matrix. */
804
ASSERT (nrowsleft == 1) ;
805
ASSERT (Rows [0] >= 0 && Rows [0] < Work->n_row) ;
807
Work->any_skip = TRUE ;
813
if (nrows == nrowsleft)
815
/* -------------------------------------------------- */
816
/* no rows have been assembled out of this Uson yet */
817
/* -------------------------------------------------- */
819
/* compute the compressed column offset vector */
820
/* [ use Wm [0..nrows-1] for offsets */
822
for (i = 0 ; i < nrows ; i++)
825
ASSERT (row >= 0 && row < n_row) ;
826
Row_degree [row] -= ncols_to_assemble ;
827
Wm [i] = Frpos [row] ;
830
for (j = 0 ; j < ncols ; j++)
833
if ((col >= 0) && (Fcpos [col] >= 0))
836
Col_degree [col] -= nrowsleft ;
838
Fcol = Fcblock + Fcpos [col] ;
840
for (i = 0 ; i < nrows ; i++)
842
/* Fcol [Wm [i]] += S [i] ; */
843
ASSEMBLE (Fcol [Wm [i]], S [i]) ;
845
/* flag the column as assembled from Uson */
852
/* ] done using Wm [0..nrows-1] for offsets */
856
/* -------------------------------------------------- */
857
/* some rows have been assembled out of this Uson */
858
/* -------------------------------------------------- */
860
/* compute the compressed column offset vector*/
861
/* [ use Woo,Wm [0..nrows-1] for offsets */
863
for (i = 0 ; i < nrows ; i++)
868
Row_degree [row] -= ncols_to_assemble ;
869
ASSERT (row < n_row && Frpos [row] >= 0) ;
871
Wm [ngetrows++] = Frpos [row] ;
874
ASSERT (ngetrows == nrowsleft) ;
876
for (j = 0 ; j < ncols ; j++)
879
if ((col >= 0) && (Fcpos [col] >= 0))
882
Col_degree [col] -= nrowsleft ;
884
Fcol = Fcblock + Fcpos [col] ;
886
for (i = 0 ; i < nrowsleft ; i++)
888
/* Fcol [Wm [i]] += S [Woo [i]] ; */
889
ASSEMBLE (Fcol [Wm [i]], S [Woo [i]]) ;
891
/* flag the column as assembled from Uson */
897
/* ] done using Woo,Wm */
899
ep->ncolsleft = extrdeg ;
907
/* -------------------------------------------------------------- */
908
/* this is an Lson - assemble all possible rows */
909
/* -------------------------------------------------------------- */
911
DEBUG6 (("New LSON: "ID"\n", e)) ;
912
ASSERT (extrdeg == 0 && extcdeg > 0) ;
914
DEBUG6 (("New lson "ID" rows to do "ID"\n", e, nrows_to_assemble)) ;
916
if (nrows_to_assemble > 0)
920
if (nrows_to_assemble * 16 < nrows && ncols == 1)
922
/* this is a tall and thin frontal matrix consisting of
923
* only one column (most likely an original column). Do
924
* not assemble it. It cannot be the pivot column, since
925
* the pivot column element would be an LU son, not an Lson,
926
* of the current frontal matrix. */
927
ASSERT (ncolsleft == 1) ;
928
ASSERT (Cols [0] >= 0 && Cols [0] < Work->n_col) ;
929
Work->any_skip = TRUE ;
936
/* compute the compressed column offset vector */
937
/* [ use Woo,Wm [0..nrows-1] for offsets */
939
for (i = 0 ; i < nrows ; i++)
942
if ((row >= 0) && (Frpos [row] >= 0))
944
ASSERT (row < n_row) ;
945
Row_degree [row] -= ncolsleft ;
947
Wm [ngetrows++] = Frpos [row] ;
948
/* flag the row as assembled from the Lson */
952
ASSERT (nrowsleft - ngetrows == extcdeg) ;
953
ASSERT (ngetrows == nrows_to_assemble) ;
955
if (ncols == ncolsleft)
957
/* -------------------------------------------------- */
958
/* no columns assembled out this Lson yet */
959
/* -------------------------------------------------- */
961
for (j = 0 ; j < ncols ; j++)
964
ASSERT (col >= 0 && col < n_col) ;
966
Col_degree [col] -= nrows_to_assemble ;
968
Fcol = Fcblock + Fcpos [col] ;
970
for (i = 0 ; i < nrows_to_assemble ; i++)
972
/* Fcol [Wm [i]] += S [Woo [i]] ; */
973
ASSEMBLE (Fcol [Wm [i]], S [Woo [i]]) ;
982
/* -------------------------------------------------- */
983
/* some columns have been assembled out of this Lson */
984
/* -------------------------------------------------- */
986
for (j = 0 ; j < ncols ; j++)
989
ASSERT (col < n_col) ;
993
Col_degree [col] -= nrows_to_assemble ;
995
Fcol = Fcblock + Fcpos [col] ;
997
for (i = 0 ; i < nrows_to_assemble ; i++)
999
/* Fcol [Wm [i]] += S [Woo [i]] ; */
1000
ASSEMBLE (Fcol [Wm [i]], S [Woo [i]]) ;
1008
/* ] done using Woo,Wm */
1010
ep->nrowsleft = extcdeg ;
1016
/* Note that garbage collection, and build tuples */
1017
/* both destroy the son list. */
1019
/* ] son_list now empty */
1021
/* ---------------------------------------------------------------------- */
1022
/* If frontal matrix extended, assemble old L/Usons from new rows/cols */
1023
/* ---------------------------------------------------------------------- */
1025
/* ---------------------------------------------------------------------- */
1026
/* SCAN2-row: assemble rows of old Lsons from the new rows */
1027
/* ---------------------------------------------------------------------- */
1030
DEBUG7 (("Current frontal matrix: (prior to scan2-row)\n")) ;
1031
UMF_dump_current_front (Numeric, Work, TRUE) ;
1034
/* rescan the pivot row */
1037
row_assemble (Work->pivrow, Numeric, Work) ;
1040
if (Work->do_scan2row)
1042
for (i2 = Work->fscan_row ; i2 < fnrows ; i2++)
1045
row = Work->NewRows [i2] ;
1046
if (row < 0) row = FLIP (row) ;
1047
ASSERT (row >= 0 && row < n_row) ;
1048
if (!(row == Work->pivrow && Work->any_skip))
1051
row_assemble (row, Numeric, Work) ;
1056
/* ---------------------------------------------------------------------- */
1057
/* SCAN2-col: assemble columns of old Usons from the new columns */
1058
/* ---------------------------------------------------------------------- */
1061
DEBUG7 (("Current frontal matrix: (prior to scan2-col)\n")) ;
1062
UMF_dump_current_front (Numeric, Work, TRUE) ;
1065
/* rescan the pivot col */
1068
col_assemble (Work->pivcol, Numeric, Work) ;
1071
if (Work->do_scan2col)
1074
for (j2 = Work->fscan_col ; j2 < fncols ; j2++)
1077
col = Work->NewCols [j2] ;
1078
if (col < 0) col = FLIP (col) ;
1079
ASSERT (col >= 0 && col < n_col) ;
1080
if (!(col == Work->pivcol && Work->any_skip))
1083
col_assemble (col, Numeric, Work) ;
1088
/* ---------------------------------------------------------------------- */
1089
/* done. the remainder of this routine is used only when in debug mode */
1090
/* ---------------------------------------------------------------------- */
1094
/* ---------------------------------------------------------------------- */
1095
/* when debugging: make sure the assembly did everything that it could */
1096
/* ---------------------------------------------------------------------- */
1098
DEBUG3 (("::Assemble done\n")) ;
1100
for (i2 = 0 ; i2 < fnrows ; i2++)
1103
row = Work->Frows [i2] ;
1104
ASSERT (row >= 0 && row < n_row) ;
1106
DEBUG6 (("DEBUG SCAN 1: "ID"\n", row)) ;
1107
UMF_dump_rowcol (0, Numeric, Work, row, TRUE) ;
1109
ASSERT (NON_PIVOTAL_ROW (row)) ;
1110
tpi = Row_tuples [row] ;
1111
if (!tpi) continue ;
1112
tp = (Tuple *) (Memory + tpi) ;
1113
tpend = tp + Row_tlen [row] ;
1114
for ( ; tp < tpend ; tp++)
1117
ASSERT (e > 0 && e <= Work->nel) ;
1118
if (!E [e]) continue ; /* element already deallocated */
1120
p = Memory + E [e] ;
1121
ep = (Element *) p ;
1122
p += UNITS (Element, 1) ;
1124
Rows = ((Int *) p) + ep->ncols ;
1125
if (Rows [f] == EMPTY) continue ; /* row already assembled */
1126
ASSERT (row == Rows [f]) ;
1127
extrdeg = (ep->rdeg < rdeg0) ? ep->ncolsleft : (ep->rdeg - rdeg0) ;
1128
extcdeg = (ep->cdeg < cdeg0) ? ep->nrowsleft : (ep->cdeg - cdeg0) ;
1130
"e "ID" After assembly ext row deg: "ID" ext col degree "ID"\n",
1131
e, extrdeg, extcdeg)) ;
1135
/* no Lsons in any row, except for very tall and thin ones */
1136
ASSERT (extrdeg >= 0) ;
1139
/* this is an unassemble Lson */
1140
ASSERT (ep->ncols == 1) ;
1141
ASSERT (ep->ncolsleft == 1) ;
1143
ASSERT (col != Work->pivcol) ;
1148
/* no Lsons in any row */
1149
ASSERT (extrdeg > 0) ;
1150
/* Uson external row degree is = number of cols left */
1151
ASSERT (IMPLIES (extcdeg == 0, extrdeg == ep->ncolsleft)) ;
1156
/* ---------------------------------------------------------------------- */
1158
for (j2 = 0 ; j2 < fncols ; j2++)
1161
col = Work->Fcols [j2] ;
1162
ASSERT (col >= 0 && col < n_col) ;
1164
DEBUG6 (("DEBUG SCAN 2: "ID"\n", col)) ;
1166
UMF_dump_rowcol (1, Numeric, Work, col, TRUE) ;
1168
UMF_dump_rowcol (1, Numeric, Work, col, FALSE) ;
1171
ASSERT (NON_PIVOTAL_COL (col)) ;
1172
tpi = Col_tuples [col] ;
1173
if (!tpi) continue ;
1174
tp = (Tuple *) (Memory + tpi) ;
1175
tpend = tp + Col_tlen [col] ;
1176
for ( ; tp < tpend ; tp++)
1179
ASSERT (e > 0 && e <= Work->nel) ;
1180
if (!E [e]) continue ; /* element already deallocated */
1182
p = Memory + E [e] ;
1183
ep = (Element *) p ;
1184
p += UNITS (Element, 1) ;
1186
Rows = ((Int *) p) + ep->ncols ;
1187
if (Cols [f] == EMPTY) continue ; /* column already assembled */
1188
ASSERT (col == Cols [f]) ;
1189
extrdeg = (ep->rdeg < rdeg0) ? ep->ncolsleft : (ep->rdeg - rdeg0) ;
1190
extcdeg = (ep->cdeg < cdeg0) ? ep->nrowsleft : (ep->cdeg - cdeg0) ;
1191
DEBUG6 (("e "ID" After assembly ext col deg: "ID"\n", e, extcdeg)) ;
1195
/* no Usons in any column, except for very tall and thin ones */
1196
ASSERT (extcdeg >= 0) ;
1199
/* this is an unassemble Uson */
1200
ASSERT (ep->nrows == 1) ;
1201
ASSERT (ep->nrowsleft == 1) ;
1203
ASSERT (row != Work->pivrow) ;
1208
/* no Usons in any column */
1209
ASSERT (extcdeg > 0) ;
1210
/* Lson external column degree is = number of rows left */
1211
ASSERT (IMPLIES (extrdeg == 0, extcdeg == ep->nrowsleft)) ;