SCM

SCM Repository

[matrix] Annotation of /pkg/Matrix/src/CHOLMOD/Core/cholmod_change_factor.c
ViewVC logotype

Annotation of /pkg/Matrix/src/CHOLMOD/Core/cholmod_change_factor.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2586 - (view) (download) (as text)

1 : bates 912 /* ========================================================================== */
2 :     /* === Core/cholmod_change_factor =========================================== */
3 :     /* ========================================================================== */
4 :    
5 :     /* -----------------------------------------------------------------------------
6 : bates 1876 * CHOLMOD/Core Module. Copyright (C) 2005-2006,
7 : bates 1515 * Univ. of Florida. Author: Timothy A. Davis
8 : bates 912 * The CHOLMOD/Core Module is licensed under Version 2.1 of the GNU
9 :     * Lesser General Public License. See lesser.txt for a text of the license.
10 :     * CHOLMOD is also available under other licenses; contact authors for details.
11 :     * http://www.cise.ufl.edu/research/sparse
12 :     * -------------------------------------------------------------------------- */
13 :    
14 :     /* Change the numeric/symbolic, LL/LDL, simplicial/super, packed/unpacked,
15 :     * monotonic/non-monotonic status of a cholmod_factor object.
16 :     *
17 :     * There are four basic classes of factor types:
18 :     *
19 :     * (1) simplicial symbolic: Consists of two size-n arrays: the fill-reducing
20 :     * permutation (L->Perm) and the nonzero count for each column of L
21 :     * (L->ColCount). All other factor types also include this information.
22 :     * L->ColCount may be exact (obtained from the analysis routines), or
23 :     * it may be a guess. During factorization, and certainly after update/
24 :     * downdate, the columns of L can have a different number of nonzeros.
25 :     * L->ColCount is used to allocate space. L->ColCount is exact for the
26 :     * supernodal factorizations. The nonzero pattern of L is not kept.
27 :     *
28 :     * (2) simplicial numeric: These represent L in a compressed column form. The
29 :     * variants of this type are:
30 :     *
31 :     * LDL': L is unit diagonal. Row indices in column j are located in
32 :     * L->i [L->p [j] ... L->p [j] + L->nz [j]], and corresponding numeric
33 :     * values are in the same locations in L->x. The total number of
34 :     * entries is the sum of L->nz [j]. The unit diagonal is not stored;
35 :     * D is stored on the diagonal of L instead. L->p may or may not be
36 :     * monotonic. The order of storage of the columns in L->i and L->x is
37 :     * given by a doubly-linked list (L->prev and L->next). L->p is of
38 :     * size n+1, but only the first n entries are used (it is used if L
39 :     * is converted to a sparse matrix via cholmod_factor_to_sparse).
40 :     *
41 :     * For the complex case, L->x is stored interleaved with real/imag
42 :     * parts, and is of size 2*lnz*sizeof(double). For the zomplex case,
43 :     * L->x is of size lnz*sizeof(double) and holds the real part; L->z
44 :     * is the same size and holds the imaginary part.
45 :     *
46 :     * LL': This is identical to the LDL' form, except that the non-unit
47 :     * diagonal of L is stored as the first entry in each column of L.
48 :     *
49 :     * (3) supernodal symbolic: A representation of the nonzero pattern of the
50 :     * supernodes for a supernodal factorization. There are L->nsuper
51 :     * supernodes. Columns L->super [k] to L->super [k+1]-1 are in the kth
52 :     * supernode. The row indices for the kth supernode are in
53 :     * L->s [L->pi [k] ... L->pi [k+1]-1]. The numerical values are not
54 :     * allocated (L->x), but when they are they will be located in
55 :     * L->x [L->px [k] ... L->px [k+1]-1], and the L->px array is defined
56 :     * in this factor type.
57 :     *
58 :     * For the complex case, L->x is stored interleaved with real/imag parts,
59 :     * and is of size 2*L->xsize*sizeof(double). The zomplex supernodal case
60 :     * is not supported, since it is not compatible with LAPACK and the BLAS.
61 :     *
62 :     * (4) supernodal numeric: Always an LL' factorization. L is non-unit
63 :     * diagonal. L->x contains the numerical values of the supernodes, as
64 :     * described above for the supernodal symbolic factor.
65 :     * For the complex case, L->x is stored interleaved, and is of size
66 :     * 2*L->xsize*sizeof(double). The zomplex supernodal case is not
67 :     * supported, since it is not compatible with LAPACK and the BLAS.
68 :     *
69 :     * FUTURE WORK: support a supernodal LDL' factor.
70 :     *
71 :     *
72 :     * In all cases, the row indices in each column (L->i for simplicial L and
73 :     * L->s for supernodal L) are kept sorted from low indices to high indices.
74 :     * This means the diagonal of L (or D for LDL' factors) is always kept as the
75 :     * first entry in each column.
76 :     *
77 :     * The cholmod_change_factor routine can do almost all possible conversions.
78 :     * It cannot do the following conversions:
79 :     *
80 :     * (1) Simplicial numeric types cannot be converted to a supernodal
81 :     * symbolic type. This would simultaneously deallocate the
82 :     * simplicial pattern and numeric values and reallocate uninitialized
83 :     * space for the supernodal pattern. This isn't useful for the user,
84 :     * and not needed by CHOLMOD's own routines either.
85 :     *
86 :     * (2) Only a symbolic factor (simplicial to supernodal) can be converted
87 :     * to a supernodal numeric factor.
88 :     *
89 :     * Some conversions are meant only to be used internally by other CHOLMOD
90 :     * routines, and should not be performed by the end user. They allocate space
91 :     * whose contents are undefined:
92 :     *
93 :     * (1) converting from simplicial symbolic to supernodal symbolic.
94 :     * (2) converting any factor to supernodal numeric.
95 :     *
96 :     * workspace: no conversion routine uses workspace in Common. No temporary
97 :     * workspace is allocated.
98 :     *
99 :     * Supports all xtypes, except that there is no supernodal zomplex L.
100 :     *
101 :     * The to_xtype parameter is used only when converting from symbolic to numeric
102 :     * or numeric to symbolic. It cannot be used to convert a numeric xtype (real,
103 :     * complex, or zomplex) to a different numeric xtype. For that conversion,
104 :     * use cholmod_factor_xtype instead.
105 :     */
106 :    
107 : bates 1515 #include "cholmod_internal.h"
108 : bates 912 #include "cholmod_core.h"
109 :    
110 :     static void natural_list (cholmod_factor *L) ;
111 :    
112 :     /* ========================================================================== */
113 :     /* === TEMPLATE ============================================================= */
114 :     /* ========================================================================== */
115 :    
116 :     #define REAL
117 :     #include "t_cholmod_change_factor.c"
118 :     #define COMPLEX
119 :     #include "t_cholmod_change_factor.c"
120 :     #define ZOMPLEX
121 :     #include "t_cholmod_change_factor.c"
122 :    
123 :    
124 :     /* ========================================================================== */
125 :     /* === L_is_packed ========================================================== */
126 :     /* ========================================================================== */
127 :    
128 :     /* Return TRUE if the columns of L are packed, FALSE otherwise. For debugging
129 :     * only. */
130 :    
131 :     #ifndef NDEBUG
132 :     static int L_is_packed (cholmod_factor *L, cholmod_common *Common)
133 :     {
134 :     Int j ;
135 :     Int *Lnz = L->nz ;
136 :     Int *Lp = L->p ;
137 :     Int n = L->n ;
138 :    
139 :     if (L->xtype == CHOLMOD_PATTERN || L->is_super)
140 :     {
141 :     return (TRUE) ;
142 :     }
143 :    
144 :     if (Lnz == NULL || Lp == NULL)
145 :     {
146 :     return (TRUE) ;
147 :     }
148 :    
149 :     for (j = 0 ; j < n ; j++)
150 :     {
151 :     PRINT3 (("j: "ID" Lnz "ID" Lp[j+1] "ID" Lp[j] "ID"\n", j, Lnz [j],
152 :     Lp [j+1], Lp [j])) ;
153 :     if (Lnz [j] != (Lp [j+1] - Lp [j]))
154 :     {
155 :     PRINT2 (("L is not packed\n")) ;
156 :     return (FALSE) ;
157 :     }
158 :     }
159 :     return (TRUE) ;
160 :     }
161 :     #endif
162 :    
163 :    
164 :     /* ========================================================================== */
165 :     /* === natural_list ========================================================= */
166 :     /* ========================================================================== */
167 :    
168 :     /* Create a naturally-ordered doubly-linked list of columns. */
169 :    
170 :     static void natural_list (cholmod_factor *L)
171 :     {
172 :     Int head, tail, n, j ;
173 :     Int *Lnext, *Lprev ;
174 :     Lnext = L->next ;
175 :     Lprev = L->prev ;
176 :     ASSERT (Lprev != NULL && Lnext != NULL) ;
177 :     n = L->n ;
178 :     head = n+1 ;
179 :     tail = n ;
180 :     Lnext [head] = 0 ;
181 :     Lprev [head] = EMPTY ;
182 :     Lnext [tail] = EMPTY ;
183 :     Lprev [tail] = n-1 ;
184 :     for (j = 0 ; j < n ; j++)
185 :     {
186 :     Lnext [j] = j+1 ;
187 :     Lprev [j] = j-1 ;
188 :     }
189 :     Lprev [0] = head ;
190 :     L->is_monotonic = TRUE ;
191 :     }
192 :    
193 :    
194 :     /* ========================================================================== */
195 :     /* === allocate_simplicial_numeric ========================================== */
196 :     /* ========================================================================== */
197 :    
198 :     /* Allocate O(n) arrays for simplicial numeric factorization. Initializes
199 :     * the link lists only. Does not allocate the L->i, L->x, or L->z arrays. */
200 :    
201 :     static int allocate_simplicial_numeric
202 :     (
203 :     cholmod_factor *L,
204 :     cholmod_common *Common
205 :     )
206 :     {
207 :     Int n ;
208 :     Int *Lp, *Lnz, *Lprev, *Lnext ;
209 : bates 1515 size_t n1, n2 ;
210 : bates 912
211 :     PRINT1 (("Allocate simplicial\n")) ;
212 :    
213 :     ASSERT (L->xtype == CHOLMOD_PATTERN || L->is_super) ;
214 :     ASSERT (L->p == NULL) ;
215 :     ASSERT (L->nz == NULL) ;
216 :     ASSERT (L->prev == NULL) ;
217 :     ASSERT (L->next == NULL) ;
218 :    
219 :     n = L->n ;
220 :    
221 : bates 1515 /* this cannot cause size_t overflow */
222 :     n1 = ((size_t) n) + 1 ;
223 :     n2 = ((size_t) n) + 2 ;
224 :    
225 :     Lp = CHOLMOD(malloc) (n1, sizeof (Int), Common) ;
226 : bates 912 Lnz = CHOLMOD(malloc) (n, sizeof (Int), Common) ;
227 : bates 1515 Lprev = CHOLMOD(malloc) (n2, sizeof (Int), Common) ;
228 :     Lnext = CHOLMOD(malloc) (n2, sizeof (Int), Common) ;
229 : bates 912
230 :     if (Common->status < CHOLMOD_OK)
231 :     {
232 : bates 1515 CHOLMOD(free) (n1, sizeof (Int), Lp, Common) ;
233 : bates 912 CHOLMOD(free) (n, sizeof (Int), Lnz, Common) ;
234 : bates 1515 CHOLMOD(free) (n2, sizeof (Int), Lprev, Common) ;
235 :     CHOLMOD(free) (n2, sizeof (Int), Lnext, Common) ;
236 : bates 912 PRINT1 (("Allocate simplicial failed\n")) ;
237 :     return (FALSE) ; /* out of memory */
238 :     }
239 :    
240 :     /* ============================================== commit the changes to L */
241 :    
242 :     L->p = Lp ;
243 :     L->nz = Lnz ;
244 :     L->prev = Lprev ;
245 :     L->next = Lnext ;
246 :     /* initialize a doubly linked list for columns in natural order */
247 :     natural_list (L) ;
248 :     PRINT1 (("Allocate simplicial done\n")) ;
249 :     return (TRUE) ;
250 :     }
251 :    
252 :    
253 :     /* ========================================================================== */
254 :     /* === simplicial_symbolic_to_super_symbolic ================================ */
255 :     /* ========================================================================== */
256 :    
257 :     /* Convert a simplicial symbolic factor supernodal symbolic factor. Does not
258 :     * initialize the new space. */
259 :    
260 :     static int simplicial_symbolic_to_super_symbolic
261 :     (
262 :     cholmod_factor *L,
263 :     cholmod_common *Common
264 :     )
265 :     {
266 :     Int nsuper, xsize, ssize ;
267 :     Int *Lsuper, *Lpi, *Lpx, *Ls ;
268 : bates 1515 size_t nsuper1 ;
269 : bates 912
270 :     ASSERT (L->xtype == CHOLMOD_PATTERN && !(L->is_super)) ;
271 :    
272 :     xsize = L->xsize ;
273 :     ssize = L->ssize ;
274 :     nsuper = L->nsuper ;
275 : bates 1515 nsuper1 = ((size_t) nsuper) + 1 ;
276 : bates 912
277 :     PRINT1 (("simple sym to super sym: ssize "ID" xsize "ID" nsuper "ID""
278 :     " status %d\n", ssize, xsize, nsuper, Common->status)) ;
279 :    
280 :     /* O(nsuper) arrays, where nsuper <= n */
281 : bates 1515 Lsuper = CHOLMOD(malloc) (nsuper1, sizeof (Int), Common) ;
282 :     Lpi = CHOLMOD(malloc) (nsuper1, sizeof (Int), Common) ;
283 :     Lpx = CHOLMOD(malloc) (nsuper1, sizeof (Int), Common) ;
284 : bates 912
285 :     /* O(ssize) array, where ssize <= nnz(L), and usually much smaller */
286 :     Ls = CHOLMOD(malloc) (ssize, sizeof (Int), Common) ;
287 :    
288 :     if (Common->status < CHOLMOD_OK)
289 :     {
290 : bates 1515 CHOLMOD(free) (nsuper1, sizeof (Int), Lsuper, Common) ;
291 :     CHOLMOD(free) (nsuper1, sizeof (Int), Lpi, Common) ;
292 :     CHOLMOD(free) (nsuper1, sizeof (Int), Lpx, Common) ;
293 : bates 912 CHOLMOD(free) (ssize, sizeof (Int), Ls, Common) ;
294 :     return (FALSE) ; /* out of memory */
295 :     }
296 :    
297 :     /* ============================================== commit the changes to L */
298 :    
299 :     ASSERT (Lsuper != NULL && Lpi != NULL && Lpx != NULL && Ls != NULL) ;
300 :    
301 :     L->maxcsize = 0 ;
302 :     L->maxesize = 0 ;
303 :    
304 :     L->super = Lsuper ;
305 :     L->pi = Lpi ;
306 :     L->px = Lpx ;
307 :     L->s = Ls ;
308 :     Ls [0] = EMPTY ; /* supernodal pattern undefined */
309 :    
310 :     L->is_super = TRUE ;
311 :     L->is_ll = TRUE ; /* supernodal LDL' not supported */
312 :     L->xtype = CHOLMOD_PATTERN ;
313 :     L->dtype = DTYPE ;
314 :     L->minor = L->n ;
315 :     return (TRUE) ;
316 :     }
317 :    
318 :    
319 :     /* ========================================================================== */
320 :     /* === any_to_simplicial_symbolic =========================================== */
321 :     /* ========================================================================== */
322 :    
323 :     /* Convert any factor L to a simplicial symbolic factor, leaving only L->Perm
324 :     * and L->ColCount. Cannot fail. Any of the components of L (except Perm and
325 :     * ColCount) may already be free'd. */
326 :    
327 :     static void any_to_simplicial_symbolic
328 :     (
329 :     cholmod_factor *L,
330 :     int to_ll,
331 :     cholmod_common *Common
332 :     )
333 :     {
334 :     Int n, lnz, xs, ss, s, e ;
335 : bates 1515 size_t n1, n2 ;
336 : bates 912
337 :     /* ============================================== commit the changes to L */
338 :    
339 :     n = L->n ;
340 :     lnz = L->nzmax ;
341 :     s = L->nsuper + 1 ;
342 :     xs = (L->is_super) ? ((Int) (L->xsize)) : (lnz) ;
343 :     e = (L->xtype == CHOLMOD_COMPLEX ? 2 : 1) ;
344 :     ss = L->ssize ;
345 :    
346 : bates 1515 /* this cannot cause size_t overflow */
347 :     n1 = ((size_t) n) + 1 ;
348 :     n2 = ((size_t) n) + 2 ;
349 :    
350 : bates 912 /* free all but the symbolic analysis (Perm and ColCount) */
351 : bates 1515 L->p = CHOLMOD(free) (n1, sizeof (Int), L->p, Common) ;
352 : bates 912 L->i = CHOLMOD(free) (lnz, sizeof (Int), L->i, Common) ;
353 :     L->x = CHOLMOD(free) (xs, e*sizeof (double), L->x, Common) ;
354 :     L->z = CHOLMOD(free) (lnz, sizeof (double), L->z, Common) ;
355 :     L->nz = CHOLMOD(free) (n, sizeof (Int), L->nz, Common) ;
356 : bates 1515 L->next = CHOLMOD(free) (n2, sizeof (Int), L->next, Common) ;
357 :     L->prev = CHOLMOD(free) (n2, sizeof (Int), L->prev, Common) ;
358 : bates 912 L->super = CHOLMOD(free) (s, sizeof (Int), L->super, Common) ;
359 :     L->pi = CHOLMOD(free) (s, sizeof (Int), L->pi, Common) ;
360 :     L->px = CHOLMOD(free) (s, sizeof (Int), L->px, Common) ;
361 :     L->s = CHOLMOD(free) (ss, sizeof (Int), L->s, Common) ;
362 :     L->nzmax = 0 ;
363 :     L->is_super = FALSE ;
364 :     L->xtype = CHOLMOD_PATTERN ;
365 :     L->dtype = DTYPE ;
366 :     L->minor = n ;
367 :     L->is_ll = to_ll ;
368 :     }
369 :    
370 :    
371 :     /* ========================================================================== */
372 :     /* === ll_super_to_super_symbolic =========================================== */
373 :     /* ========================================================================== */
374 :    
375 :     /* Convert a numerical supernodal L to symbolic supernodal. Cannot fail. */
376 :    
377 :     static void ll_super_to_super_symbolic
378 :     (
379 :     cholmod_factor *L,
380 :     cholmod_common *Common
381 :     )
382 :     {
383 :    
384 :     /* ============================================== commit the changes to L */
385 :    
386 :     /* free all but the supernodal numerical factor */
387 :     ASSERT (L->xtype != CHOLMOD_PATTERN && L->is_super && L->is_ll) ;
388 :     DEBUG (CHOLMOD(dump_factor) (L, "start to super symbolic", Common)) ;
389 :     L->x = CHOLMOD(free) (L->xsize,
390 :     (L->xtype == CHOLMOD_COMPLEX ? 2 : 1) * sizeof (double), L->x,
391 :     Common) ;
392 :     L->xtype = CHOLMOD_PATTERN ;
393 :     L->dtype = DTYPE ;
394 :     L->minor = L->n ;
395 :     L->is_ll = TRUE ; /* supernodal LDL' not supported */
396 :     DEBUG (CHOLMOD(dump_factor) (L, "done to super symbolic", Common)) ;
397 :     }
398 :    
399 :    
400 :     /* ========================================================================== */
401 :     /* === simplicial_symbolic_to_simplicial_numeric ============================ */
402 :     /* ========================================================================== */
403 :    
404 :     /* Convert a simplicial symbolic L to a simplicial numeric L; allocate space
405 :     * for L using L->ColCount from symbolic analysis, and set L to identity.
406 :     *
407 :     * If packed < 0, then this routine is creating a copy of another factor
408 :     * (via cholmod_copy_factor). In this case, the space is not initialized. */
409 :    
410 :     static void simplicial_symbolic_to_simplicial_numeric
411 :     (
412 :     cholmod_factor *L,
413 :     int to_ll,
414 :     int packed,
415 :     int to_xtype,
416 :     cholmod_common *Common
417 :     )
418 :     {
419 :     double grow0, grow1, xlen, xlnz ;
420 :     double *Lx, *Lz ;
421 :     Int *Li, *Lp, *Lnz, *ColCount ;
422 :     Int n, grow, grow2, p, j, lnz, len, ok, e ;
423 :    
424 :     ASSERT (L->xtype == CHOLMOD_PATTERN && !(L->is_super)) ;
425 :     if (!allocate_simplicial_numeric (L, Common))
426 :     {
427 :     PRINT1 (("out of memory, allocate simplicial numeric\n")) ;
428 :     return ; /* out of memory */
429 :     }
430 :     ASSERT (L->ColCount != NULL && L->nz != NULL && L->p != NULL) ;
431 :     ASSERT (L->x == NULL && L->z == NULL && L->i == NULL) ;
432 :    
433 :     ColCount = L->ColCount ;
434 :     Lnz = L->nz ;
435 :     Lp = L->p ;
436 :     ok = TRUE ;
437 :     n = L->n ;
438 :    
439 :     if (packed < 0)
440 :     {
441 :    
442 :     /* ------------------------------------------------------------------ */
443 :     /* used by cholmod_copy_factor to allocate a copy of a factor object */
444 :     /* ------------------------------------------------------------------ */
445 :    
446 :     lnz = L->nzmax ;
447 :     L->nzmax = 0 ;
448 :    
449 :     }
450 :     else if (packed)
451 :     {
452 :    
453 :     /* ------------------------------------------------------------------ */
454 :     /* LDL' or LL' packed */
455 :     /* ------------------------------------------------------------------ */
456 :    
457 :     PRINT1 (("convert to packed LL' or LDL'\n")) ;
458 :     lnz = 0 ;
459 :     for (j = 0 ; ok && j < n ; j++)
460 :     {
461 :     /* ensure len is in the range 1 to n-j */
462 :     len = ColCount [j] ;
463 :     len = MAX (1, len) ;
464 :     len = MIN (len, n-j) ;
465 :     lnz += len ;
466 :     ok = (lnz >= 0) ;
467 :     }
468 :     for (j = 0 ; j <= n ; j++)
469 :     {
470 :     Lp [j] = j ;
471 :     }
472 :     for (j = 0 ; j < n ; j++)
473 :     {
474 :     Lnz [j] = 1 ;
475 :     }
476 :    
477 :     }
478 :     else
479 :     {
480 :    
481 :     /* ------------------------------------------------------------------ */
482 :     /* LDL' unpacked */
483 :     /* ------------------------------------------------------------------ */
484 :    
485 :     PRINT1 (("convert to unpacked\n")) ;
486 :     /* compute new lnzmax */
487 :     /* if any parameter is NaN, grow is false */
488 :     grow0 = Common->grow0 ;
489 :     grow1 = Common->grow1 ;
490 :     grow2 = Common->grow2 ;
491 :     grow0 = IS_NAN (grow0) ? 1 : grow0 ;
492 :     grow1 = IS_NAN (grow1) ? 1 : grow1 ;
493 :     /* fl.pt. compare, but no NaN's: */
494 :     grow = (grow0 >= 1.0) && (grow1 >= 1.0) && (grow2 > 0) ;
495 :     PRINT1 (("init, grow1 %g grow2 "ID"\n", grow1, grow2)) ;
496 :     /* initialize Lp and Lnz for each column */
497 :     lnz = 0 ;
498 :     for (j = 0 ; ok && j < n ; j++)
499 :     {
500 :     Lp [j] = lnz ;
501 :     Lnz [j] = 1 ;
502 :    
503 :     /* ensure len is in the range 1 to n-j */
504 :     len = ColCount [j] ;
505 :     len = MAX (1, len) ;
506 :     len = MIN (len, n-j) ;
507 :    
508 :     /* compute len in double to avoid integer overflow */
509 :     PRINT1 (("ColCount ["ID"] = "ID"\n", j, len)) ;
510 :     if (grow)
511 :     {
512 :     xlen = (double) len ;
513 :     xlen = grow1 * xlen + grow2 ;
514 :     xlen = MIN (xlen, n-j) ;
515 :     len = (Int) xlen ;
516 :     }
517 :     ASSERT (len >= 1 && len <= n-j) ;
518 :     lnz += len ;
519 :     ok = (lnz >= 0) ;
520 :     }
521 :     if (ok)
522 :     {
523 :     Lp [n] = lnz ;
524 :     if (grow)
525 :     {
526 :     /* add extra space */
527 :     xlnz = (double) lnz ;
528 :     xlnz *= grow0 ;
529 :     xlnz = MIN (xlnz, Size_max) ;
530 :     xlnz = MIN (xlnz, ((double) n * (double) n + (double) n) / 2) ;
531 :     lnz = (Int) xlnz ;
532 :     }
533 :     }
534 :     }
535 :    
536 :     lnz = MAX (1, lnz) ;
537 :    
538 :     if (!ok)
539 :     {
540 :     ERROR (CHOLMOD_TOO_LARGE, "problem too large") ;
541 :     }
542 :    
543 :     /* allocate L->i, L->x, and L->z */
544 :     PRINT1 (("resizing from zero size to lnz "ID"\n", lnz)) ;
545 :     ASSERT (L->nzmax == 0) ;
546 :     e = (to_xtype == CHOLMOD_COMPLEX ? 2 : 1) ;
547 :     if (!ok || !CHOLMOD(realloc_multiple) (lnz, 1, to_xtype, &(L->i), NULL,
548 :     &(L->x), &(L->z), &(L->nzmax), Common))
549 :     {
550 :     L->p = CHOLMOD(free) (n+1, sizeof (Int), L->p, Common) ;
551 :     L->nz = CHOLMOD(free) (n, sizeof (Int), L->nz, Common) ;
552 :     L->prev = CHOLMOD(free) (n+2, sizeof (Int), L->prev, Common) ;
553 :     L->next = CHOLMOD(free) (n+2, sizeof (Int), L->next, Common) ;
554 :     L->i = CHOLMOD(free) (lnz, sizeof (Int), L->i, Common) ;
555 :     L->x = CHOLMOD(free) (lnz, e*sizeof (double), L->x, Common) ;
556 :     L->z = CHOLMOD(free) (lnz, sizeof (double), L->z, Common) ;
557 :     PRINT1 (("cannot realloc simplicial numeric\n")) ;
558 :     return ; /* out of memory */
559 :     }
560 :    
561 :     /* ============================================== commit the changes to L */
562 :    
563 :     /* initialize L to be the identity matrix */
564 :     L->xtype = to_xtype ;
565 :     L->dtype = DTYPE ;
566 :     L->minor = n ;
567 :    
568 :     Li = L->i ;
569 :     Lx = L->x ;
570 :     Lz = L->z ;
571 :    
572 :     #if 0
573 :     if (lnz == 1)
574 :     {
575 :     /* the user won't expect to access this entry, but some CHOLMOD
576 :     * routines may. Set it to zero so that valgrind doesn't complain. */
577 :     switch (to_xtype)
578 :     {
579 :     case CHOLMOD_REAL:
580 :     Lx [0] = 0 ;
581 :     break ;
582 :    
583 :     case CHOLMOD_COMPLEX:
584 :     Lx [0] = 0 ;
585 :     Lx [1] = 0 ;
586 :     break ;
587 :    
588 :     case CHOLMOD_ZOMPLEX:
589 :     Lx [0] = 0 ;
590 :     Lz [0] = 0 ;
591 :     break ;
592 :     }
593 :     }
594 :     #endif
595 :    
596 :     if (packed >= 0)
597 :     {
598 :     /* create the unit diagonal for either the LL' or LDL' case */
599 :    
600 :     switch (L->xtype)
601 :     {
602 :     case CHOLMOD_REAL:
603 :     for (j = 0 ; j < n ; j++)
604 :     {
605 :     ASSERT (Lp [j] < Lp [j+1]) ;
606 :     p = Lp [j] ;
607 :     Li [p] = j ;
608 :     Lx [p] = 1 ;
609 :     }
610 :     break ;
611 :    
612 :     case CHOLMOD_COMPLEX:
613 :     for (j = 0 ; j < n ; j++)
614 :     {
615 :     ASSERT (Lp [j] < Lp [j+1]) ;
616 :     p = Lp [j] ;
617 :     Li [p] = j ;
618 :     Lx [2*p ] = 1 ;
619 :     Lx [2*p+1] = 0 ;
620 :     }
621 :     break ;
622 :    
623 :     case CHOLMOD_ZOMPLEX:
624 :     for (j = 0 ; j < n ; j++)
625 :     {
626 :     ASSERT (Lp [j] < Lp [j+1]) ;
627 :     p = Lp [j] ;
628 :     Li [p] = j ;
629 :     Lx [p] = 1 ;
630 :     Lz [p] = 0 ;
631 :     }
632 :     break ;
633 :     }
634 :     }
635 :    
636 :     L->is_ll = to_ll ;
637 :    
638 :     PRINT1 (("done convert simplicial symbolic to numeric\n")) ;
639 :     }
640 :    
641 :    
642 :     /* ========================================================================== */
643 :     /* === change_simplicial_numeric ============================================ */
644 :     /* ========================================================================== */
645 :    
646 :     /* Change LL' to LDL', LDL' to LL', or leave as-is.
647 :     *
648 :     * If to_packed is TRUE, then the columns of L are packed and made monotonic
649 :     * (to_monotonic is ignored; it is implicitly TRUE).
650 :     *
651 :     * If to_monotonic is TRUE but to_packed is FALSE, the columns of L are made
652 :     * monotonic but not packed.
653 :     *
654 :     * If both to_packed and to_monotonic are FALSE, then the columns of L are
655 :     * left as-is, and the conversion is done in place.
656 :     *
657 :     * If L is already monotonic, or if it is to be left non-monotonic, then this
658 :     * conversion always succeeds.
659 :     *
660 :     * When converting an LDL' to LL' factorization, any column with a negative
661 :     * or zero diagonal entry is not modified so that conversion back to LDL' will
662 :     * succeed. This can result in a matrix L with a negative entry on the diagonal
663 :     * If the kth entry on the diagonal of D is negative, it and the kth column of
664 :     * L are left unchanged. A subsequent conversion back to an LDL' form will also
665 :     * leave the column unchanged, so the correct LDL' factorization will be
666 :     * restored. L->minor is set to the smallest k for which D (k,k) is negative.
667 :     */
668 :    
669 :     static void change_simplicial_numeric
670 :     (
671 :     cholmod_factor *L,
672 :     int to_ll,
673 :     int to_packed,
674 :     int to_monotonic,
675 :     cholmod_common *Common
676 :     )
677 :     {
678 :     double grow0, grow1, xlen, xlnz ;
679 :     void *newLi, *newLx, *newLz ;
680 :     double *Lx, *Lz ;
681 :     Int *Lp, *Li, *Lnz ;
682 :     Int make_monotonic, grow2, n, j, lnz, len, grow, ok, make_ll, make_ldl ;
683 :     size_t nzmax0 ;
684 :    
685 :     PRINT1 (("\n===Change simplicial numeric: %d %d %d\n",
686 :     to_ll, to_packed, to_monotonic)) ;
687 :     DEBUG (CHOLMOD(dump_factor) (L, "change simplicial numeric", Common)) ;
688 :     ASSERT (L->xtype != CHOLMOD_PATTERN && !(L->is_super)) ;
689 :    
690 :     make_monotonic = ((to_packed || to_monotonic) && !(L->is_monotonic)) ;
691 :     make_ll = (to_ll && !(L->is_ll)) ;
692 :     make_ldl = (!to_ll && L->is_ll) ;
693 :    
694 :     n = L->n ;
695 :     Lp = L->p ;
696 :     Li = L->i ;
697 :     Lx = L->x ;
698 :     Lz = L->z ;
699 :     Lnz = L->nz ;
700 :    
701 :     grow = FALSE ;
702 :     grow0 = Common->grow0 ;
703 :     grow1 = Common->grow1 ;
704 :     grow2 = Common->grow2 ;
705 :     grow0 = IS_NAN (grow0) ? 1 : grow0 ;
706 :     grow1 = IS_NAN (grow1) ? 1 : grow1 ;
707 :     ok = TRUE ;
708 :     newLi = NULL ;
709 :     newLx = NULL ;
710 :     newLz = NULL ;
711 :     lnz = 0 ;
712 :    
713 :     if (make_monotonic)
714 :     {
715 :    
716 :     /* ------------------------------------------------------------------ */
717 :     /* Columns out of order, but will be reordered and optionally packed. */
718 :     /* ------------------------------------------------------------------ */
719 :    
720 :     PRINT1 (("L is non-monotonic\n")) ;
721 :    
722 :     /* compute new L->nzmax */
723 :     if (!to_packed)
724 :     {
725 :     /* if any parameter is NaN, grow is false */
726 :     /* fl.pt. comparisons below are false if any parameter is NaN */
727 :     grow = (grow0 >= 1.0) && (grow1 >= 1.0) && (grow2 > 0) ;
728 :     }
729 :     for (j = 0 ; ok && j < n ; j++)
730 :     {
731 :     len = Lnz [j] ;
732 :     ASSERT (len >= 1 && len <= n-j) ;
733 :    
734 :     /* compute len in double to avoid integer overflow */
735 :     if (grow)
736 :     {
737 :     xlen = (double) len ;
738 :     xlen = grow1 * xlen + grow2 ;
739 :     xlen = MIN (xlen, n-j) ;
740 :     len = (Int) xlen ;
741 :     }
742 :     ASSERT (len >= Lnz [j] && len <= n-j) ;
743 :    
744 :     PRINT2 (("j: "ID" Lnz[j] "ID" len "ID" p "ID"\n",
745 :     j, Lnz [j], len, lnz)) ;
746 :    
747 :     lnz += len ;
748 :     ok = (lnz >= 0) ;
749 :     }
750 :    
751 :     if (!ok)
752 :     {
753 :     ERROR (CHOLMOD_TOO_LARGE, "problem too large") ;
754 :     return ;
755 :     }
756 :    
757 :     if (grow)
758 :     {
759 :     xlnz = (double) lnz ;
760 :     xlnz *= grow0 ;
761 :     xlnz = MIN (xlnz, Size_max) ;
762 :     xlnz = MIN (xlnz, ((double) n * (double) n + (double) n) / 2) ;
763 :     lnz = (Int) xlnz ;
764 :     }
765 :    
766 :     lnz = MAX (1, lnz) ;
767 :     PRINT1 (("final lnz "ID"\n", lnz)) ;
768 :     nzmax0 = 0 ;
769 :    
770 :     CHOLMOD(realloc_multiple) (lnz, 1, L->xtype, &newLi, NULL,
771 :     &newLx, &newLz, &nzmax0, Common) ;
772 :    
773 :     if (Common->status < CHOLMOD_OK)
774 :     {
775 :     return ; /* out of memory */
776 :     }
777 :     }
778 :    
779 :     /* ============================================== commit the changes to L */
780 :    
781 :     /* ---------------------------------------------------------------------- */
782 :     /* convert the simplicial L, using template routine */
783 :     /* ---------------------------------------------------------------------- */
784 :    
785 :     switch (L->xtype)
786 :     {
787 :    
788 :     case CHOLMOD_REAL:
789 :     r_change_simplicial_numeric (L, to_ll, to_packed,
790 :     newLi, newLx, newLz, lnz, grow, grow1, grow2,
791 :     make_ll, make_monotonic, make_ldl, Common) ;
792 :     break ;
793 :    
794 :     case CHOLMOD_COMPLEX:
795 :     c_change_simplicial_numeric (L, to_ll, to_packed,
796 :     newLi, newLx, newLz, lnz, grow, grow1, grow2,
797 :     make_ll, make_monotonic, make_ldl, Common) ;
798 :     break ;
799 :    
800 :     case CHOLMOD_ZOMPLEX:
801 :     z_change_simplicial_numeric (L, to_ll, to_packed,
802 :     newLi, newLx, newLz, lnz, grow, grow1, grow2,
803 :     make_ll, make_monotonic, make_ldl, Common) ;
804 :     break ;
805 :     }
806 :    
807 :     DEBUG (CHOLMOD(dump_factor) (L, "L simplicial changed", Common)) ;
808 :     }
809 :    
810 :    
811 :     /* ========================================================================== */
812 :     /* === ll_super_to_simplicial_numeric ======================================= */
813 :     /* ========================================================================== */
814 :    
815 :     /* Convert a supernodal numeric factorization to any simplicial numeric one.
816 :     * Leaves L->xtype unchanged (real or complex, not zomplex since there is
817 :     * no supernodal zomplex L). */
818 :    
819 :     static void ll_super_to_simplicial_numeric
820 :     (
821 :     cholmod_factor *L,
822 :     int to_packed,
823 :     int to_ll,
824 :     cholmod_common *Common
825 :     )
826 :     {
827 :     Int *Ls, *Lpi, *Lpx, *Super, *Li ;
828 :     Int n, lnz, s, nsuper, psi, psend, nsrow, nscol, k1, k2, erows ;
829 :    
830 :     DEBUG (CHOLMOD(dump_factor) (L, "start LL super to simplicial", Common)) ;
831 :     PRINT1 (("super -> simplicial (%d %d)\n", to_packed, to_ll)) ;
832 :     ASSERT (L->xtype != CHOLMOD_PATTERN && L->is_ll && L->is_super) ;
833 :     ASSERT (L->x != NULL && L->i == NULL) ;
834 :    
835 :     n = L->n ;
836 :     nsuper = L->nsuper ;
837 :     Lpi = L->pi ;
838 :     Lpx = L->px ;
839 :     Ls = L->s ;
840 :     Super = L->super ;
841 :    
842 :     /* Int overflow cannot occur since supernodal L already exists */
843 :    
844 :     if (to_packed)
845 :     {
846 :     /* count the number of nonzeros in L. Each supernode is of the form
847 :     *
848 :     * l . . . For this example, nscol = 4 (# columns). nsrow = 9.
849 :     * l l . . The "." entries are allocated in the supernodal
850 :     * l l l . factor, but not used. They are not copied to the
851 :     * l l l l simplicial factor. Some "l" and "e" entries may be
852 :     * e e e e numerically zero and even symbolically zero if a
853 :     * e e e e tight simplicial factorization or resymbol were
854 :     * e e e e done, because of numerical cancellation and relaxed
855 :     * e e e e supernode amalgamation, respectively.
856 :     * e e e e
857 :     */
858 :     lnz = 0 ;
859 :     for (s = 0 ; s < nsuper ; s++)
860 :     {
861 :     k1 = Super [s] ;
862 :     k2 = Super [s+1] ;
863 :     psi = Lpi [s] ;
864 :     psend = Lpi [s+1] ;
865 :     nsrow = psend - psi ;
866 :     nscol = k2 - k1 ;
867 :     ASSERT (nsrow >= nscol) ;
868 :     erows = nsrow - nscol ;
869 :    
870 :     /* lower triangular part, including the diagonal,
871 :     * counting the "l" terms in the figure above. */
872 :     lnz += nscol * (nscol+1) / 2 ;
873 :    
874 :     /* rectangular part, below the diagonal block (the "e" terms) */
875 :     lnz += nscol * erows ;
876 :     }
877 :     ASSERT (lnz <= (Int) (L->xsize)) ;
878 :     }
879 :     else
880 :     {
881 :     /* Li will be the same size as Lx */
882 :     lnz = L->xsize ;
883 :     }
884 :     ASSERT (lnz >= 0) ;
885 : bates 1515 PRINT1 (("simplicial lnz = "ID" to_packed: %d to_ll: %d L->xsize %g\n",
886 :     lnz, to_ll, to_packed, (double) L->xsize)) ;
887 : bates 912
888 :     Li = CHOLMOD(malloc) (lnz, sizeof (Int), Common) ;
889 :     if (Common->status < CHOLMOD_OK)
890 :     {
891 :     return ; /* out of memory */
892 :     }
893 :    
894 :     if (!allocate_simplicial_numeric (L, Common))
895 :     {
896 :     CHOLMOD(free) (lnz, sizeof (Int), Li, Common) ;
897 :     return ; /* out of memory */
898 :     }
899 :    
900 :     /* ============================================== commit the changes to L */
901 :    
902 :     L->i = Li ;
903 :     L->nzmax = lnz ;
904 :    
905 :     /* ---------------------------------------------------------------------- */
906 :     /* convert the supernodal L, using template routine */
907 :     /* ---------------------------------------------------------------------- */
908 :    
909 :     switch (L->xtype)
910 :     {
911 :    
912 :     case CHOLMOD_REAL:
913 :     r_ll_super_to_simplicial_numeric (L, to_packed, to_ll, Common) ;
914 :     break ;
915 :    
916 :     case CHOLMOD_COMPLEX:
917 :     c_ll_super_to_simplicial_numeric (L, to_packed, to_ll, Common) ;
918 :     break ;
919 :     }
920 :    
921 :     /* ---------------------------------------------------------------------- */
922 :     /* free unused parts of L */
923 :     /* ---------------------------------------------------------------------- */
924 :    
925 :     L->super = CHOLMOD(free) (nsuper+1, sizeof (Int), L->super, Common) ;
926 :     L->pi = CHOLMOD(free) (nsuper+1, sizeof (Int), L->pi, Common) ;
927 :     L->px = CHOLMOD(free) (nsuper+1, sizeof (Int), L->px, Common) ;
928 :     L->s = CHOLMOD(free) (L->ssize, sizeof (Int), L->s, Common) ;
929 :    
930 :     L->ssize = 0 ;
931 :     L->xsize = 0 ;
932 :     L->nsuper = 0 ;
933 :     L->maxesize = 0 ;
934 :     L->maxcsize = 0 ;
935 :    
936 :     L->is_super = FALSE ;
937 :    
938 :     DEBUG (CHOLMOD(dump_factor) (L, "done LL super to simplicial", Common)) ;
939 :     }
940 :    
941 :    
942 :     /* ========================================================================== */
943 :     /* === super_symbolic_to_ll_super =========================================== */
944 :     /* ========================================================================== */
945 :    
946 :     /* Convert a supernodal symbolic factorization to a supernodal numeric
947 :     * factorization by allocating L->x. Contents of L->x are undefined.
948 :     */
949 :    
950 :     static int super_symbolic_to_ll_super
951 :     (
952 :     int to_xtype,
953 :     cholmod_factor *L,
954 :     cholmod_common *Common
955 :     )
956 :     {
957 :     double *Lx ;
958 :     Int wentry = (to_xtype == CHOLMOD_REAL) ? 1 : 2 ;
959 :     PRINT1 (("convert super sym to num\n")) ;
960 :     ASSERT (L->xtype == CHOLMOD_PATTERN && L->is_super) ;
961 :     Lx = CHOLMOD(malloc) (L->xsize, wentry * sizeof (double), Common) ;
962 : bates 1515 PRINT1 (("xsize %g\n", (double) L->xsize)) ;
963 : bates 912 if (Common->status < CHOLMOD_OK)
964 :     {
965 :     return (FALSE) ; /* out of memory */
966 :     }
967 :    
968 :     /* ============================================== commit the changes to L */
969 :    
970 :     if (L->xsize == 1)
971 :     {
972 :     /* the caller won't expect to access this entry, but some CHOLMOD
973 :     * routines may. Set it to zero so that valgrind doesn't complain. */
974 :     switch (to_xtype)
975 :     {
976 :     case CHOLMOD_REAL:
977 :     Lx [0] = 0 ;
978 :     break ;
979 :    
980 :     case CHOLMOD_COMPLEX:
981 :     Lx [0] = 0 ;
982 :     Lx [1] = 0 ;
983 :     break ;
984 :     }
985 :     }
986 :    
987 :     L->x = Lx ;
988 :     L->xtype = to_xtype ;
989 :     L->dtype = DTYPE ;
990 :     L->minor = L->n ;
991 :     return (TRUE) ;
992 :     }
993 :    
994 :    
995 :     /* ========================================================================== */
996 :     /* === cholmod_change_factor ================================================ */
997 :     /* ========================================================================== */
998 :    
999 :     /* Convert a factor L. Some conversions simply allocate uninitialized space
1000 :     * that meant to be filled later.
1001 :     *
1002 :     * If the conversion fails, the factor is left in its original form, with one
1003 :     * exception. Converting a supernodal symbolic factor to a simplicial numeric
1004 :     * one (with L=D=I) may leave the factor in simplicial symbolic form.
1005 :     *
1006 :     * Memory allocated for each conversion is listed below.
1007 :     */
1008 :    
1009 :     int CHOLMOD(change_factor)
1010 :     (
1011 :     /* ---- input ---- */
1012 :     int to_xtype, /* convert to CHOLMOD_PATTERN, _REAL, _COMPLEX, or
1013 :     * _ZOMPLEX */
1014 :     int to_ll, /* TRUE: convert to LL', FALSE: LDL' */
1015 :     int to_super, /* TRUE: convert to supernodal, FALSE: simplicial */
1016 :     int to_packed, /* TRUE: pack simplicial columns, FALSE: do not pack */
1017 :     int to_monotonic, /* TRUE: put simplicial columns in order, FALSE: not */
1018 :     /* ---- in/out --- */
1019 :     cholmod_factor *L, /* factor to modify */
1020 :     /* --------------- */
1021 :     cholmod_common *Common
1022 :     )
1023 :     {
1024 :    
1025 :     /* ---------------------------------------------------------------------- */
1026 :     /* get inputs */
1027 :     /* ---------------------------------------------------------------------- */
1028 :    
1029 :     RETURN_IF_NULL_COMMON (FALSE) ;
1030 :     RETURN_IF_NULL (L, FALSE) ;
1031 :     RETURN_IF_XTYPE_INVALID (L, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ;
1032 :     if (to_xtype < CHOLMOD_PATTERN || to_xtype > CHOLMOD_ZOMPLEX)
1033 :     {
1034 :     ERROR (CHOLMOD_INVALID, "xtype invalid") ;
1035 :     return (FALSE) ;
1036 :     }
1037 :     Common->status = CHOLMOD_OK ;
1038 :    
1039 :     PRINT1 (("-----convert from (%d,%d,%d,%d,%d) to (%d,%d,%d,%d,%d)\n",
1040 :     L->xtype, L->is_ll, L->is_super, L_is_packed (L, Common), L->is_monotonic,
1041 :     to_xtype, to_ll, to_super, to_packed, to_monotonic)) ;
1042 :    
1043 :     /* ensure all parameters are TRUE/FALSE */
1044 :     to_ll = BOOLEAN (to_ll) ;
1045 :     to_super = BOOLEAN (to_super) ;
1046 :    
1047 :     ASSERT (BOOLEAN (L->is_ll) == L->is_ll) ;
1048 :     ASSERT (BOOLEAN (L->is_super) == L->is_super) ;
1049 :    
1050 :     if (to_super && to_xtype == CHOLMOD_ZOMPLEX)
1051 :     {
1052 :     ERROR (CHOLMOD_INVALID, "supernodal zomplex L not supported") ;
1053 :     return (FALSE) ;
1054 :     }
1055 :    
1056 :     /* ---------------------------------------------------------------------- */
1057 :     /* convert */
1058 :     /* ---------------------------------------------------------------------- */
1059 :    
1060 :     if (to_xtype == CHOLMOD_PATTERN)
1061 :     {
1062 :    
1063 :     /* ------------------------------------------------------------------ */
1064 :     /* convert to symbolic */
1065 :     /* ------------------------------------------------------------------ */
1066 :    
1067 :     if (!to_super)
1068 :     {
1069 :    
1070 :     /* -------------------------------------------------------------- */
1071 :     /* convert any factor into a simplicial symbolic factor */
1072 :     /* -------------------------------------------------------------- */
1073 :    
1074 :     any_to_simplicial_symbolic (L, to_ll, Common) ; /* cannot fail */
1075 :    
1076 :     }
1077 :     else
1078 :     {
1079 :    
1080 :     /* -------------------------------------------------------------- */
1081 :     /* convert to a supernodal symbolic factor */
1082 :     /* -------------------------------------------------------------- */
1083 :    
1084 :     if (L->xtype != CHOLMOD_PATTERN && L->is_super)
1085 :     {
1086 :     /* convert from supernodal numeric to supernodal symbolic.
1087 :     * this preserves symbolic pattern of L, discards numeric
1088 :     * values */
1089 :     ll_super_to_super_symbolic (L, Common) ; /* cannot fail */
1090 :     }
1091 :     else if (L->xtype == CHOLMOD_PATTERN && !(L->is_super))
1092 :     {
1093 :     /* convert from simplicial symbolic to supernodal symbolic.
1094 :     * contents of supernodal pattern are uninitialized. Not meant
1095 :     * for the end user. */
1096 :     simplicial_symbolic_to_super_symbolic (L, Common) ;
1097 :     }
1098 :     else
1099 :     {
1100 :     /* cannot convert from simplicial numeric to supernodal
1101 :     * symbolic */
1102 :     ERROR (CHOLMOD_INVALID,
1103 :     "cannot convert L to supernodal symbolic") ;
1104 :     }
1105 :     }
1106 :    
1107 :     }
1108 :     else
1109 :     {
1110 :    
1111 :     /* ------------------------------------------------------------------ */
1112 :     /* convert to numeric */
1113 :     /* ------------------------------------------------------------------ */
1114 :    
1115 :     if (to_super)
1116 :     {
1117 :    
1118 :     /* -------------------------------------------------------------- */
1119 :     /* convert to supernodal numeric factor */
1120 :     /* -------------------------------------------------------------- */
1121 :    
1122 :     if (L->xtype == CHOLMOD_PATTERN)
1123 :     {
1124 :     if (L->is_super)
1125 :     {
1126 :     /* Convert supernodal symbolic to supernodal numeric.
1127 :     * Contents of supernodal numeric values are uninitialized.
1128 :     * This is used by cholmod_super_numeric. Not meant for
1129 :     * the end user. */
1130 :     super_symbolic_to_ll_super (to_xtype, L, Common) ;
1131 :     }
1132 :     else
1133 :     {
1134 :     /* Convert simplicial symbolic to supernodal numeric.
1135 :     * Contents not defined. This is used by
1136 :     * Core/cholmod_copy_factor only. Not meant for the end
1137 :     * user. */
1138 :     if (!simplicial_symbolic_to_super_symbolic (L, Common))
1139 :     {
1140 :     /* failure, convert back to simplicial symbolic */
1141 :     any_to_simplicial_symbolic (L, to_ll, Common) ;
1142 :     }
1143 :     else
1144 :     {
1145 :     /* conversion to super symbolic OK, allocate numeric
1146 :     * part */
1147 :     super_symbolic_to_ll_super (to_xtype, L, Common) ;
1148 :     }
1149 :     }
1150 :     }
1151 :     else
1152 :     {
1153 :     /* nothing to do if L is already in supernodal numeric form */
1154 :     if (!(L->is_super))
1155 :     {
1156 :     ERROR (CHOLMOD_INVALID,
1157 :     "cannot convert simplicial L to supernodal") ;
1158 :     }
1159 :     /* FUTURE WORK: convert to/from supernodal LL' and LDL' */
1160 :     }
1161 :    
1162 :     }
1163 :     else
1164 :     {
1165 :    
1166 :     /* -------------------------------------------------------------- */
1167 :     /* convert any factor to simplicial numeric */
1168 :     /* -------------------------------------------------------------- */
1169 :    
1170 :     if (L->xtype == CHOLMOD_PATTERN && !(L->is_super))
1171 :     {
1172 :    
1173 :     /* ---------------------------------------------------------- */
1174 :     /* convert simplicial symbolic to simplicial numeric (L=I,D=I)*/
1175 :     /* ---------------------------------------------------------- */
1176 :    
1177 :     simplicial_symbolic_to_simplicial_numeric (L, to_ll, to_packed,
1178 :     to_xtype, Common) ;
1179 :    
1180 :     }
1181 :     else if (L->xtype != CHOLMOD_PATTERN && L->is_super)
1182 :     {
1183 :    
1184 :     /* ---------------------------------------------------------- */
1185 :     /* convert a supernodal LL' to simplicial numeric */
1186 :     /* ---------------------------------------------------------- */
1187 :    
1188 :     ll_super_to_simplicial_numeric (L, to_packed, to_ll, Common) ;
1189 :    
1190 :     }
1191 :     else if (L->xtype == CHOLMOD_PATTERN && L->is_super)
1192 :     {
1193 :    
1194 :     /* ---------------------------------------------------------- */
1195 :     /* convert a supernodal symbolic to simplicial numeric (L=D=I)*/
1196 :     /* ---------------------------------------------------------- */
1197 :    
1198 :     any_to_simplicial_symbolic (L, to_ll, Common) ;
1199 :     /* if the following fails, it leaves the factor in simplicial
1200 :     * symbolic form */
1201 :     simplicial_symbolic_to_simplicial_numeric (L, to_ll, to_packed,
1202 :     to_xtype, Common) ;
1203 :    
1204 :     }
1205 :     else
1206 :     {
1207 :    
1208 :     /* ---------------------------------------------------------- */
1209 :     /* change a simplicial numeric factor */
1210 :     /* ---------------------------------------------------------- */
1211 :    
1212 :     /* change LL' to LDL', LDL' to LL', or leave as-is. pack the
1213 :     * columns of L, or leave as-is. Ensure the columns are
1214 :     * monotonic, or leave as-is. */
1215 :    
1216 :     change_simplicial_numeric (L, to_ll, to_packed, to_monotonic,
1217 :     Common) ;
1218 :     }
1219 :     }
1220 :     }
1221 :    
1222 :     /* ---------------------------------------------------------------------- */
1223 :     /* return result */
1224 :     /* ---------------------------------------------------------------------- */
1225 :    
1226 :     return (Common->status >= CHOLMOD_OK) ;
1227 :     }

root@r-forge.r-project.org
ViewVC Help
Powered by ViewVC 1.0.0  
Thanks to:
Vienna University of Economics and Business Powered By FusionForge