Matrix r5059
Loading...
Searching...
No Matches
qr.c
Go to the documentation of this file.
1#include "cs-etc.h"
2#include "Mdefines.h"
3
4/* defined in ./coerce.c : */
5SEXP sparse_as_kind(SEXP, const char *, char);
6SEXP sparse_as_general(SEXP, const char *);
7SEXP sparse_as_Csparse(SEXP, const char *);
8
9/* copy and paste in ./lu.c : */
10#define DO_FREE(_T_, _S_, _N_, _P_) \
11do { \
12 if (!(_T_)) \
13 _T_ = Matrix_cs_spfree(_T_); \
14 if (!(_S_)) \
15 _S_ = Matrix_cs_sfree (_S_); \
16 if (!(_N_)) \
17 _N_ = Matrix_cs_nfree (_N_); \
18 if (!(_P_)) \
19 _P_ = Matrix_cs_free (_P_); \
20} while (0)
21
22/* copy and paste in ./lu.c : */
23#define DO_SORT(_A_, _T_) \
24do { \
25 Matrix_cs_dropzeros(_A_); \
26 _T_ = Matrix_cs_transpose(_A_, 1); \
27 if (!_T_) \
28 goto oom; \
29 _A_ = Matrix_cs_spfree(_A_); \
30 _A_ = Matrix_cs_transpose(_T_, 1); \
31 if (!_A_) \
32 goto oom; \
33 _T_ = Matrix_cs_spfree(_T_); \
34} while (0)
35
36SEXP sparse_qr(SEXP obj, const char *class, int warn, int order)
37{
38 PROTECT_INDEX pid;
39 PROTECT_WITH_INDEX(obj, &pid);
40 if (class[0] != 'z' && class[0] != 'd') {
41 REPROTECT(obj = sparse_as_kind(obj, class, ','), pid);
42 class = Matrix_class(obj, valid_sparse, 6, __func__);
43 }
44 if (class[1] != 'g') {
45 REPROTECT(obj = sparse_as_general(obj, class), pid);
46 class = Matrix_class(obj, valid_sparse, 6, __func__);
47 }
48 if (class[2] != 'C') {
49 REPROTECT(obj = sparse_as_Csparse(obj, class), pid);
50 class = Matrix_class(obj, valid_sparse, 6, __func__);
51 }
52
53 Matrix_cs *A = M2CXS(obj, 1);
55
56 if (A->m < A->n)
57 Rf_error(_("sparse QR factorization of m-by-n matrix requires m >= n"));
58
59 Matrix_cs *T = NULL;
60 Matrix_css *S = NULL;
61 Matrix_csn *N = NULL;
62 int *P = NULL;
63
64 if (!(S = Matrix_cs_sqr(order, A, 1)) ||
65 !(N = Matrix_cs_qr(A, S)) ||
66 !(P = Matrix_cs_pinv(S->pinv, S->m2)))
67 goto oom;
68 DO_SORT(N->L, T);
69 DO_SORT(N->U, T);
70
71 char cl[] = ".sparseQR";
72 cl[0] = (A->xtype == CXSPARSE_COMPLEX) ? 'z' : 'd';
73 SEXP ans = PROTECT(newObject(cl));
74
75 SET_DIM(ans, A->m, A->n);
76 SET_DIMNAMES(ans, 0, DIMNAMES(obj, 0));
77
78 SEXP V = PROTECT(CXS2M(N->L, 1, 'g')),
79 R = PROTECT(CXS2M(N->U, 1, 'g'));
80 SET_SLOT(ans, Matrix_VSym, V);
81 SET_SLOT(ans, Matrix_RSym, R);
82 UNPROTECT(2); /* R, V */
83
84 SEXP beta = PROTECT(Rf_allocVector(REALSXP, A->n));
85 memcpy(REAL(beta), N->B, sizeof(double) * (size_t) A->n);
86 SET_SLOT(ans, Matrix_betaSym, beta);
87 UNPROTECT(1); /* beta */
88
89 SEXP p = PROTECT(Rf_allocVector(INTSXP, S->m2));
90 memcpy(INTEGER(p), P, sizeof(int) * (size_t) S->m2);
91 SET_SLOT(ans, Matrix_pSym, p);
92 UNPROTECT(1); /* p */
93
94 if (order > 0) {
95 SEXP q = PROTECT(Rf_allocVector(INTSXP, A->n));
96 memcpy(INTEGER(q), S->q, sizeof(int) * (size_t) A->n);
97 SET_SLOT(ans, Matrix_qSym, q);
98 UNPROTECT(1); /* q */
99 }
100
101 DO_FREE(T, S, N, P);
102 UNPROTECT(2); /* ans, obj */
103 return ans;
104
105oom:
106 DO_FREE(T, S, N, P);
107 if (warn > 1)
108 Rf_error (_("sparse QR factorization failed: out of memory"));
109 else if (warn > 0)
110 Rf_warning(_("sparse QR factorization failed: out of memory"));
111 UNPROTECT(1); /* obj */
112 return R_NilValue;
113}
114
115SEXP R_sparse_qr(SEXP s_obj, SEXP s_warn, SEXP s_order)
116{
117 const char *class = Matrix_class(s_obj, valid_sparse, 6, __func__);
118 int order = Rf_asInteger(s_order);
119 if (order < 0 || order > 3)
120 order = 0;
121 int cache =
122 (class[1] == 'g' || class[1] == 's') &&
123 (class[0] == 'z' || class[0] == 'd');
124 const char *nm = (order == 0) ? "sparseQR-" : "sparseQR+";
125 SEXP ans = (cache) ? get_factor(s_obj, nm) : R_NilValue;
126 if (ans == R_NilValue) {
127 int warn = Rf_asLogical(s_warn);
128 ans = sparse_qr(s_obj, class, warn, order);
129 if (cache) {
130 PROTECT(ans);
131 set_factor(s_obj, nm, ans);
132 UNPROTECT(1);
133 }
134 }
135 return ans;
136}
#define SET_DIM(x, m, n)
Definition Mdefines.h:87
#define _(String)
Definition Mdefines.h:66
#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
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
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_qr(const Matrix_cs *A, const Matrix_css *S)
Definition cs-etc.c:246
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_betaSym
Definition init.c:603
SEXP Matrix_RSym
Definition init.c:600
SEXP Matrix_VSym
Definition init.c:602
SEXP Matrix_qSym
Definition init.c:627
SEXP Matrix_pSym
Definition init.c:622
SEXP sparse_as_general(SEXP, const char *)
Definition coerce.c:2298
#define DO_FREE(_T_, _S_, _N_, _P_)
Definition qr.c:10
SEXP sparse_as_kind(SEXP, const char *, char)
Definition coerce.c:2076
#define DO_SORT(_A_, _T_)
Definition qr.c:23
SEXP sparse_qr(SEXP obj, const char *class, int warn, int order)
Definition qr.c:36
SEXP R_sparse_qr(SEXP s_obj, SEXP s_warn, SEXP s_order)
Definition qr.c:115
SEXP sparse_as_Csparse(SEXP, const char *)
Definition coerce.c:2731
double * B
Definition cs-etc.h:45
Matrix_cs * L
Definition cs-etc.h:42
Matrix_cs * U
Definition cs-etc.h:43