Amesos Package Browser (Single Doxygen Collection)  Development
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
amesos_cholmod_triplet.c
Go to the documentation of this file.
1 /* ========================================================================== */
2 /* === Core/cholmod_triplet ================================================= */
3 /* ========================================================================== */
4 
5 /* -----------------------------------------------------------------------------
6  * CHOLMOD/Core Module. Copyright (C) 2005-2006,
7  * Univ. of Florida. Author: Timothy A. Davis
8  * 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 /* Core utility routines for the cholmod_triplet object:
15  *
16  * A sparse matrix held in triplet form is the simplest one for a user to
17  * create. It consists of a list of nz entries in arbitrary order, held in
18  * three arrays: i, j, and x, each of length nk. The kth entry is in row i[k],
19  * column j[k], with value x[k]. There may be duplicate values; if A(i,j)
20  * appears more than once, its value is the sum of the entries with those row
21  * and column indices.
22  *
23  * Primary routines:
24  * -----------------
25  * cholmod_allocate_triplet allocate a triplet matrix
26  * cholmod_free_triplet free a triplet matrix
27  *
28  * Secondary routines:
29  * -------------------
30  * cholmod_reallocate_triplet reallocate a triplet matrix
31  * cholmod_sparse_to_triplet create a triplet matrix copy of a sparse matrix
32  * cholmod_triplet_to_sparse create a sparse matrix copy of a triplet matrix
33  * cholmod_copy_triplet create a copy of a triplet matrix
34  *
35  * The relationship between an m-by-n cholmod_sparse matrix A and a
36  * cholmod_triplet matrix (i, j, and x) is identical to how they are used in
37  * the MATLAB "sparse" and "find" functions:
38  *
39  * [i j x] = find (A)
40  * [m n] = size (A)
41  * A = sparse (i,j,x,m,n)
42  *
43  * with the exception that the cholmod_sparse matrix may be "unpacked", may
44  * have either sorted or unsorted columns (depending on the option selected),
45  * and may be symmetric with just the upper or lower triangular part stored.
46  * Likewise, the cholmod_triplet matrix may contain just the entries in the
47  * upper or lower triangular part of a symmetric matrix.
48  *
49  * MATLAB sparse matrices are always "packed", always have sorted columns,
50  * and always store both parts of a symmetric matrix. In some cases, MATLAB
51  * behaves like CHOLMOD by ignoring entries in the upper or lower triangular
52  * part of a matrix that is otherwise assumed to be symmetric (such as the
53  * input to chol). In CHOLMOD, that option is a characteristic of the object.
54  * In MATLAB, that option is based on how a matrix is used as the input to
55  * a function.
56  *
57  * The triplet matrix is provided to give the user a simple way of constructing
58  * a sparse matrix. There are very few operations supported for triplet
59  * matrices. The assumption is that they will be converted to cholmod_sparse
60  * matrix form first.
61  *
62  * Adding two triplet matrices simply involves concatenating the contents of
63  * the three arrays (i, j, and x). To permute a triplet matrix, just replace
64  * the row and column indices with their permuted values. For example, if
65  * P is a permutation vector, then P [k] = j means row/column j is the kth
66  * row/column in C=P*A*P'. In MATLAB notation, C=A(p,p). If Pinv is an array
67  * of size n and T is the triplet form of A, then:
68  *
69  * Ti = T->i ;
70  * Tj = T->j ;
71  * for (k = 0 ; k < n ; k++) Pinv [P [k]] = k ;
72  * for (k = 0 ; k < nz ; k++) Ti [k] = Pinv [Ti [k]] ;
73  * for (k = 0 ; k < nz ; k++) Tj [k] = Pinv [Tj [k]] ;
74  *
75  * overwrites T with the triplet form of C=P*A*P'. The conversion
76  *
77  * C = cholmod_triplet_to_sparse (T, 0, &Common) ;
78  *
79  * will then return the matrix C = P*A*P'.
80  *
81  * Note that T->stype > 0 means that entries in the lower triangular part of
82  * T are transposed into the upper triangular part when T is converted to
83  * sparse matrix (cholmod_sparse) form with cholmod_triplet_to_sparse. The
84  * opposite is true for T->stype < 0.
85  *
86  * Since the triplet matrix T is so simple to generate, it's quite easy
87  * to remove entries that you do not want, prior to converting T to the
88  * cholmod_sparse form. So if you include these entries in T, CHOLMOD
89  * assumes that there must be a reason (such as the one above). Thus,
90  * no entry in a triplet matrix is ever ignored.
91  *
92  * Other operations, such as extacting a submatrix, horizontal and vertical
93  * concatenation, multiply a triplet matrix times a dense matrix, are also
94  * simple. Multiplying two triplet matrices is not trivial; the simplest
95  * method is to convert them to cholmod_sparse matrices first.
96  *
97  * Supports all xtypes (pattern, real, complex, and zomplex).
98  */
99 
100 #include "amesos_cholmod_internal.h"
101 #include "amesos_cholmod_core.h"
102 
103 
104 /* ========================================================================== */
105 /* === TEMPLATE ============================================================= */
106 /* ========================================================================== */
107 
108 #define PATTERN
110 #define REAL
112 #define COMPLEX
114 #define ZOMPLEX
116 
117 
118 /* ========================================================================== */
119 /* === cholmod_allocate_triplet ============================================= */
120 /* ========================================================================== */
121 
122 /* allocate space for a triplet matrix
123  *
124  * workspace: none
125  */
126 
128 (
129  /* ---- input ---- */
130  size_t nrow, /* # of rows of T */
131  size_t ncol, /* # of columns of T */
132  size_t nzmax, /* max # of nonzeros of T */
133  int stype, /* stype of T */
134  int xtype, /* CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX */
135  /* --------------- */
136  cholmod_common *Common
137 )
138 {
139  cholmod_triplet *T ;
140  size_t nzmax0 ;
141  int ok = TRUE ;
142 
143  /* ---------------------------------------------------------------------- */
144  /* get inputs */
145  /* ---------------------------------------------------------------------- */
146 
148  if (xtype < CHOLMOD_PATTERN || xtype > CHOLMOD_ZOMPLEX)
149  {
150  ERROR (CHOLMOD_INVALID, "xtype invalid") ;
151  return (NULL) ;
152  }
153  /* ensure the dimensions do not cause integer overflow */
154  (void) CHOLMOD(add_size_t) (ncol, 2, &ok) ;
155  if (!ok || nrow > Int_max || ncol > Int_max || nzmax > Int_max)
156  {
157  ERROR (CHOLMOD_TOO_LARGE, "problem too large") ;
158  return (NULL) ;
159  }
160 
161  Common->status = CHOLMOD_OK ;
162 
163  /* ---------------------------------------------------------------------- */
164  /* allocate header */
165  /* ---------------------------------------------------------------------- */
166 
167  T = CHOLMOD(malloc) (sizeof (cholmod_triplet), 1, Common) ;
168  if (Common->status < CHOLMOD_OK)
169  {
170  return (NULL) ; /* out of memory */
171  }
172 
173  PRINT1 (("cholmod_allocate_triplet %d-by-%d nzmax %d xtype %d\n",
174  nrow, ncol, nzmax, xtype)) ;
175 
176  nzmax = MAX (1, nzmax) ;
177 
178  T->nrow = nrow ;
179  T->ncol = ncol ;
180  T->nzmax = nzmax ;
181  T->nnz = 0 ;
182  T->stype = stype ;
183  T->itype = ITYPE ;
184  T->xtype = xtype ;
185  T->dtype = DTYPE ;
186 
187  T->j = NULL ;
188  T->i = NULL ;
189  T->x = NULL ;
190  T->z = NULL ;
191 
192  /* ---------------------------------------------------------------------- */
193  /* allocate the matrix itself */
194  /* ---------------------------------------------------------------------- */
195 
196  nzmax0 = 0 ;
197  CHOLMOD(realloc_multiple) (nzmax, 2, xtype, &(T->i), &(T->j),
198  &(T->x), &(T->z), &nzmax0, Common) ;
199 
200  if (Common->status < CHOLMOD_OK)
201  {
202  CHOLMOD(free_triplet) (&T, Common) ;
203  return (NULL) ; /* out of memory */
204  }
205 
206  return (T) ;
207 }
208 
209 
210 /* ========================================================================== */
211 /* === cholmod_free_triplet ================================================= */
212 /* ========================================================================== */
213 
214 /* free a triplet matrix
215  *
216  * workspace: none
217  */
218 
220 (
221  /* ---- in/out --- */
222  cholmod_triplet **THandle, /* matrix to deallocate, NULL on output */
223  /* --------------- */
224  cholmod_common *Common
225 )
226 {
227  Int nz ;
228  cholmod_triplet *T ;
229 
231 
232  if (THandle == NULL)
233  {
234  /* nothing to do */
235  return (TRUE) ;
236  }
237  T = *THandle ;
238  if (T == NULL)
239  {
240  /* nothing to do */
241  return (TRUE) ;
242  }
243  nz = T->nzmax ;
244  T->j = CHOLMOD(free) (nz, sizeof (Int), T->j, Common) ;
245  T->i = CHOLMOD(free) (nz, sizeof (Int), T->i, Common) ;
246  if (T->xtype == CHOLMOD_REAL)
247  {
248  T->x = CHOLMOD(free) (nz, sizeof (double), T->x, Common) ;
249  }
250  else if (T->xtype == CHOLMOD_COMPLEX)
251  {
252  T->x = CHOLMOD(free) (nz, 2*sizeof (double), T->x, Common) ;
253  }
254  else if (T->xtype == CHOLMOD_ZOMPLEX)
255  {
256  T->x = CHOLMOD(free) (nz, sizeof (double), T->x, Common) ;
257  T->z = CHOLMOD(free) (nz, sizeof (double), T->z, Common) ;
258  }
259  *THandle = CHOLMOD(free) (1, sizeof (cholmod_triplet), (*THandle), Common) ;
260  return (TRUE) ;
261 }
262 
263 
264 /* ========================================================================== */
265 /* === cholmod_reallocate_triplet =========================================== */
266 /* ========================================================================== */
267 
268 /* Change the size of T->i, T->j, and T->x, or allocate them if their current
269  * size is zero. T->x is not modified if T->xtype is CHOLMOD_PATTERN.
270  *
271  * workspace: none
272  */
273 
275 (
276  /* ---- input ---- */
277  size_t nznew, /* new # of entries in T */
278  /* ---- in/out --- */
279  cholmod_triplet *T, /* triplet matrix to modify */
280  /* --------------- */
281  cholmod_common *Common
282 )
283 {
284 
285  /* ---------------------------------------------------------------------- */
286  /* get inputs */
287  /* ---------------------------------------------------------------------- */
288 
290  RETURN_IF_NULL (T, FALSE) ;
292  Common->status = CHOLMOD_OK ;
293  PRINT1 (("realloc triplet %d to %d, xtype: %d\n",
294  T->nzmax, nznew, T->xtype)) ;
295 
296  /* ---------------------------------------------------------------------- */
297  /* resize the matrix */
298  /* ---------------------------------------------------------------------- */
299 
300  CHOLMOD(realloc_multiple) (MAX (1,nznew), 2, T->xtype, &(T->i), &(T->j),
301  &(T->x), &(T->z), &(T->nzmax), Common) ;
302 
303  return (Common->status == CHOLMOD_OK) ;
304 }
305 
306 
307 /* ========================================================================== */
308 /* === cholmod_triplet_to_sparse ============================================ */
309 /* ========================================================================== */
310 
311 /* Convert a set of triplets into a cholmod_sparse matrix. In MATLAB notation,
312  * for unsymmetric matrices:
313  *
314  * A = sparse (Ti, Tj, Tx, nrow, ncol, nzmax) ;
315  *
316  * For the symmetric upper case:
317  *
318  * A = sparse (min(Ti,Tj), max(Ti,Tj), Tx, nrow, ncol, nzmax) ;
319  *
320  * For the symmetric lower case:
321  *
322  * A = sparse (max(Ti,Tj), min(Ti,Tj), Tx, nrow, ncol, nzmax) ;
323  *
324  * If Tx is NULL, then A->x is not allocated, and only the pattern of A is
325  * computed. A is returned in packed form, and can be of any stype
326  * (upper/lower/unsymmetric). It has enough space to hold the values in T,
327  * or nzmax, whichever is larger.
328  *
329  * workspace: Iwork (max (nrow,ncol))
330  * allocates a temporary copy of its output matrix.
331  *
332  * The resulting sparse matrix has the same xtype as the input triplet matrix.
333  */
334 
336 (
337  /* ---- input ---- */
338  cholmod_triplet *T, /* matrix to copy */
339  size_t nzmax, /* allocate at least this much space in output matrix */
340  /* --------------- */
341  cholmod_common *Common
342 )
343 {
344  cholmod_sparse *R, *A = NULL ;
345  Int *Wj, *Rp, *Ri, *Rnz, *Ti, *Tj ;
346  Int i, j, p, k, stype, nrow, ncol, nz, ok ;
347  size_t anz = 0 ;
348 
349  /* ---------------------------------------------------------------------- */
350  /* check inputs */
351  /* ---------------------------------------------------------------------- */
352 
354  RETURN_IF_NULL (T, NULL) ;
355  Ti = T->i ;
356  Tj = T->j ;
357  RETURN_IF_NULL (Ti, NULL) ;
358  RETURN_IF_NULL (Tj, NULL) ;
360  stype = SIGN (T->stype) ;
361  if (stype && T->nrow != T->ncol)
362  {
363  /* inputs invalid */
364  ERROR (CHOLMOD_INVALID, "matrix invalid") ;
365  return (NULL) ;
366  }
367  Common->status = CHOLMOD_OK ;
368  DEBUG (CHOLMOD(dump_triplet) (T, "T", Common)) ;
369 
370  /* ---------------------------------------------------------------------- */
371  /* get inputs */
372  /* ---------------------------------------------------------------------- */
373 
374  nrow = T->nrow ;
375  ncol = T->ncol ;
376  nz = T->nnz ;
377 
378  /* ---------------------------------------------------------------------- */
379  /* allocate workspace */
380  /* ---------------------------------------------------------------------- */
381 
382  CHOLMOD(allocate_work) (0, MAX (nrow, ncol), 0, Common) ;
383  if (Common->status < CHOLMOD_OK)
384  {
385  return (NULL) ; /* out of memory */
386  }
387 
388  /* ---------------------------------------------------------------------- */
389  /* allocate temporary matrix R */
390  /* ---------------------------------------------------------------------- */
391 
392  R = CHOLMOD(allocate_sparse) (ncol, nrow, nz, FALSE, FALSE, -stype,
393  T->xtype, Common) ;
394 
395  if (Common->status < CHOLMOD_OK)
396  {
397  return (NULL) ; /* out of memory */
398  }
399 
400  Rp = R->p ;
401  Ri = R->i ;
402  Rnz = R->nz ;
403 
404  /* ---------------------------------------------------------------------- */
405  /* count the entries in each row of A (also counting duplicates) */
406  /* ---------------------------------------------------------------------- */
407 
408  for (i = 0 ; i < nrow ; i++)
409  {
410  Rnz [i] = 0 ;
411  }
412 
413  if (stype > 0)
414  {
415  for (k = 0 ; k < nz ; k++)
416  {
417  i = Ti [k] ;
418  j = Tj [k] ;
419  if (i < 0 || i >= nrow || j < 0 || j >= ncol)
420  {
421  ERROR (CHOLMOD_INVALID, "index out of range") ;
422  break ;
423  }
424  /* A will be symmetric with just the upper triangular part stored.
425  * Create a matrix R that is lower triangular. Entries in the
426  * upper part of R are transposed to the lower part. */
427  Rnz [MIN (i,j)]++ ;
428  }
429  }
430  else if (stype < 0)
431  {
432  for (k = 0 ; k < nz ; k++)
433  {
434  i = Ti [k] ;
435  j = Tj [k] ;
436  if (i < 0 || i >= nrow || j < 0 || j >= ncol)
437  {
438  ERROR (CHOLMOD_INVALID, "index out of range") ;
439  break ;
440  }
441  /* A will be symmetric with just the lower triangular part stored.
442  * Create a matrix R that is upper triangular. Entries in the
443  * lower part of R are transposed to the upper part. */
444  Rnz [MAX (i,j)]++ ;
445  }
446  }
447  else
448  {
449  for (k = 0 ; k < nz ; k++)
450  {
451  i = Ti [k] ;
452  j = Tj [k] ;
453  if (i < 0 || i >= nrow || j < 0 || j >= ncol)
454  {
455  ERROR (CHOLMOD_INVALID, "index out of range") ;
456  break ;
457  }
458  /* constructing an unsymmetric matrix */
459  Rnz [i]++ ;
460  }
461  }
462 
463  if (Common->status < CHOLMOD_OK)
464  {
465  /* triplet matrix is invalid */
466  CHOLMOD(free_sparse) (&R, Common) ;
467  return (NULL) ;
468  }
469 
470  /* ---------------------------------------------------------------------- */
471  /* construct the row pointers */
472  /* ---------------------------------------------------------------------- */
473 
474  p = 0 ;
475  for (i = 0 ; i < nrow ; i++)
476  {
477  Rp [i] = p ;
478  p += Rnz [i] ;
479  }
480  Rp [nrow] = p ;
481 
482  /* use Wj (i/l/l) as temporary row pointers */
483  Wj = Common->Iwork ; /* size MAX (nrow,ncol) FUTURE WORK: (i/l/l) */
484  for (i = 0 ; i < nrow ; i++)
485  {
486  Wj [i] = Rp [i] ;
487  }
488 
489  /* ---------------------------------------------------------------------- */
490  /* construct triplet matrix, using template routine */
491  /* ---------------------------------------------------------------------- */
492 
493  switch (T->xtype)
494  {
495  case CHOLMOD_PATTERN:
496  anz = amesos_p_cholmod_triplet_to_sparse (T, R, Common) ;
497  break ;
498 
499  case CHOLMOD_REAL:
500  anz = amesos_r_cholmod_triplet_to_sparse (T, R, Common) ;
501  break ;
502 
503  case CHOLMOD_COMPLEX:
504  anz = amesos_c_cholmod_triplet_to_sparse (T, R, Common) ;
505  break ;
506 
507  case CHOLMOD_ZOMPLEX:
508  anz = amesos_z_cholmod_triplet_to_sparse (T, R, Common) ;
509  break ;
510  }
511 
512  /* ---------------------------------------------------------------------- */
513  /* A = R' (array transpose, not complex conjugate transpose) */
514  /* ---------------------------------------------------------------------- */
515 
516  /* workspace: Iwork (R->nrow), which is A->ncol */
517 
518  ASSERT (CHOLMOD(dump_sparse) (R, "R", Common) >= 0) ;
519 
520  A = CHOLMOD(allocate_sparse) (nrow, ncol, MAX (anz, nzmax), TRUE, TRUE,
521  stype, T->xtype, Common) ;
522 
523  if (stype)
524  {
525  ok = CHOLMOD(transpose_sym) (R, 1, NULL, A, Common) ;
526  }
527  else
528  {
529  ok = CHOLMOD(transpose_unsym) (R, 1, NULL, NULL, 0, A, Common) ;
530  }
531 
532  CHOLMOD(free_sparse) (&R, Common) ;
533  if (Common->status < CHOLMOD_OK)
534  {
535  CHOLMOD(free_sparse) (&A, Common) ;
536  }
537 
538  /* ---------------------------------------------------------------------- */
539  /* return result */
540  /* ---------------------------------------------------------------------- */
541 
542  ASSERT (CHOLMOD(dump_sparse) (A, "A = triplet(T) result", Common) >= 0) ;
543  return (A) ;
544 }
545 
546 
547 /* ========================================================================== */
548 /* === cholmod_sparse_to_triplet ============================================ */
549 /* ========================================================================== */
550 
551 /* Converts a sparse column-oriented matrix to triplet form.
552  * The resulting triplet matrix has the same xtype as the sparse matrix.
553  *
554  * workspace: none
555  */
556 
558 (
559  /* ---- input ---- */
560  cholmod_sparse *A, /* matrix to copy */
561  /* --------------- */
562  cholmod_common *Common
563 )
564 {
565  double *Ax, *Az, *Tx, *Tz ;
566  Int *Ap, *Ai, *Ti, *Tj, *Anz ;
567  cholmod_triplet *T ;
568  Int i, xtype, p, pend, k, j, nrow, ncol, nz, stype, packed, up, lo,
569  both ;
570 
571  /* ---------------------------------------------------------------------- */
572  /* check inputs */
573  /* ---------------------------------------------------------------------- */
574 
576  RETURN_IF_NULL (A, NULL) ;
578  stype = SIGN (A->stype) ;
579  nrow = A->nrow ;
580  ncol = A->ncol ;
581  if (stype && nrow != ncol)
582  {
583  /* inputs invalid */
584  ERROR (CHOLMOD_INVALID, "matrix invalid") ;
585  return (NULL) ;
586  }
587  Ax = A->x ;
588  Az = A->z ;
589  xtype = A->xtype ;
590  Common->status = CHOLMOD_OK ;
591 
592  ASSERT (CHOLMOD(dump_sparse) (A, "A", Common) >= 0) ;
593 
594  /* ---------------------------------------------------------------------- */
595  /* allocate triplet matrix */
596  /* ---------------------------------------------------------------------- */
597 
598  nz = CHOLMOD(nnz) (A, Common) ;
599  T = CHOLMOD(allocate_triplet) (nrow, ncol, nz, A->stype, A->xtype, Common) ;
600 
601  if (Common->status < CHOLMOD_OK)
602  {
603  return (NULL) ; /* out of memory */
604  }
605 
606  /* ---------------------------------------------------------------------- */
607  /* convert to a sparse matrix */
608  /* ---------------------------------------------------------------------- */
609 
610  Ap = A->p ;
611  Ai = A->i ;
612  Anz = A->nz ;
613  packed = A->packed ;
614 
615  Ti = T->i ;
616  Tj = T->j ;
617  Tx = T->x ;
618  Tz = T->z ;
619  T->stype = A->stype ;
620 
621  both = (A->stype == 0) ;
622  up = (A->stype > 0) ;
623  lo = (A->stype < 0) ;
624 
625  k = 0 ;
626 
627  for (j = 0 ; j < ncol ; j++)
628  {
629  p = Ap [j] ;
630  pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ;
631  for ( ; p < pend ; p++)
632  {
633  i = Ai [p] ;
634  if (both || (up && i <= j) || (lo && i >= j))
635  {
636  Ti [k] = Ai [p] ;
637  Tj [k] = j ;
638 
639  if (xtype == CHOLMOD_REAL)
640  {
641  Tx [k] = Ax [p] ;
642  }
643  else if (xtype == CHOLMOD_COMPLEX)
644  {
645  Tx [2*k ] = Ax [2*p ] ;
646  Tx [2*k+1] = Ax [2*p+1] ;
647  }
648  else if (xtype == CHOLMOD_ZOMPLEX)
649  {
650  Tx [k] = Ax [p] ;
651  Tz [k] = Az [p] ;
652  }
653 
654  k++ ;
655  ASSERT (k <= nz) ;
656  }
657  }
658  }
659 
660  T->nnz = k ;
661 
662  /* ---------------------------------------------------------------------- */
663  /* return result */
664  /* ---------------------------------------------------------------------- */
665 
666  ASSERT (CHOLMOD(dump_triplet) (T, "T", Common)) ;
667  return (T) ;
668 }
669 
670 
671 /* ========================================================================== */
672 /* === cholmod_copy_triplet ================================================= */
673 /* ========================================================================== */
674 
675 /* Create an exact copy of a triplet matrix, except that entries in unused
676  * space are not copied (they might not be initialized, and copying them would
677  * cause program checkers such as purify and valgrind to complain).
678  * The output triplet matrix has the same xtype as the input triplet matrix.
679  */
680 
682 (
683  /* ---- input ---- */
684  cholmod_triplet *T, /* matrix to copy */
685  /* --------------- */
686  cholmod_common *Common
687 )
688 {
689  double *Tx, *Tz, *Cx, *Cz ;
690  Int *Ci, *Cj, *Ti, *Tj ;
691  cholmod_triplet *C ;
692  Int xtype, k, nz ;
693 
694  /* ---------------------------------------------------------------------- */
695  /* check inputs */
696  /* ---------------------------------------------------------------------- */
697 
699  RETURN_IF_NULL (T, NULL) ;
701  nz = T->nnz ;
702  Ti = T->i ;
703  Tj = T->j ;
704  Tx = T->x ;
705  Tz = T->z ;
706  xtype = T->xtype ;
707  RETURN_IF_NULL (Ti, NULL) ;
708  RETURN_IF_NULL (Tj, NULL) ;
709  Common->status = CHOLMOD_OK ;
710  DEBUG (CHOLMOD(dump_triplet) (T, "T input", Common)) ;
711 
712  /* ---------------------------------------------------------------------- */
713  /* allocate copy */
714  /* ---------------------------------------------------------------------- */
715 
716  C = CHOLMOD(allocate_triplet) (T->nrow, T->ncol, T->nzmax, T->stype,
717  xtype, Common) ;
718 
719  if (Common->status < CHOLMOD_OK)
720  {
721  return (NULL) ; /* out of memory */
722  }
723 
724  /* ---------------------------------------------------------------------- */
725  /* copy the triplet matrix */
726  /* ---------------------------------------------------------------------- */
727 
728  Ci = C->i ;
729  Cj = C->j ;
730  Cx = C->x ;
731  Cz = C->z ;
732  C->nnz = nz ;
733 
734  for (k = 0 ; k < nz ; k++)
735  {
736  Ci [k] = Ti [k] ;
737  }
738  for (k = 0 ; k < nz ; k++)
739  {
740  Cj [k] = Tj [k] ;
741  }
742 
743  if (xtype == CHOLMOD_REAL)
744  {
745  for (k = 0 ; k < nz ; k++)
746  {
747  Cx [k] = Tx [k] ;
748  }
749  }
750  else if (xtype == CHOLMOD_COMPLEX)
751  {
752  for (k = 0 ; k < nz ; k++)
753  {
754  Cx [2*k ] = Tx [2*k ] ;
755  Cx [2*k+1] = Tx [2*k+1] ;
756  }
757  }
758  else if (xtype == CHOLMOD_ZOMPLEX)
759  {
760  for (k = 0 ; k < nz ; k++)
761  {
762  Cx [k] = Tx [k] ;
763  Cz [k] = Tz [k] ;
764  }
765  }
766 
767  /* ---------------------------------------------------------------------- */
768  /* return the result */
769  /* ---------------------------------------------------------------------- */
770 
771  ASSERT (CHOLMOD(dump_triplet) (C, "C triplet copy", Common)) ;
772  return (C) ;
773 }
#define CHOLMOD_TOO_LARGE
UF_long CHOLMOD() nnz(cholmod_sparse *A, cholmod_common *Common)
int CHOLMOD() transpose_sym(cholmod_sparse *A, int values, Int *Perm, cholmod_sparse *F, cholmod_common *Common)
int CHOLMOD() transpose_unsym(cholmod_sparse *A, int values, Int *Perm, Int *fset, size_t fsize, cholmod_sparse *F, cholmod_common *Common)
int CHOLMOD() realloc_multiple(size_t nnew, int nint, int xtype, void **I, void **J, void **X, void **Z, size_t *nold_p, cholmod_common *Common)
int CHOLMOD() dump_triplet(cholmod_triplet *T, char *name, cholmod_common *Common)
#define Int
struct cholmod_triplet_struct cholmod_triplet
size_t CHOLMOD() add_size_t(size_t a, size_t b, int *ok)
#define CHOLMOD_COMPLEX
#define FALSE
#define PRINT1(params)
int CHOLMOD() free_triplet(cholmod_triplet **THandle, cholmod_common *Common)
#define RETURN_IF_NULL_COMMON(result)
#define SIGN(x)
cholmod_triplet *CHOLMOD() allocate_triplet(size_t nrow, size_t ncol, size_t nzmax, int stype, int xtype, cholmod_common *Common)
#define CHOLMOD_PATTERN
#define CHOLMOD(name)
#define MAX(a, b)
int CHOLMOD() free_sparse(cholmod_sparse **AHandle, cholmod_common *Common)
#define CHOLMOD_REAL
#define NULL
cholmod_triplet *CHOLMOD() copy_triplet(cholmod_triplet *T, cholmod_common *Common)
#define Int_max
#define ASSERT(expression)
#define DTYPE
#define CHOLMOD_INVALID
#define CHOLMOD_OK
cholmod_sparse *CHOLMOD() allocate_sparse(size_t nrow, size_t ncol, size_t nzmax, int sorted, int packed, int stype, int xtype, cholmod_common *Common)
int CHOLMOD() allocate_work(size_t nrow, size_t iworksize, size_t xworksize, cholmod_common *Common)
#define RETURN_IF_NULL(A, result)
#define DEBUG(statement)
#define MIN(a, b)
#define ERROR(status, msg)
#define TRUE
int CHOLMOD() reallocate_triplet(size_t nznew, cholmod_triplet *T, cholmod_common *Common)
#define RETURN_IF_XTYPE_INVALID(A, xtype1, xtype2, result)
cholmod_triplet *CHOLMOD() sparse_to_triplet(cholmod_sparse *A, cholmod_common *Common)
#define CHOLMOD_ZOMPLEX
cholmod_sparse *CHOLMOD() triplet_to_sparse(cholmod_triplet *T, size_t nzmax, cholmod_common *Common)
#define ITYPE