Matrix r5059
Loading...
Searching...
No Matches
lu.c
Go to the documentation of this file.
1#include "Lapack-etc.h"
2#include "cs-etc.h"
3#include "Mdefines.h"
4
5/* defined in ./coerce.c : */
6SEXP dense_as_kind(SEXP, const char *, char, int);
7SEXP dense_as_general(SEXP, const char *, int);
8SEXP sparse_as_kind(SEXP, const char *, char);
9SEXP sparse_as_general(SEXP, const char *);
10SEXP sparse_as_Csparse(SEXP, const char *);
11
12SEXP dense_lu(SEXP obj, const char *class, int warn)
13{
14 char cl[] = ".denseLU";
15 cl[0] = (class[0] == 'z') ? 'z' : 'd';
16 SEXP ans = PROTECT(newObject(cl));
17 int *pdim = DIM(obj), m = pdim[0], n = pdim[1], r = (m < n) ? m : n;
18 SET_DIM(ans, m, n);
19 SET_DIMNAMES(ans, -(class[1] == 's'), DIMNAMES(obj, 0));
20 if (r > 0) {
21 PROTECT_INDEX pid;
22 PROTECT_WITH_INDEX(obj, &pid);
23 if (class[0] != 'z' && class[0] != 'd') {
24 REPROTECT(obj = dense_as_kind(obj, class, ',', 1), pid);
25 class = Matrix_class(obj, valid_dense, 6, __func__);
26 }
27 if (class[1] != 'g')
28 REPROTECT(obj = dense_as_general(obj, class, 1), pid);
29 SEXP perm = PROTECT(Rf_allocVector(INTSXP, r)),
30 x = PROTECT(GET_SLOT(obj, Matrix_xSym)),
31 y = PROTECT(Rf_allocVector(TYPEOF(x), XLENGTH(x)));
32 int *pperm = INTEGER(perm), info;
33 if (TYPEOF(x) == CPLXSXP) {
34 Rcomplex *px = COMPLEX(x), *py = COMPLEX(y);
35 memcpy(py, px, sizeof(Rcomplex) * (size_t) XLENGTH(y));
36 F77_CALL(zgetrf)(&m, &n, py, &m, pperm, &info);
37 ERROR_LAPACK_2(zgetrf, info, warn, U);
38 } else {
39 double *px = REAL(x), *py = REAL(y);
40 memcpy(py, px, sizeof(double) * (size_t) XLENGTH(y));
41 F77_CALL(dgetrf)(&m, &n, py, &m, pperm, &info);
42 ERROR_LAPACK_2(dgetrf, info, warn, U);
43 }
44 SET_SLOT(ans, Matrix_permSym, perm);
45 SET_SLOT(ans, Matrix_xSym, y);
46 UNPROTECT(4); /* y, x, perm, obj */
47 }
48 UNPROTECT(1); /* ans */
49 return ans;
50}
51
52/* copy and paste in ./qr.c : */
53#define DO_FREE(_T_, _S_, _N_, _P_) \
54do { \
55 if (!(_T_)) \
56 _T_ = Matrix_cs_spfree(_T_); \
57 if (!(_S_)) \
58 _S_ = Matrix_cs_sfree (_S_); \
59 if (!(_N_)) \
60 _N_ = Matrix_cs_nfree (_N_); \
61 if (!(_P_)) \
62 _P_ = Matrix_cs_free (_P_); \
63} while (0)
64
65/* copy and paste in ./qr.c : */
66#define DO_SORT(_A_, _T_) \
67do { \
68 Matrix_cs_dropzeros(_A_); \
69 _T_ = Matrix_cs_transpose(_A_, 1); \
70 if (!_T_) \
71 goto oom; \
72 _A_ = Matrix_cs_spfree(_A_); \
73 _A_ = Matrix_cs_transpose(_T_, 1); \
74 if (!_A_) \
75 goto oom; \
76 _T_ = Matrix_cs_spfree(_T_); \
77} while (0)
78
79SEXP sparse_lu(SEXP obj, const char *class, int warn, int order,
80 double tol)
81{
82 PROTECT_INDEX pid;
83 PROTECT_WITH_INDEX(obj, &pid);
84 if (class[0] != 'z' && class[0] != 'd') {
85 REPROTECT(obj = sparse_as_kind(obj, class, ','), pid);
86 class = Matrix_class(obj, valid_sparse, 6, __func__);
87 }
88 if (class[1] != 'g') {
89 REPROTECT(obj = sparse_as_general(obj, class), pid);
90 class = Matrix_class(obj, valid_sparse, 6, __func__);
91 }
92 if (class[2] != 'C') {
93 REPROTECT(obj = sparse_as_Csparse(obj, class), pid);
94 class = Matrix_class(obj, valid_sparse, 6, __func__);
95 }
96
97 Matrix_cs *A = M2CXS(obj, 1);
99
100 if (A->m < A->n)
101 Rf_error(_("sparse LU factorization of m-by-n matrix requires m == n"));
102
103 Matrix_cs *T = NULL;
104 Matrix_css *S = NULL;
105 Matrix_csn *N = NULL;
106 int *P = NULL;
107
108 if (!(S = Matrix_cs_sqr(order, A, 0)) ||
109 !(N = Matrix_cs_lu(A, S, tol)) ||
110 !(P = Matrix_cs_pinv(N->pinv, A->m)))
111 goto oom;
112 DO_SORT(N->L, T);
113 DO_SORT(N->U, T);
114
115 char cl[] = ".sparseLU";
116 cl[0] = (A->xtype == CXSPARSE_COMPLEX) ? 'z' : 'd';
117 SEXP ans = PROTECT(newObject(cl));
118
119 SET_DIM(ans, A->m, A->n);
120 SET_DIMNAMES(ans, 0, DIMNAMES(obj, 0));
121
122 SEXP L = PROTECT(CXS2M(N->L, 1, 't')),
123 U = PROTECT(CXS2M(N->U, 1, 't'));
124 SET_UPLO(L);
125 SET_SLOT(ans, Matrix_LSym, L);
126 SET_SLOT(ans, Matrix_USym, U);
127 UNPROTECT(2); /* U, L */
128
129 SEXP p = PROTECT(Rf_allocVector(INTSXP, A->m));
130 memcpy(INTEGER(p), P, sizeof(int) * (size_t) A->m);
131 SET_SLOT(ans, Matrix_pSym, p);
132 UNPROTECT(1); /* p */
133 if (order > 0) {
134 SEXP q = PROTECT(Rf_allocVector(INTSXP, A->n));
135 memcpy(INTEGER(q), S->q, sizeof(int) * (size_t) A->n);
136 SET_SLOT(ans, Matrix_qSym, q);
137 UNPROTECT(1); /* q */
138 }
139
140 DO_FREE(T, S, N, P);
141 UNPROTECT(2); /* ans, obj */
142 return ans;
143
144oom:
145 DO_FREE(T, S, N, P);
146 if (warn > 1)
147 Rf_error (_("sparse LU factorization failed: out of memory or near-singular"));
148 else if (warn > 0)
149 Rf_warning(_("sparse LU factorization failed: out of memory or near-singular"));
150 UNPROTECT(1); /* obj */
151 return R_NilValue;
152}
153
154SEXP R_dense_lu(SEXP s_obj, SEXP s_warn)
155{
156 const char *class = Matrix_class(s_obj, valid_dense, 6, __func__);
157 int cache =
158 (class[1] == 'g' || class[1] == 's') &&
159 (class[0] == 'z' || class[0] == 'd');
160 const char *nm = "denseLU";
161 SEXP ans = (cache) ? get_factor(s_obj, nm) : R_NilValue;
162 if (ans == R_NilValue) {
163 int warn = Rf_asLogical(s_warn);
164 ans = dense_lu(s_obj, class, warn);
165 if (cache) {
166 PROTECT(ans);
167 set_factor(s_obj, nm, ans);
168 UNPROTECT(1);
169 }
170 }
171 return ans;
172}
173
174SEXP R_sparse_lu(SEXP s_obj, SEXP s_warn, SEXP s_order, SEXP s_tol)
175{
176 const char *class = Matrix_class(s_obj, valid_sparse, 6, __func__);
177 double tol = Rf_asReal(s_tol);
178 if (ISNAN(tol))
179 Rf_error(_("'%s' is not a number"), "tol");
180 int order = Rf_asInteger(s_order);
181 if (order == NA_INTEGER)
182 order = (tol == 1.0) ? 2 : 1;
183 else if (order < 0 || order > 3)
184 order = 0;
185 int cache =
186 (class[1] == 'g' || class[1] == 's') &&
187 (class[0] == 'z' || class[0] == 'd');
188 const char *nm = (order == 0) ? "sparseLU-" : "sparseLU+";
189 SEXP ans = (cache) ? get_factor(s_obj, nm) : R_NilValue;
190 if (ans == R_NilValue) {
191 int warn = Rf_asInteger(s_warn);
192 ans = sparse_lu(s_obj, class, warn, order, tol);
193 if (cache) {
194 PROTECT(ans);
195 set_factor(s_obj, nm, ans);
196 UNPROTECT(1);
197 }
198 }
199 return ans;
200}
#define ERROR_LAPACK_2(_ROUTINE_, _INFO_, _WARN_, _LETTER_)
Definition Lapack-etc.h:25
#define SET_DIM(x, m, n)
Definition Mdefines.h:87
const char * valid_dense[]
Definition objects.c:3
#define _(String)
Definition Mdefines.h:66
#define SET_UPLO(x)
Definition Mdefines.h:103
#define SET_DIMNAMES(x, mode, value)
Definition Mdefines.h:98
const char * Matrix_class(SEXP, const char **, int, const char *)
Definition objects.c:112
#define DIMNAMES(x, mode)
Definition Mdefines.h:96
#define DIM(x)
Definition Mdefines.h:85
#define GET_SLOT(x, name)
Definition Mdefines.h:72
SEXP newObject(const char *)
Definition objects.c:13
const char * valid_sparse[]
Definition Mdefines.h:328
#define SET_SLOT(x, name, value)
Definition Mdefines.h:73
#define TYPEOF(s)
Definition Mdefines.h:123
SEXP get_factor(SEXP obj, const char *nm)
Definition attrib.c:180
void set_factor(SEXP obj, const char *nm, SEXP val)
Definition attrib.c:192
cholmod_common cl
Definition cholmod-etc.c:6
Matrix_csn * Matrix_cs_lu(const Matrix_cs *A, const Matrix_css *S, double tol)
Definition cs-etc.c:161
SEXP CXS2M(Matrix_cs *A, int values, char shape)
Definition cs-etc.c:42
int * Matrix_cs_pinv(const int *p, int n)
Definition cs-etc.c:222
Matrix_css * Matrix_cs_sqr(int order, const Matrix_cs *A, int qr)
Definition cs-etc.c:373
Matrix_cs * M2CXS(SEXP obj, int values)
Definition cs-etc.c:6
#define CXSPARSE_XTYPE_SET(_VALUE_)
Definition cs-etc.h:12
#define CXSPARSE_COMPLEX
Definition cs-etc.h:9
SEXP Matrix_permSym
Definition init.c:623
SEXP Matrix_xSym
Definition init.c:635
SEXP Matrix_LSym
Definition init.c:599
SEXP Matrix_qSym
Definition init.c:627
SEXP Matrix_USym
Definition init.c:601
SEXP Matrix_pSym
Definition init.c:622
SEXP R_sparse_lu(SEXP s_obj, SEXP s_warn, SEXP s_order, SEXP s_tol)
Definition lu.c:174
SEXP sparse_as_general(SEXP, const char *)
Definition coerce.c:2298
#define DO_FREE(_T_, _S_, _N_, _P_)
Definition lu.c:53
SEXP dense_as_general(SEXP, const char *, int)
Definition coerce.c:2237
SEXP sparse_as_kind(SEXP, const char *, char)
Definition coerce.c:2076
#define DO_SORT(_A_, _T_)
Definition lu.c:66
SEXP R_dense_lu(SEXP s_obj, SEXP s_warn)
Definition lu.c:154
SEXP dense_lu(SEXP obj, const char *class, int warn)
Definition lu.c:12
SEXP sparse_as_Csparse(SEXP, const char *)
Definition coerce.c:2731
SEXP sparse_lu(SEXP obj, const char *class, int warn, int order, double tol)
Definition lu.c:79
SEXP dense_as_kind(SEXP, const char *, char, int)
Definition coerce.c:2000
Matrix_cs * L
Definition cs-etc.h:42
Matrix_cs * U
Definition cs-etc.h:43