1 /* ========================================================================== */
2 /* === Supernodal/cholmod_super_solve ======================================= */
3 /* ========================================================================== */
4
5 /* -----------------------------------------------------------------------------
6 * CHOLMOD/Supernodal Module. Copyright (C) 2005-2006, Timothy A. Davis
7 * http://www.suitesparse.com
8 * -------------------------------------------------------------------------- */
9
10 /* Solve Lx=b or L'x=b for a supernodal factorization. These routines do not
11 * apply the permutation L->Perm. See cholmod_solve for a more general
12 * interface that performs that operation.
13 */
14
15 #ifndef NGPL
16 #ifndef NSUPERNODAL
17
18 #include "cholmod_internal.h"
19 #include "cholmod_supernodal.h"
20
21 /* ========================================================================== */
22 /* === TEMPLATE ============================================================= */
23 /* ========================================================================== */
24
25 #define REAL
26 #include "t_cholmod_super_solve.c"
27 #define COMPLEX
28 #include "t_cholmod_super_solve.c"
29
30 /* ========================================================================== */
31 /* === cholmod_super_lsolve ================================================= */
32 /* ========================================================================== */
33
34 /* Solve Lx=b where x and b are of size n-by-nrhs. b is overwritten by the
35 * solution x. On input, b is stored in col-major order with leading dimension
36 * of d, and on output x is stored in the same manner.
37 *
38 * The contents of the workspace E are undefined on both input and output.
39 *
40 * workspace: none
41 */
42
CHOLMOD(super_lsolve)43 int CHOLMOD(super_lsolve) /* TRUE if OK, FALSE if BLAS overflow occured */
44 (
45 /* ---- input ---- */
46 cholmod_factor *L, /* factor to use for the forward solve */
47 /* ---- output ---- */
48 cholmod_dense *X, /* b on input, solution to Lx=b on output */
49 /* ---- workspace ---- */
50 cholmod_dense *E, /* workspace of size nrhs*(L->maxesize) */
51 /* --------------- */
52 cholmod_common *Common
53 )
54 {
55 /* ---------------------------------------------------------------------- */
56 /* check inputs */
57 /* ---------------------------------------------------------------------- */
58
59 RETURN_IF_NULL_COMMON (FALSE) ;
60 RETURN_IF_NULL (L, FALSE) ;
61 RETURN_IF_NULL (X, FALSE) ;
62 RETURN_IF_NULL (E, FALSE) ;
63 RETURN_IF_XTYPE_INVALID (L, CHOLMOD_REAL, CHOLMOD_COMPLEX, FALSE) ;
64 RETURN_IF_XTYPE_INVALID (X, CHOLMOD_REAL, CHOLMOD_COMPLEX, FALSE) ;
65 RETURN_IF_XTYPE_INVALID (E, CHOLMOD_REAL, CHOLMOD_COMPLEX, FALSE) ;
66 if (L->xtype != X->xtype)
67 {
68 ERROR (CHOLMOD_INVALID, "L and X must have the same xtype") ;
69 return (FALSE) ;
70 }
71 if (L->xtype != E->xtype)
72 {
73 ERROR (CHOLMOD_INVALID, "L and E must have the same xtype") ;
74 return (FALSE) ;
75 }
76 if (X->d < X->nrow || L->n != X->nrow)
77 {
78 ERROR (CHOLMOD_INVALID, "X and L dimensions must match") ;
79 return (FALSE) ;
80 }
81 if (E->nzmax < X->ncol * (L->maxesize))
82 {
83 ERROR (CHOLMOD_INVALID, "workspace E not large enough") ;
84 return (FALSE) ;
85 }
86 if (!(L->is_ll) || !(L->is_super))
87 {
88 ERROR (CHOLMOD_INVALID, "L not supernodal") ;
89 return (FALSE) ;
90 }
91 Common->status = CHOLMOD_OK ;
92 ASSERT (IMPLIES (L->n == 0, L->nsuper == 0)) ;
93 if (L->n == 0 || X->ncol == 0)
94 {
95 /* nothing to do */
96 return (TRUE) ;
97 }
98
99 /* ---------------------------------------------------------------------- */
100 /* solve Lx=b using template routine */
101 /* ---------------------------------------------------------------------- */
102
103 switch (L->xtype)
104 {
105
106 case CHOLMOD_REAL:
107 r_cholmod_super_lsolve (L, X, E, Common) ;
108 break ;
109
110 case CHOLMOD_COMPLEX:
111 c_cholmod_super_lsolve (L, X, E, Common) ;
112 break ;
113 }
114
115 if (CHECK_BLAS_INT && !Common->blas_ok)
116 {
117 ERROR (CHOLMOD_TOO_LARGE, "problem too large for the BLAS") ;
118 }
119 return (Common->blas_ok) ;
120 }
121
122
123 /* ========================================================================== */
124 /* === cholmod_super_ltsolve ================================================ */
125 /* ========================================================================== */
126
127 /* Solve L'x=b where x and b are of size n-by-nrhs. b is overwritten by the
128 * solution x. On input, b is stored in col-major order with leading dimension
129 * of d, and on output x is stored in the same manner.
130 *
131 * The contents of the workspace E are undefined on both input and output.
132 *
133 * workspace: none
134 */
135
CHOLMOD(super_ltsolve)136 int CHOLMOD(super_ltsolve) /* TRUE if OK, FALSE if BLAS overflow occured */
137 (
138 /* ---- input ---- */
139 cholmod_factor *L, /* factor to use for the backsolve */
140 /* ---- output ---- */
141 cholmod_dense *X, /* b on input, solution to L'x=b on output */
142 /* ---- workspace ---- */
143 cholmod_dense *E, /* workspace of size nrhs*(L->maxesize) */
144 /* --------------- */
145 cholmod_common *Common
146 )
147 {
148 /* ---------------------------------------------------------------------- */
149 /* check inputs */
150 /* ---------------------------------------------------------------------- */
151
152 RETURN_IF_NULL_COMMON (FALSE) ;
153 RETURN_IF_NULL (L, FALSE) ;
154 RETURN_IF_NULL (X, FALSE) ;
155 RETURN_IF_NULL (E, FALSE) ;
156 RETURN_IF_XTYPE_INVALID (L, CHOLMOD_REAL, CHOLMOD_COMPLEX, FALSE) ;
157 RETURN_IF_XTYPE_INVALID (X, CHOLMOD_REAL, CHOLMOD_COMPLEX, FALSE) ;
158 RETURN_IF_XTYPE_INVALID (E, CHOLMOD_REAL, CHOLMOD_COMPLEX, FALSE) ;
159 if (L->xtype != X->xtype)
160 {
161 ERROR (CHOLMOD_INVALID, "L and X must have the same xtype") ;
162 return (FALSE) ;
163 }
164 if (L->xtype != E->xtype)
165 {
166 ERROR (CHOLMOD_INVALID, "L and E must have the same xtype") ;
167 return (FALSE) ;
168 }
169 if (X->d < X->nrow || L->n != X->nrow)
170 {
171 ERROR (CHOLMOD_INVALID, "X and L dimensions must match") ;
172 return (FALSE) ;
173 }
174 if (E->nzmax < X->ncol * (L->maxesize))
175 {
176 ERROR (CHOLMOD_INVALID, "workspace E not large enough") ;
177 return (FALSE) ;
178 }
179 if (!(L->is_ll) || !(L->is_super))
180 {
181 ERROR (CHOLMOD_INVALID, "L not supernodal") ;
182 return (FALSE) ;
183 }
184 Common->status = CHOLMOD_OK ;
185 ASSERT (IMPLIES (L->n == 0, L->nsuper == 0)) ;
186 if (L->n == 0 || X->ncol == 0)
187 {
188 /* nothing to do */
189 return (TRUE) ;
190 }
191
192 /* ---------------------------------------------------------------------- */
193 /* solve Lx=b using template routine */
194 /* ---------------------------------------------------------------------- */
195
196 switch (L->xtype)
197 {
198
199 case CHOLMOD_REAL:
200 r_cholmod_super_ltsolve (L, X, E, Common) ;
201 break ;
202
203 case CHOLMOD_COMPLEX:
204 c_cholmod_super_ltsolve (L, X, E, Common) ;
205 break ;
206 }
207
208 if (CHECK_BLAS_INT && !Common->blas_ok)
209 {
210 ERROR (CHOLMOD_TOO_LARGE, "problem too large for the BLAS") ;
211 }
212 return (Common->blas_ok) ;
213 }
214 #endif
215 #endif
216