Amesos Package Browser (Single Doxygen Collection)  Development
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
amesos_klu_extract.c
Go to the documentation of this file.
1 /* ========================================================================== */
2 /* === KLU_extract ========================================================== */
3 /* ========================================================================== */
4 
5 /* Extract KLU factorization into conventional compressed-column matrices.
6  * If any output array is NULL, that part of the LU factorization is not
7  * extracted (this is not an error condition).
8  *
9  * nnz(L) = Numeric->lnz, nnz(U) = Numeric->unz, and nnz(F) = Numeric->Offp [n]
10  */
11 
12 #include "amesos_klu_internal.h"
13 
14 Int KLU_extract /* returns TRUE if successful, FALSE otherwise */
15 (
16  /* inputs: */
17  KLU_numeric *Numeric,
18  KLU_symbolic *Symbolic,
19 
20  /* outputs, all of which must be allocated on input */
21 
22  /* L */
23  Int *Lp, /* size n+1 */
24  Int *Li, /* size nnz(L) */
25  double *Lx, /* size nnz(L) */
26 #ifdef COMPLEX
27  double *Lz, /* size nnz(L) for the complex case, ignored if real */
28 #endif
29 
30  /* U */
31  Int *Up, /* size n+1 */
32  Int *Ui, /* size nnz(U) */
33  double *Ux, /* size nnz(U) */
34 #ifdef COMPLEX
35  double *Uz, /* size nnz(U) for the complex case, ignored if real */
36 #endif
37 
38  /* F */
39  Int *Fp, /* size n+1 */
40  Int *Fi, /* size nnz(F) */
41  double *Fx, /* size nnz(F) */
42 #ifdef COMPLEX
43  double *Fz, /* size nnz(F) for the complex case, ignored if real */
44 #endif
45 
46  /* P, row permutation */
47  Int *P, /* size n */
48 
49  /* Q, column permutation */
50  Int *Q, /* size n */
51 
52  /* Rs, scale factors */
53  double *Rs, /* size n */
54 
55  /* R, block boundaries */
56  Int *R, /* size nblocks+1 */
57 
58  KLU_common *Common
59 )
60 {
61  Int *Lip, *Llen, *Uip, *Ulen, *Li2, *Ui2 ;
62  Unit *LU ;
63  Entry *Lx2, *Ux2, *Ukk ;
64  Int i, k, block, nblocks, n, nz, k1, k2, nk, len, kk, p ;
65 
66  if (Common == NULL)
67  {
68  return (FALSE) ;
69  }
70 
71  if (Symbolic == NULL || Numeric == NULL)
72  {
73  Common->status = KLU_INVALID ;
74  return (FALSE) ;
75  }
76 
77  Common->status = KLU_OK ;
78  n = Symbolic->n ;
79  nblocks = Symbolic->nblocks ;
80 
81  /* ---------------------------------------------------------------------- */
82  /* extract scale factors */
83  /* ---------------------------------------------------------------------- */
84 
85  if (Rs != NULL)
86  {
87  if (Numeric->Rs != NULL)
88  {
89  for (i = 0 ; i < n ; i++)
90  {
91  Rs [i] = Numeric->Rs [i] ;
92  }
93  }
94  else
95  {
96  /* no scaling */
97  for (i = 0 ; i < n ; i++)
98  {
99  Rs [i] = 1 ;
100  }
101  }
102  }
103 
104  /* ---------------------------------------------------------------------- */
105  /* extract block boundaries */
106  /* ---------------------------------------------------------------------- */
107 
108  if (R != NULL)
109  {
110  for (block = 0 ; block <= nblocks ; block++)
111  {
112  R [block] = Symbolic->R [block] ;
113  }
114  }
115 
116  /* ---------------------------------------------------------------------- */
117  /* extract final row permutation */
118  /* ---------------------------------------------------------------------- */
119 
120  if (P != NULL)
121  {
122  for (k = 0 ; k < n ; k++)
123  {
124  P [k] = Numeric->Pnum [k] ;
125  }
126  }
127 
128  /* ---------------------------------------------------------------------- */
129  /* extract column permutation */
130  /* ---------------------------------------------------------------------- */
131 
132  if (Q != NULL)
133  {
134  for (k = 0 ; k < n ; k++)
135  {
136  Q [k] = Symbolic->Q [k] ;
137  }
138  }
139 
140  /* ---------------------------------------------------------------------- */
141  /* extract each block of L */
142  /* ---------------------------------------------------------------------- */
143 
144  if (Lp != NULL && Li != NULL && Lx != NULL
145 #ifdef COMPLEX
146  && Lz != NULL
147 #endif
148  )
149  {
150  nz = 0 ;
151  for (block = 0 ; block < nblocks ; block++)
152  {
153  k1 = Symbolic->R [block] ;
154  k2 = Symbolic->R [block+1] ;
155  nk = k2 - k1 ;
156  if (nk == 1)
157  {
158  /* singleton block */
159  Lp [k1] = nz ;
160  Li [nz] = k1 ;
161  Lx [nz] = 1 ;
162 #ifdef COMPLEX
163  Lz [nz] = 0 ;
164 #endif
165  nz++ ;
166  }
167  else
168  {
169  /* non-singleton block */
170  LU = Numeric->LUbx [block] ;
171  Lip = Numeric->Lip + k1 ;
172  Llen = Numeric->Llen + k1 ;
173  for (kk = 0 ; kk < nk ; kk++)
174  {
175  Lp [k1+kk] = nz ;
176  /* add the unit diagonal entry */
177  Li [nz] = k1 + kk ;
178  Lx [nz] = 1 ;
179 #ifdef COMPLEX
180  Lz [nz] = 0 ;
181 #endif
182  nz++ ;
183  GET_POINTER (LU, Lip, Llen, Li2, Lx2, kk, len) ;
184  for (p = 0 ; p < len ; p++)
185  {
186  Li [nz] = k1 + Li2 [p] ;
187  Lx [nz] = REAL (Lx2 [p]) ;
188 #ifdef COMPLEX
189  Lz [nz] = IMAG (Lx2 [p]) ;
190 #endif
191  nz++ ;
192  }
193  }
194  }
195  }
196  Lp [n] = nz ;
197  ASSERT (nz == Numeric->lnz) ;
198  }
199 
200  /* ---------------------------------------------------------------------- */
201  /* extract each block of U */
202  /* ---------------------------------------------------------------------- */
203 
204  if (Up != NULL && Ui != NULL && Ux != NULL
205 #ifdef COMPLEX
206  && Uz != NULL
207 #endif
208  )
209  {
210  nz = 0 ;
211  for (block = 0 ; block < nblocks ; block++)
212  {
213  k1 = Symbolic->R [block] ;
214  k2 = Symbolic->R [block+1] ;
215  nk = k2 - k1 ;
216  Ukk = ((Entry *) Numeric->Udiag) + k1 ;
217  if (nk == 1)
218  {
219  /* singleton block */
220  Up [k1] = nz ;
221  Ui [nz] = k1 ;
222  Ux [nz] = REAL (Ukk [0]) ;
223 #ifdef COMPLEX
224  Uz [nz] = IMAG (Ukk [0]) ;
225 #endif
226  nz++ ;
227  }
228  else
229  {
230  /* non-singleton block */
231  LU = Numeric->LUbx [block] ;
232  Uip = Numeric->Uip + k1 ;
233  Ulen = Numeric->Ulen + k1 ;
234  for (kk = 0 ; kk < nk ; kk++)
235  {
236  Up [k1+kk] = nz ;
237  GET_POINTER (LU, Uip, Ulen, Ui2, Ux2, kk, len) ;
238  for (p = 0 ; p < len ; p++)
239  {
240  Ui [nz] = k1 + Ui2 [p] ;
241  Ux [nz] = REAL (Ux2 [p]) ;
242 #ifdef COMPLEX
243  Uz [nz] = IMAG (Ux2 [p]) ;
244 #endif
245  nz++ ;
246  }
247  /* add the diagonal entry */
248  Ui [nz] = k1 + kk ;
249  Ux [nz] = REAL (Ukk [kk]) ;
250 #ifdef COMPLEX
251  Uz [nz] = IMAG (Ukk [kk]) ;
252 #endif
253  nz++ ;
254  }
255  }
256  }
257  Up [n] = nz ;
258  ASSERT (nz == Numeric->unz) ;
259  }
260 
261  /* ---------------------------------------------------------------------- */
262  /* extract the off-diagonal blocks, F */
263  /* ---------------------------------------------------------------------- */
264 
265  if (Fp != NULL && Fi != NULL && Fx != NULL
266 #ifdef COMPLEX
267  && Fz != NULL
268 #endif
269  )
270  {
271  for (k = 0 ; k <= n ; k++)
272  {
273  Fp [k] = Numeric->Offp [k] ;
274  }
275  nz = Fp [n] ;
276  for (k = 0 ; k < nz ; k++)
277  {
278  Fi [k] = Numeric->Offi [k] ;
279  }
280  for (k = 0 ; k < nz ; k++)
281  {
282  Fx [k] = REAL (((Entry *) Numeric->Offx) [k]) ;
283 #ifdef COMPLEX
284  Fz [k] = IMAG (((Entry *) Numeric->Offx) [k]) ;
285 #endif
286  }
287  }
288 
289  return (TRUE) ;
290 }
#define GET_POINTER(LU, Xip, Xlen, Xi, Xx, k, xlen)
#define REAL
#define COMPLEX
#define KLU_INVALID
#define KLU_symbolic
#define Int
#define FALSE
#define P(k)
double Unit
#define IMAG(c)
#define NULL
#define ASSERT(expression)
#define KLU_numeric
Int KLU_extract(KLU_numeric *Numeric, KLU_symbolic *Symbolic, Int *Lp, Int *Li, double *Lx, Int *Up, Int *Ui, double *Ux, Int *Fp, Int *Fi, double *Fx, Int *P, Int *Q, double *Rs, Int *R, KLU_common *Common)
#define KLU_common
#define Entry
int n
#define TRUE
#define KLU_OK