~ubuntu-branches/ubuntu/raring/python-scipy/raring-proposed

« back to all changes in this revision

Viewing changes to Lib/sandbox/pysparse/umfpack/umf_create_element.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2007-01-07 14:12:12 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20070107141212-mm0ebkh5b37hcpzn
* Remove build dependency on python-numpy-dev.
* python-scipy: Depend on python-numpy instead of python-numpy-dev.
* Package builds on other archs than i386. Closes: #402783.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ========================================================================== */
 
2
/* === UMF_create_element =================================================== */
 
3
/* ========================================================================== */
 
4
 
 
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
/* -------------------------------------------------------------------------- */
 
11
 
 
12
/*
 
13
    Factorization of a frontal matrix is complete.  Create a new element for
 
14
    later assembly into a subsequent frontal matrix.  Returns TRUE if
 
15
    successful, FALSE if out of memory.
 
16
*/
 
17
 
 
18
#include "umf_internal.h"
 
19
#include "umf_mem_alloc_element.h"
 
20
#include "umf_mem_alloc_tail_block.h"
 
21
#include "umf_mem_free_tail_block.h"
 
22
#include "umf_get_memory.h"
 
23
 
 
24
/* ========================================================================== */
 
25
/* === copy_column ========================================================== */
 
26
/* ========================================================================== */
 
27
 
 
28
PRIVATE void copy_column (Int len, Entry *X, Entry *Y)
 
29
{
 
30
    Int i ;
 
31
#pragma ivdep
 
32
    for (i = 0 ; i < len ; i++)
 
33
    {
 
34
        Y [i] = X [i] ;
 
35
    }
 
36
}
 
37
 
 
38
/* ========================================================================== */
 
39
/* === UMF_create_element =================================================== */
 
40
/* ========================================================================== */
 
41
 
 
42
GLOBAL Int UMF_create_element
 
43
(
 
44
    NumericType *Numeric,
 
45
    WorkType *Work,
 
46
    SymbolicType *Symbolic
 
47
)
 
