Amesos Package Browser (Single Doxygen Collection)  Development
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
amesos_t_cholmod_triplet.c
Go to the documentation of this file.
1 /* ========================================================================== */
2 /* === Core/t_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 /* Template routine for cholmod_triplet. All xtypes supported */
15 
17 
18 /* ========================================================================== */
19 /* === t_cholmod_triplet_to_sparse ========================================== */
20 /* ========================================================================== */
21 
22 static size_t TEMPLATE (cholmod_triplet_to_sparse)
23 (
24  /* ---- input ---- */
25  cholmod_triplet *T, /* matrix to copy */
26  /* ---- in/out --- */
27  cholmod_sparse *R, /* output matrix */
28  /* --------------- */
29  cholmod_common *Common
30 )
31 {
32  double *Rx, *Rz, *Tx, *Tz ;
33  Int *Wj, *Rp, *Ri, *Rnz, *Ti, *Tj ;
34  Int i, j, p, p1, p2, pdest, pj, k, stype, nrow, ncol, nz ;
35  size_t anz ;
36 
37  /* ---------------------------------------------------------------------- */
38  /* get inputs */
39  /* ---------------------------------------------------------------------- */
40 
41  /* Wj contains a copy of Rp on input [ */
42  Wj = Common->Iwork ; /* size MAX (nrow,ncol). (i/l/l) */
43 
44  Rp = R->p ;
45  Ri = R->i ;
46  Rnz = R->nz ;
47  Rx = R->x ;
48  Rz = R->z ;
49 
50  Ti = T->i ;
51  Tj = T->j ;
52  Tx = T->x ;
53  Tz = T->z ;
54  nz = T->nnz ;
55  nrow = T->nrow ;
56  ncol = T->ncol ;
57  stype = SIGN (T->stype) ;
58 
59  /* ---------------------------------------------------------------------- */
60  /* construct the row form */
61  /* ---------------------------------------------------------------------- */
62 
63  /* if Ti is jumbled, this part dominates the run time */
64 
65  if (stype > 0)
66  {
67  for (k = 0 ; k < nz ; k++)
68  {
69  i = Ti [k] ;
70  j = Tj [k] ;
71  if (i < j)
72  {
73  /* place triplet (j,i,x) in column i of R */
74  p = Wj [i]++ ;
75  Ri [p] = j ;
76  }
77  else
78  {
79  /* place triplet (i,j,x) in column j of R */
80  p = Wj [j]++ ;
81  Ri [p] = i ;
82  }
83  ASSIGN (Rx, Rz, p, Tx, Tz, k) ;
84  }
85  }
86  else if (stype < 0)
87  {
88  for (k = 0 ; k < nz ; k++)
89  {
90  i = Ti [k] ;
91  j = Tj [k] ;
92  if (i > j)
93  {
94  /* place triplet (j,i,x) in column i of R */
95  p = Wj [i]++ ;
96  Ri [p] = j ;
97  }
98  else
99  {
100  /* place triplet (i,j,x) in column j of R */
101  p = Wj [j]++ ;
102  Ri [p] = i ;
103  }
104  ASSIGN (Rx, Rz, p, Tx, Tz, k) ;
105  }
106  }
107  else
108  {
109  for (k = 0 ; k < nz ; k++)
110  {
111  /* place triplet (i,j,x) in column i of R */
112  p = Wj [Ti [k]]++ ;
113  Ri [p] = Tj [k] ;
114  ASSIGN (Rx, Rz, p, Tx, Tz, k) ;
115  }
116  }
117 
118  /* done using Wj (i/l/l) as temporary row pointers ] */
119 
120  /* ---------------------------------------------------------------------- */
121  /* sum up duplicates */
122  /* ---------------------------------------------------------------------- */
123 
124  /* use Wj (i/l/l) of size ncol to keep track of duplicates in each row [ */
125  for (j = 0 ; j < ncol ; j++)
126  {
127  Wj [j] = EMPTY ;
128  }
129 
130  anz = 0 ;
131  for (i = 0 ; i < nrow ; i++)
132  {
133  p1 = Rp [i] ;
134  p2 = Rp [i+1] ;
135  pdest = p1 ;
136  /* at this point Wj [j] < p1 holds true for all columns j, because
137  * Ri/Rx is stored in row oriented manner */
138  for (p = p1 ; p < p2 ; p++)
139  {
140  j = Ri [p] ;
141  pj = Wj [j] ;
142  if (pj >= p1)
143  {
144  /* this column index j is already in row i at position pj;
145  * sum up the duplicate entry */
146  /* Rx [pj] += Rx [p] ; */
147  ASSEMBLE (Rx, Rz, pj, Rx, Rz, p) ;
148  }
149  else
150  {
151  /* keep the entry and keep track in Wj [j] for case above */
152  Wj [j] = pdest ;
153  if (pdest != p)
154  {
155  Ri [pdest] = j ;
156  ASSIGN (Rx, Rz, pdest, Rx, Rz, p) ;
157  }
158  pdest++ ;
159  }
160  }
161  Rnz [i] = pdest - p1 ;
162  anz += (pdest - p1) ;
163  }
164  /* done using Wj to keep track of duplicate entries in each row ] */
165 
166  /* ---------------------------------------------------------------------- */
167  /* return number of entries after summing up duplicates */
168  /* ---------------------------------------------------------------------- */
169 
170  return (anz) ;
171 }
172 
173 #undef PATTERN
174 #undef REAL
175 #undef COMPLEX
176 #undef ZOMPLEX
#define EMPTY
#define Int
#define SIGN(x)
#define ASSEMBLE(c, a)
static size_t TEMPLATE() cholmod_triplet_to_sparse(cholmod_triplet *T, cholmod_sparse *R, cholmod_common *Common)
#define ASSIGN(c, s1, s2, p, split)