Amesos Package Browser (Single Doxygen Collection)  Development
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
amesos_t_cholmod_transpose.c
Go to the documentation of this file.
1 /* ========================================================================== */
2 /* === Core/t_cholmod_transpose ============================================= */
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_transpose. All xtypes are supported. For
15  * complex matrices, either the array tranpose or complex conjugate transpose
16  * can be computed. */
17 
19 
20 /* ========================================================================== */
21 /* === t_cholmod_transpose_unsym ============================================ */
22 /* ========================================================================== */
23 
24 /* Compute F = A', A (:,f)', or A (p,f)', where A is unsymmetric and F is
25  * already allocated. The complex case performs either the array transpose
26  * or complex conjugate transpose.
27  *
28  * workspace:
29  * Iwork (MAX (nrow,ncol)) if fset is present
30  * Iwork (nrow) if fset is NULL
31  */
32 
33 static int TEMPLATE (cholmod_transpose_unsym)
34 (
35  /* ---- input ---- */
36  cholmod_sparse *A, /* matrix to transpose */
37  Int *Perm, /* size nrow, if present (can be NULL) */
38  Int *fset, /* subset of 0:(A->ncol)-1 */
39  Int nf, /* size of fset */
40  /* ---- output --- */
41  cholmod_sparse *F, /* F = A', A(:,f)', or A(p,f)' */
42  /* --------------- */
43  cholmod_common *Common
44 )
45 {
46  double *Ax, *Az, *Fx, *Fz ;
47  Int *Ap, *Anz, *Ai, *Fp, *Fnz, *Fj, *Wi, *Iwork ;
48  Int j, p, pend, nrow, ncol, Apacked, use_fset, fp, Fpacked, jj, permute ;
49 
50  /* ---------------------------------------------------------------------- */
51  /* check inputs */
52  /* ---------------------------------------------------------------------- */
53 
54  /* ensure the xtype of A and F match (ignored if this is pattern version) */
55  if (!XTYPE_OK (A->xtype))
56  {
57  ERROR (CHOLMOD_INVALID, "real/complex mismatch") ;
58  return (FALSE) ;
59  }
60 
61  /* ---------------------------------------------------------------------- */
62  /* get inputs */
63  /* ---------------------------------------------------------------------- */
64 
65  use_fset = (fset != NULL) ;
66  nrow = A->nrow ;
67  ncol = A->ncol ;
68 
69  Ap = A->p ; /* size A->ncol+1, column pointers of A */
70  Ai = A->i ; /* size nz = Ap [A->ncol], row indices of A */
71  Ax = A->x ; /* size nz, real values of A */
72  Az = A->z ; /* size nz, imag values of A */
73  Anz = A->nz ;
74  Apacked = A->packed ;
75  ASSERT (IMPLIES (!Apacked, Anz != NULL)) ;
76 
77  permute = (Perm != NULL) ;
78 
79  Fp = F->p ; /* size A->nrow+1, row pointers of F */
80  Fj = F->i ; /* size nz, column indices of F */
81  Fx = F->x ; /* size nz, real values of F */
82  Fz = F->z ; /* size nz, imag values of F */
83  Fnz = F->nz ;
84  Fpacked = F->packed ;
85  ASSERT (IMPLIES (!Fpacked, Fnz != NULL)) ;
86 
87  nf = (use_fset) ? nf : ncol ;
88 
89  /* ---------------------------------------------------------------------- */
90  /* get workspace */
91  /* ---------------------------------------------------------------------- */
92 
93  Iwork = Common->Iwork ;
94  Wi = Iwork ; /* size nrow (i/l/l) */
95 
96  /* ---------------------------------------------------------------------- */
97  /* construct the transpose */
98  /* ---------------------------------------------------------------------- */
99 
100  for (jj = 0 ; jj < nf ; jj++)
101  {
102  j = (use_fset) ? (fset [jj]) : jj ;
103  p = Ap [j] ;
104  pend = (Apacked) ? (Ap [j+1]) : (p + Anz [j]) ;
105  for ( ; p < pend ; p++)
106  {
107  fp = Wi [Ai [p]]++ ;
108  Fj [fp] = j ;
109 #ifdef NCONJUGATE
110  ASSIGN (Fx, Fz, fp, Ax, Az, p) ;
111 #else
112  ASSIGN_CONJ (Fx, Fz, fp, Ax, Az, p) ;
113 #endif
114  }
115  }
116 
117  return (TRUE) ;
118 }
119 
120 
121 /* ========================================================================== */
122 /* === t_cholmod_transpose_sym ============================================== */
123 /* ========================================================================== */
124 
125 /* Compute F = A' or A (p,p)', where A is symmetric and F is already allocated.
126  * The complex case performs either the array transpose or complex conjugate
127  * transpose.
128  *
129  * workspace: Iwork (nrow) if Perm NULL, Iwork (2*nrow) if Perm non-NULL.
130  */
131 
132 static int TEMPLATE (cholmod_transpose_sym)
133 (
134  /* ---- input ---- */
135  cholmod_sparse *A, /* matrix to transpose */
136  Int *Perm, /* size n, if present (can be NULL) */
137  /* ---- output --- */
138  cholmod_sparse *F, /* F = A' or A(p,p)' */
139  /* --------------- */
140  cholmod_common *Common
141 )
142 {
143  double *Ax, *Az, *Fx, *Fz ;
144  Int *Ap, *Anz, *Ai, *Fp, *Fj, *Wi, *Pinv, *Iwork ;
145  Int p, pend, packed, fp, upper, permute, jold, n, i, j, iold ;
146 
147  /* ---------------------------------------------------------------------- */
148  /* check inputs */
149  /* ---------------------------------------------------------------------- */
150 
151  /* ensure the xtype of A and F match (ignored if this is pattern version) */
152  if (!XTYPE_OK (A->xtype))
153  {
154  ERROR (CHOLMOD_INVALID, "real/complex mismatch") ;
155  return (FALSE) ;
156  }
157 
158  /* ---------------------------------------------------------------------- */
159  /* get inputs */
160  /* ---------------------------------------------------------------------- */
161 
162  permute = (Perm != NULL) ;
163  n = A->nrow ;
164  Ap = A->p ; /* size A->ncol+1, column pointers of A */
165  Ai = A->i ; /* size nz = Ap [A->ncol], row indices of A */
166  Ax = A->x ; /* size nz, real values of A */
167  Az = A->z ; /* size nz, imag values of A */
168  Anz = A->nz ;
169  packed = A->packed ;
170  ASSERT (IMPLIES (!packed, Anz != NULL)) ;
171  upper = (A->stype > 0) ;
172 
173  Fp = F->p ; /* size A->nrow+1, row pointers of F */
174  Fj = F->i ; /* size nz, column indices of F */
175  Fx = F->x ; /* size nz, real values of F */
176  Fz = F->z ; /* size nz, imag values of F */
177 
178  /* ---------------------------------------------------------------------- */
179  /* get workspace */
180  /* ---------------------------------------------------------------------- */
181 
182  Iwork = Common->Iwork ;
183  Wi = Iwork ; /* size n (i/l/l) */
184  Pinv = Iwork + n ; /* size n (i/i/l) , unused if Perm NULL */
185 
186  /* ---------------------------------------------------------------------- */
187  /* construct the transpose */
188  /* ---------------------------------------------------------------------- */
189 
190  if (permute)
191  {
192  if (upper)
193  {
194  /* permuted, upper */
195  for (j = 0 ; j < n ; j++)
196  {
197  jold = Perm [j] ;
198  p = Ap [jold] ;
199  pend = (packed) ? Ap [jold+1] : p + Anz [jold] ;
200  for ( ; p < pend ; p++)
201  {
202  iold = Ai [p] ;
203  if (iold <= jold)
204  {
205  i = Pinv [iold] ;
206  if (i < j)
207  {
208  fp = Wi [i]++ ;
209  Fj [fp] = j ;
210 #ifdef NCONJUGATE
211  ASSIGN (Fx, Fz, fp, Ax, Az, p) ;
212 #else
213  ASSIGN_CONJ (Fx, Fz, fp, Ax, Az, p) ;
214 #endif
215  }
216  else
217  {
218  fp = Wi [j]++ ;
219  Fj [fp] = i ;
220  ASSIGN (Fx, Fz, fp, Ax, Az, p) ;
221  }
222  }
223  }
224  }
225  }
226  else
227  {
228  /* permuted, lower */
229  for (j = 0 ; j < n ; j++)
230  {
231  jold = Perm [j] ;
232  p = Ap [jold] ;
233  pend = (packed) ? Ap [jold+1] : p + Anz [jold] ;
234  for ( ; p < pend ; p++)
235  {
236  iold = Ai [p] ;
237  if (iold >= jold)
238  {
239  i = Pinv [iold] ;
240  if (i > j)
241  {
242  fp = Wi [i]++ ;
243  Fj [fp] = j ;
244 #ifdef NCONJUGATE
245  ASSIGN (Fx, Fz, fp, Ax, Az, p) ;
246 #else
247  ASSIGN_CONJ (Fx, Fz, fp, Ax, Az, p) ;
248 #endif
249  }
250  else
251  {
252  fp = Wi [j]++ ;
253  Fj [fp] = i ;
254  ASSIGN (Fx, Fz, fp, Ax, Az, p) ;
255  }
256  }
257  }
258  }
259  }
260  }
261  else
262  {
263  if (upper)
264  {
265  /* unpermuted, upper */
266  for (j = 0 ; j < n ; j++)
267  {
268  p = Ap [j] ;
269  pend = (packed) ? Ap [j+1] : p + Anz [j] ;
270  for ( ; p < pend ; p++)
271  {
272  i = Ai [p] ;
273  if (i <= j)
274  {
275  fp = Wi [i]++ ;
276  Fj [fp] = j ;
277 #ifdef NCONJUGATE
278  ASSIGN (Fx, Fz, fp, Ax, Az, p) ;
279 #else
280  ASSIGN_CONJ (Fx, Fz, fp, Ax, Az, p) ;
281 #endif
282  }
283  }
284  }
285  }
286  else
287  {
288  /* unpermuted, lower */
289  for (j = 0 ; j < n ; j++)
290  {
291  p = Ap [j] ;
292  pend = (packed) ? Ap [j+1] : p + Anz [j] ;
293  for ( ; p < pend ; p++)
294  {
295  i = Ai [p] ;
296  if (i >= j)
297  {
298  fp = Wi [i]++ ;
299  Fj [fp] = j ;
300 #ifdef NCONJUGATE
301  ASSIGN (Fx, Fz, fp, Ax, Az, p) ;
302 #else
303  ASSIGN_CONJ (Fx, Fz, fp, Ax, Az, p) ;
304 #endif
305  }
306  }
307  }
308  }
309  }
310 
311  return (TRUE) ;
312 }
313 
314 #undef PATTERN
315 #undef REAL
316 #undef COMPLEX
317 #undef ZOMPLEX
318 #undef NCONJUGATE
#define Int
#define FALSE
#define NULL
#define ASSERT(expression)
static int TEMPLATE() cholmod_transpose_unsym(cholmod_sparse *A, Int *Perm, Int *fset, Int nf, cholmod_sparse *F, cholmod_common *Common)
#define CHOLMOD_INVALID
static int TEMPLATE() cholmod_transpose_sym(cholmod_sparse *A, Int *Perm, cholmod_sparse *F, cholmod_common *Common)
#define IMPLIES(p, q)
int n
#define ERROR(status, msg)
#define TRUE
#define ASSIGN(c, s1, s2, p, split)