48
{
 
49
    /* ---------------------------------------------------------------------- */
 
50
    /* local variables */
 
51
    /* ---------------------------------------------------------------------- */
 
52
 
 
53
    Int j, col, row, *Fcols, *Frows, fnrows, fncols, *Cols, len, needunits, t1,
 
54
        t2, size, e, i, *E, *Fcpos, *Frpos, *Rows, eloc, fnr_curr, f,
 
55
        got_memory, *Row_tuples, *Row_degree, *Row_tlen, *Col_tuples, max_mark,
 
56
        *Col_degree, *Col_tlen, nn, n_row, n_col, r2, c2, do_Fcpos ;
 
57
    Entry *C, *Fcol ;
 
58
    Element *ep ;
 
59
    Unit *p, *Memory ;
 
60
    Tuple *tp, *tp1, *tp2, tuple, *tpend ;
 
61
#ifndef NDEBUG
 
62
    DEBUG2 (("FRONTAL WRAPUP\n")) ;
 
63
    UMF_dump_current_front (Numeric, Work, TRUE) ;
 
64
#endif
 
65
 
 
66
    /* ---------------------------------------------------------------------- */
 
67
    /* get parameters */
 
68
    /* ---------------------------------------------------------------------- */
 
69
 
 
70
    ASSERT (Work->fnpiv == 0) ;
 
71
    ASSERT (Work->fnzeros == 0) ;
 
72
    Row_degree = Numeric->Rperm ;
 
73
    Row_tuples = Numeric->Uip ;
 
74
    Row_tlen   = Numeric->Uilen ;
 
75
    Col_degree = Numeric->Cperm ;
 
76
    Col_tuples = Numeric->Lip ;
 
77
    Col_tlen   = Numeric->Lilen ;
 
78
    n_row = Work->n_row ;
 
79
    n_col = Work->n_col ;
 
80
    nn = MAX (n_row, n_col) ;
 
81
    Fcols = Work->Fcols ;
 
82
    Frows = Work->Frows ;
 
83
    Fcpos = Work->Fcpos ;
 
84
    Frpos = Work->Frpos ;
 
85
    Memory = Numeric->Memory ;
 
86
    fncols = Work->fncols ;
 
87
    fnrows = Work->fnrows ;
 
88
 
 
89
    tp = (Tuple *) NULL ;
 
90
    tp1 = (Tuple *) NULL ;
 
91
    tp2 = (Tuple *) NULL ;
 
92
 
 
93
    /* ---------------------------------------------------------------------- */
 
94
    /* add the current frontal matrix to the degrees of each column */
 
95
    /* ---------------------------------------------------------------------- */
 
96
 
 
97
    if (!Symbolic->fixQ)
 
98
    {
 
99
        /* but only if the column ordering is not fixed */
 
100
#pragma ivdep
 
101
        for (j = 0 ; j < fncols ; j++)
 
102
        {
 
103
            /* add the current frontal matrix to the degree */
 
104
            ASSERT (Fcols [j] >= 0 && Fcols [j] < n_col) ;
 
105
            Col_degree [Fcols [j]] += fnrows ;
 
106
        }
 
107
    }
 
108
 
 
109
    /* ---------------------------------------------------------------------- */
 
110
    /* add the current frontal matrix to the degrees of each row */
 
111
    /* ---------------------------------------------------------------------- */
 
112
 
 
113
#pragma ivdep
 
114
    for (i = 0 ; i < fnrows ; i++)
 
115
    {
 
116
        /* add the current frontal matrix to the degree */
 
117
        ASSERT (Frows [i] >= 0 && Frows [i] < n_row) ;
 
118
        Row_degree [Frows [i]] += fncols ;
 
119
    }
 
120
 
 
121
    /* ---------------------------------------------------------------------- */
 
122
    /* Reset the external degree counters */
 
123
    /* ---------------------------------------------------------------------- */
 
124
 
 
125
    E = Work->E ;
 
126
    max_mark = MAX_MARK (nn) ;
 
127
 
 
128
    if (!Work->pivcol_in_front)
 
129
    {
 
130
        /* clear the external column degrees. no more Usons of current front */
 
131
        Work->cdeg0 += (nn + 1) ;
 
132
        if (Work->cdeg0 >= max_mark)
 
133
        {
 
134
            /* guard against integer overflow.  This is very rare */
 
135
            DEBUG1 (("Integer overflow, cdeg\n")) ;
 
136
            Work->cdeg0 = 1 ;
 
137
#pragma ivdep
 
138
            for (e = 1 ; e <= Work->nel ; e++)
 
139
            {
 
140
                if (E [e])
 
141
                {
 
142
                    ep = (Element *) (Memory + E [e]) ;
 
143
                    ep->cdeg = 0 ;
 
144
                }
 
145
            }
 
146
        }
 
147
    }
 
148
 
 
149
    if (!Work->pivrow_in_front)
 
150
    {
 
151
        /* clear the external row degrees.  no more Lsons of current front */
 
152
        Work->rdeg0 += (nn + 1) ;
 
153
        if (Work->rdeg0 >= max_mark)
 
154
        {
 
155
            /* guard against integer overflow.  This is very rare */
 
156
            DEBUG1 (("Integer overflow, rdeg\n")) ;
 
157
            Work->rdeg0 = 1 ;
 
158
#pragma ivdep
 
159
            for (e = 1 ; e <= Work->nel ; e++)
 
160
            {
 
161
                if (E [e])
 
162
                {
 
163
                    ep = (Element *) (Memory + E [e]) ;
 
164
                    ep->rdeg = 0 ;
 
165
                }
 
166
            }
 
167
        }
 
168
    }
 
169
 
 
170
    /* ---------------------------------------------------------------------- */
 
171
    /* clear row/col offsets */
 
172
    /* ---------------------------------------------------------------------- */
 
173
 
 
174
    if (!Work->pivrow_in_front)
 
175
    {
 
176
#pragma ivdep
 
177
        for (j = 0 ; j < fncols ; j++)
 
178
        {
 
179
            Fcpos [Fcols [j]] = EMPTY ;
 
180
        }
 
181
    }
 
182
 
 
183
    if (!Work->pivcol_in_front)
 
184
    {
 
185
#pragma ivdep
 
186
        for (i = 0 ; i < fnrows ; i++)
 
187
        {
 
188
            Frpos [Frows [i]] = EMPTY ;
 
189
        }
 
190
    }
 
191
 
 
192
    if (fncols <= 0 || fnrows <= 0)
 
193
    {
 
194
        /* no element to create */
 
195
        DEBUG2 (("Element evaporation\n")) ;
 
196
        Work->prior_element = EMPTY ;
 
197
        return (TRUE) ;
 
198
    }
 
199
 
 
200
    /* ---------------------------------------------------------------------- */
 
201
    /* create element for later assembly */
 
202
    /* ---------------------------------------------------------------------- */
 
203
 
 
204
#ifndef NDEBUG
 
205
    UMF_allocfail = FALSE ;
 
206
    if (UMF_gprob > 0)
 
207
    {
 
208
        double rrr = ((double) (rand ( ))) / (((double) RAND_MAX) + 1) ;
 
209
        DEBUG4 (("Check random %e %e\n", rrr, UMF_gprob)) ;
 
210
        UMF_allocfail = rrr < UMF_gprob ;
 
211
        if (UMF_allocfail) DEBUGm2 (("Random garbage collection (create)\n"));
 
212
    }
 
213
#endif
 
214
 
 
215
    needunits = 0 ;
 
216
    got_memory = FALSE ;
 
217
    eloc = UMF_mem_alloc_element (Numeric, fnrows, fncols, &Rows, &Cols, &C,
 
218
        &needunits, &ep) ;
 
219
 
 
220
    /* if UMF_get_memory needs to be called */
 
221
    if (Work->do_grow)
 
222
    {
 
223
        /* full compaction of current frontal matrix, since UMF_grow_front will
 
224
         * be called next anyway. */
 
225
        r2 = fnrows ;
 
226
        c2 = fncols ;
 
227
        do_Fcpos = FALSE ;
 
228
    }
 
229
    else
 
230
    {
 
231
        /* partial compaction. */
 
232
        r2 = MAX (fnrows, Work->fnrows_new + 1) ;
 
233
        c2 = MAX (fncols, Work->fncols_new + 1) ;
 
234
        /* recompute Fcpos if pivot row is in the front */
 
235
        do_Fcpos = Work->pivrow_in_front ;
 
236
    }
 
237
 
 
238
    if (!eloc)
 
239
    {
 
240
        /* Do garbage collection, realloc, and try again. */
 
241
        /* Compact the current front if it needs to grow anyway. */
 
242
        /* Note that there are no pivot rows or columns in the current front */
 
243
        DEBUGm3 (("get_memory from umf_create_element, 1\n")) ;
 
244
        if (!UMF_get_memory (Numeric, Work, needunits, r2, c2, do_Fcpos))
 
245
        {
 
246
            /* :: out of memory in umf_create_element (1) :: */
 
247
            DEBUGm4 (("out of memory: create element (1)\n")) ;
 
248
            return (FALSE) ;    /* out of memory */
 
249
        }
 
250
        got_memory = TRUE ;
 
251
        Memory = Numeric->Memory ;
 
252
        eloc = UMF_mem_alloc_element (Numeric, fnrows, fncols, &Rows, &Cols, &C,
 
253
            &needunits, &ep) ;
 
254
        ASSERT (eloc >= 0) ;
 
255
        if (!eloc)
 
256
        {
 
257
            /* :: out of memory in umf_create_element (2) :: */
 
258
            DEBUGm4 (("out of memory: create element (2)\n")) ;
 
259
            return (FALSE) ;    /* out of memory */
 
260
        }
 
261
    }
 
262
 
 
263
    e = ++(Work->nel) ; /* get the name of this new frontal matrix */
 
264
    Work->prior_element = e ;
 
265
    DEBUG8 (("wrapup e "ID" nel "ID"\n", e, Work->nel)) ;
 
266
 
 
267
    ASSERT (e > 0 && e < Work->elen) ;
 
268
    ASSERT (E [e] == 0) ;
 
269
    E [e] = eloc ;
 
270
 
 
271
    if (Work->pivcol_in_front)
 
272
    {
 
273
        /* the new element is a Uson of the next frontal matrix */
 
274
        ep->cdeg = Work->cdeg0 ;
 
275
    }
 
276
 
 
277
    if (Work->pivrow_in_front)
 
278
    {
 
279
        /* the new element is an Lson of the next frontal matrix */
 
280
        ep->rdeg = Work->rdeg0 ;
 
281
    }
 
282
 
 
283
    /* ---------------------------------------------------------------------- */
 
284
    /* copy frontal matrix into the new element */
 
285
    /* ---------------------------------------------------------------------- */
 
286
 
 
287
#pragma ivdep
 
288
    for (i = 0 ; i < fnrows ; i++)
 
289
    {
 
290
        Rows [i] = Frows [i] ;
 
291
    }
 
292
#pragma ivdep
 
293
    for (i = 0 ; i < fncols ; i++)
 
294
    {
 
295
        Cols [i] = Fcols [i] ;
 
296
    }
 
297
    Fcol = Work->Fcblock ;
 
298
    DEBUG0 (("copy front "ID" by "ID"\n", fnrows, fncols)) ;
 
299
    fnr_curr = Work->fnr_curr ;
 
300
    ASSERT (fnr_curr >= 0 && fnr_curr % 2 == 1) ;
 
301
    for (j = 0 ; j < fncols ; j++)
 
302
    {
 
303
        copy_column (fnrows, Fcol, C) ;
 
304
#if 0
 
305
#ifdef USE_NO_BLAS
 
306
        copy_column (fnrows, Fcol, C) ;
 
307
#else
 
308
        could also use BLAS-COPY (fnrows, Fcol, C) here, but it is typically
 
309
        not as fast as the inlined copy_column subroutine, above.
 
310
#endif
 
311
        for (i = 0 ; i < fnrows ; i++)
 
312
        {
 
313
            C [i] = Fcol [i] ;
 
314
        }
 
315
#endif
 
316
        Fcol += fnr_curr ;
 
317
        C += fnrows ;
 
318
    }
 
319
 
 
320
    DEBUG8 (("element copied\n")) ;
 
321
 
 
322
    /* ---------------------------------------------------------------------- */
 
323
    /* add tuples for the new element */
 
324
    /* ---------------------------------------------------------------------- */
 
325
 
 
326
    tuple.e = e ;
 
327
 
 
328
    if (got_memory)
 
329
    {
 
330
 
 
331
        /* ------------------------------------------------------------------ */
 
332
        /* UMF_get_memory ensures enough space exists for each new tuple */
 
333
        /* ------------------------------------------------------------------ */
 
334
 
 
335
        /* place (e,f) in the element list of each column */
 
336
        for (tuple.f = 0 ; tuple.f < fncols ; tuple.f++)
 
337
        {
 
338
            col = Fcols [tuple.f] ;
 
339
            ASSERT (col >= 0 && col < n_col) ;
 
340
            ASSERT (NON_PIVOTAL_COL (col)) ;
 
341
            ASSERT (Col_tuples [col]) ;
 
342
            tp = ((Tuple *) (Memory + Col_tuples [col])) + Col_tlen [col]++ ;
 
343
            *tp = tuple ;
 
344
        }
 
345
 
 
346
        /* ------------------------------------------------------------------ */
 
347
 
 
348
        /* place (e,f) in the element list of each row */
 
349
        for (tuple.f = 0 ; tuple.f < fnrows ; tuple.f++)
 
350
        {
 
351
            row = Frows [tuple.f] ;
 
352
            ASSERT (row >= 0 && row < n_row) ;
 
353
            ASSERT (NON_PIVOTAL_ROW (row)) ;
 
354
            ASSERT (Row_tuples [row]) ;
 
355
            tp = ((Tuple *) (Memory + Row_tuples [row])) + Row_tlen [row]++ ;
 
356
            *tp = tuple ;
 
357
        }
 
358
 
 
359
    }
 
360
    else
 
361
    {
 
362
 
 
363
        /* ------------------------------------------------------------------ */
 
364
        /* place (e,f) in the element list of each column */
 
365
        /* ------------------------------------------------------------------ */
 
366
 
 
367
        /* might not have enough space for each tuple */
 
368
 
 
369
        for (tuple.f = 0 ; tuple.f < fncols ; tuple.f++)
 
370
        {
 
371
            col = Fcols [tuple.f] ;
 
372
            ASSERT (col >= 0 && col < n_col) ;
 
373
            ASSERT (NON_PIVOTAL_COL (col)) ;
 
374
            t1 = Col_tuples [col] ;
 
375
            DEBUG1 (("Placing on col:"ID" , tuples at "ID"\n",
 
376
                col, Col_tuples [col])) ;
 
377
 
 
378
            size = 0 ;
 
379
            len = 0 ;
 
380
 
 
381
            if (t1)
 
382
            {
 
383
                p = Memory + t1 ;
 
384
                tp = (Tuple *) p ;
 
385
                size = GET_BLOCK_SIZE (p) ;
 
386
                len = Col_tlen [col] ;
 
387
                tp2 = tp + len ;
 
388
            }
 
389
 
 
390
            needunits = UNITS (Tuple, len + 1) ;
 
391
            DEBUG1 (("len: "ID" size: "ID" needunits: "ID"\n",
 
392
                len, size, needunits));
 
393
 
 
394
            if (needunits > size && t1)
 
395
            {
 
396
                /* prune the tuples */
 
397
                tp1 = tp ;
 
398
                tp2 = tp ;
 
399
                tpend = tp + len ;
 
400
                for ( ; tp < tpend ; tp++)
 
401
                {
 
402
                    e = tp->e ;
 
403
                    ASSERT (e > 0 && e <= Work->nel) ;
 
404
                    if (!E [e]) continue ;   /* element already deallocated */
 
405
                    f = tp->f ;
 
406
                    p = Memory + E [e] ;
 
407
                    ep = (Element *) p ;
 
408
                    p += UNITS (Element, 1) ;
 
409
                    Cols = (Int *) p ;
 
410
                    ;
 
411
                    if (Cols [f] == EMPTY) continue ;   /* already assembled */
 
412
                    ASSERT (col == Cols [f]) ;
 
413
                    *tp2++ = *tp ;      /* leave the tuple in the list */
 
414
                }
 
415
                len = tp2 - tp1 ;
 
416
                Col_tlen [col] = len ;
 
417
                needunits = UNITS (Tuple, len + 1) ;
 
418
            }
 
419
 
 
420
            if (needunits > size)
 
421
            {
 
422
                /* no room exists - reallocate elsewhere */
 
423
                DEBUG1 (("REALLOCATE Col: "ID", size "ID" to "ID"\n",
 
424
                    col, size, 2*needunits)) ;
 
425
 
 
426
#ifndef NDEBUG
 
427
                UMF_allocfail = FALSE ;
 
428
                if (UMF_gprob > 0)  /* a double relop, but ignore NaN case */
 
429
                {
 
430
                    double rrr = ((double) (rand ( ))) /
 
431
                        (((double) RAND_MAX) + 1) ;
 
432
                    DEBUG1 (("Check random %e %e\n", rrr, UMF_gprob)) ;
 
433
                    UMF_allocfail = rrr < UMF_gprob ;
 
434
                    if (UMF_allocfail) DEBUGm2 (("Random gar. (col tuple)\n")) ;
 
435
                }
 
436
#endif
 
437
 
 
438
                needunits = MIN (2*needunits, (Int) UNITS (Tuple, nn)) ;
 
439
                t2 = UMF_mem_alloc_tail_block (Numeric, needunits) ;
 
440
                if (!t2)
 
441
                {
 
442
                    /* :: get memory in umf_create_element (1) :: */
 
443
                    /* get memory, reconstruct all tuple lists, and return */
 
444
                    /* Compact the current front if it needs to grow anyway. */
 
445
                    /* Note: no pivot rows or columns in the current front */
 
446
                    DEBUGm4 (("get_memory from umf_create_element, 1\n")) ;
 
447
                    return (UMF_get_memory (Numeric, Work, 0, r2, c2,do_Fcpos));
 
448
                }
 
449
                Col_tuples [col] = t2 ;
 
450
                tp2 = (Tuple *) (Memory + t2) ;
 
451
                if (t1)
 
452
                {
 
453
                    for (i = 0 ; i < len ; i++)
 
454
                    {
 
455
                        *tp2++ = *tp1++ ;
 
456
                    }
 
457
                    UMF_mem_free_tail_block (Numeric, t1) ;
 
458
                }
 
459
            }
 
460
 
 
461
            /* place the new (e,f) tuple in the element list of the column */
 
462
            Col_tlen [col]++ ;
 
463
            *tp2 = tuple ;
 
464
        }
 
465
 
 
466
        /* ------------------------------------------------------------------ */
 
467
        /* place (e,f) in the element list of each row */
 
468
        /* ------------------------------------------------------------------ */
 
469
 
 
470
        for (tuple.f = 0 ; tuple.f < fnrows ; tuple.f++)
 
471
        {
 
472
            row = Frows [tuple.f] ;
 
473
            ASSERT (row >= 0 && row < n_row) ;
 
474
            ASSERT (NON_PIVOTAL_ROW (row)) ;
 
475
            t1 = Row_tuples [row] ;
 
476
            DEBUG1 (("Placing on row:"ID" , tuples at "ID"\n",
 
477
                row, Row_tuples [row])) ;
 
478
 
 
479
            size = 0 ;
 
480
            len = 0 ;
 
481
            if (t1)
 
482
            {
 
483
                p = Memory + t1 ;
 
484
                tp = (Tuple *) p ;
 
485
                size = GET_BLOCK_SIZE (p) ;
 
486
                len = Row_tlen [row] ;
 
487
                tp2 = tp + len ;
 
488
            }
 
489
 
 
490
            needunits = UNITS (Tuple, len + 1) ;
 
491
            DEBUG1 (("len: "ID" size: "ID" needunits: "ID"\n",
 
492
                len, size, needunits)) ;
 
493
 
 
494
            if (needunits > size && t1)
 
495
            {
 
496
                /* prune the tuples */
 
497
                tp1 = tp ;
 
498
                tp2 = tp ;
 
499
                tpend = tp + len ;
 
500
                for ( ; tp < tpend ; tp++)
 
501
                {
 
502
                    e = tp->e ;
 
503
                    ASSERT (e > 0 && e <= Work->nel) ;
 
504
                    if (!E [e])
 
505
                    {
 
506
                        continue ;      /* element already deallocated */
 
507
                    }
 
508
                    f = tp->f ;
 
509
                    p = Memory + E [e] ;
 
510
                    ep = (Element *) p ;
 
511
                    p += UNITS (Element, 1) ;
 
512
                    Cols = (Int *) p ;
 
513
                    Rows = Cols + (ep->ncols) ;
 
514
                    if (Rows [f] == EMPTY) continue ;   /* already assembled */
 
515
                    ASSERT (row == Rows [f]) ;
 
516
                    *tp2++ = *tp ;      /* leave the tuple in the list */
 
517
                }
 
518
                len = tp2 - tp1 ;
 
519
                Row_tlen [row] = len ;
 
520
                needunits = UNITS (Tuple, len + 1) ;
 
521
            }
 
522
 
 
523
            if (needunits > size)
 
524
            {
 
525
                /* no room exists - reallocate elsewhere */
 
526
                DEBUG1 (("REALLOCATE Row: "ID", size "ID" to "ID"\n",
 
527
                    row, size, 2*needunits)) ;
 
528
 
 
529
#ifndef NDEBUG
 
530
                UMF_allocfail = FALSE ;
 
531
                if (UMF_gprob > 0)  /* a double relop, but ignore NaN case */
 
532
                {
 
533
                    double rrr = ((double) (rand ( ))) /
 
534
                        (((double) RAND_MAX) + 1) ;
 
535
                    DEBUG1 (("Check random %e %e\n", rrr, UMF_gprob)) ;
 
536
                    UMF_allocfail = rrr < UMF_gprob ;
 
537
                    if (UMF_allocfail) DEBUGm2 (("Random gar. (row tuple)\n")) ;
 
538
                }
 
539
#endif
 
540
 
 
541
                needunits = MIN (2*needunits, (Int) UNITS (Tuple, nn)) ;
 
542
                t2 = UMF_mem_alloc_tail_block (Numeric, needunits) ;
 
543
                if (!t2)
 
544
                {
 
545
                    /* :: get memory in umf_create_element (2) :: */
 
546
                    /* get memory, reconstruct all tuple lists, and return */
 
547
                    /* Compact the current front if it needs to grow anyway. */
 
548
                    /* Note: no pivot rows or columns in the current front */
 
549
                    DEBUGm4 (("get_memory from umf_create_element, 2\n")) ;
 
550
                    return (UMF_get_memory (Numeric, Work, 0, r2, c2,do_Fcpos));
 
551
                }
 
552
                Row_tuples [row] = t2 ;
 
553
                tp2 = (Tuple *) (Memory + t2) ;
 
554
                if (t1)
 
555
                {
 
556
                    for (i = 0 ; i < len ; i++)
 
557
                    {
 
558
                        *tp2++ = *tp1++ ;
 
559
                    }
 
560
                    UMF_mem_free_tail_block (Numeric, t1) ;
 
561
                }
 
562
            }
 
563
 
 
564
            /* place the new (e,f) tuple in the element list of the row */
 
565
            Row_tlen [row]++ ;
 
566
            *tp2 = tuple ;
 
567
        }
 
568
 
 
569
    }
 
570
 
 
571
    /* ---------------------------------------------------------------------- */
 
572
 
 
573
#ifndef NDEBUG
 
574
    DEBUG1 (("Done extending\nFINAL: element row pattern: len="ID"\n", fncols));
 
575
    for (j = 0 ; j < fncols ; j++) DEBUG1 ((""ID"\n", Fcols [j])) ;
 
576
    DEBUG1 (("FINAL: element col pattern:  len="ID"\n", fnrows)) ;
 
577
    for (j = 0 ; j < fnrows ; j++) DEBUG1 ((""ID"\n", Frows [j])) ;
 
578
    for (j = 0 ; j < fncols ; j++)
 
579
    {
 
580
        col = Fcols [j] ;
 
581
        ASSERT (col >= 0 && col < n_col) ;
 
582
        UMF_dump_rowcol (1, Numeric, Work, col, !Symbolic->fixQ) ;
 
583
    }
 
584
    for (j = 0 ; j < fnrows ; j++)
 
585
    {
 
586
        row = Frows [j] ;
 
587
        ASSERT (row >= 0 && row < n_row) ;
 
588
        UMF_dump_rowcol (0, Numeric, Work, row, TRUE) ;
 
589
    }
 
590
    if (n_row < 1000 && n_col < 1000)
 
591
    {
 
592
        UMF_dump_memory (Numeric) ;
 
593
    }
 
594
    DEBUG1 (("New element, after filling with stuff: "ID"\n", e)) ;
 
595
    UMF_dump_element (Numeric, Work, e, TRUE) ;
 
596
    if (nn < 1000)
 
597
    {
 
598
        DEBUG4 (("Matrix dump, after New element: "ID"\n", e)) ;
 
599
        UMF_dump_matrix (Numeric, Work, TRUE) ;
 
600
    }
 
601
    DEBUG3 (("FRONTAL WRAPUP DONE\n")) ;
 
602
#endif
 
603
 
 
604
    return (TRUE) ;
 
605
}