Matrix r5059
Loading...
Searching...
No Matches
BunchKaufman.c
Go to the documentation of this file.
1#include "Lapack-etc.h"
2#include "Mdefines.h"
3
4/* defined in ./coerce.c : */
5SEXP dense_as_kind(SEXP, const char *, char, int);
6
7/* defined in ./forceCanonical.c : */
8SEXP dense_force_canonical(SEXP, const char *, int);
9
10SEXP dense_bunchkaufman(SEXP obj, const char *class, int warn,
11 char ul, char ct)
12{
13 int *pdim = DIM(obj), n = pdim[1];
14 if (pdim[0] != n)
15 Rf_error(_("matrix is not square"));
16 ul = (class[1] != 'g') ? UPLO(obj) : (ul == '\0') ? 'U' : ul;
17 ct = (class[1] == 's' && class[0] == 'z') ? TRANS(obj) : ct;
18 char cl[] = ".denseBunchKaufman";
19 cl[0] = (class[0] == 'z') ? 'z' : 'd';
20 SEXP ans = PROTECT(newObject(cl));
21 SET_DIM(ans, n, n);
22 SET_DIMNAMES(ans, -(class[1] == 's'), DIMNAMES(obj, 0));
23 if (ul != 'U')
24 SET_UPLO(ans);
25 if (ct != 'C' && class[0] == 'z')
26 SET_TRANS(ans);
27 if (n > 0) {
28 PROTECT_INDEX pid;
29 PROTECT_WITH_INDEX(obj, &pid);
30 if (class[0] != 'z' && class[0] != 'd') {
31 REPROTECT(obj = dense_as_kind(obj, class, ',', 1), pid);
32 class = Matrix_class(obj, valid_dense, 6, __func__);
33 }
34 if (class[1] == 't' && DIAG(obj) != 'N')
35 REPROTECT(obj = dense_force_canonical(obj, class, 0), pid);
36 SEXP perm = PROTECT(Rf_allocVector(INTSXP, n)),
37 x = PROTECT(GET_SLOT(obj, Matrix_xSym)),
38 y = PROTECT(Rf_allocVector(TYPEOF(x), XLENGTH(x)));
39 int *pperm = INTEGER(perm), info;
40 if (class[2] != 'p') {
41 int lwork = -1;
42 if (TYPEOF(x) == CPLXSXP) {
43 Rcomplex *px = COMPLEX(x), *py = COMPLEX(y), tmp, *work;
44 memset(py, 0, sizeof(Rcomplex) * (size_t) XLENGTH(y));
45 F77_CALL(zlacpy)(&ul, &n, &n, px, &n, py, &n FCONE);
46 if (ct == 'C') {
47 F77_CALL(zhetrf)(&ul, &n, py, &n, pperm, &tmp, &lwork, &info FCONE);
48 lwork = (int) tmp.r;
49 work = (Rcomplex *) R_alloc((size_t) lwork, sizeof(Rcomplex));
50 F77_CALL(zhetrf)(&ul, &n, py, &n, pperm, work, &lwork, &info FCONE);
51 ERROR_LAPACK_2(zhetrf, info, warn, D);
52 } else {
53 F77_CALL(zsytrf)(&ul, &n, py, &n, pperm, &tmp, &lwork, &info FCONE);
54 lwork = (int) tmp.r;
55 work = (Rcomplex *) R_alloc((size_t) lwork, sizeof(Rcomplex));
56 F77_CALL(zsytrf)(&ul, &n, py, &n, pperm, work, &lwork, &info FCONE);
57 ERROR_LAPACK_2(zsytrf, info, warn, D);
58 }
59 } else {
60 double *px = REAL(x), *py = REAL(y), tmp, *work;
61 memset(py, 0, sizeof(double) * (size_t) XLENGTH(y));
62 F77_CALL(dlacpy)(&ul, &n, &n, px, &n, py, &n FCONE);
63 F77_CALL(dsytrf)(&ul, &n, py, &n, pperm, &tmp, &lwork, &info FCONE);
64 lwork = (int) tmp;
65 work = (double *) R_alloc((size_t) lwork, sizeof(double));
66 F77_CALL(dsytrf)(&ul, &n, py, &n, pperm, work, &lwork, &info FCONE);
67 ERROR_LAPACK_2(dsytrf, info, warn, D);
68 }
69 } else {
70 if (TYPEOF(x) == CPLXSXP) {
71 Rcomplex *px = COMPLEX(x), *py = COMPLEX(y);
72 memcpy(py, px, sizeof(Rcomplex) * (size_t) XLENGTH(y));
73 if (ct == 'C') {
74 F77_CALL(zhptrf)(&ul, &n, py, pperm, &info FCONE);
75 ERROR_LAPACK_2(zhptrf, info, warn, D);
76 } else {
77 F77_CALL(zsptrf)(&ul, &n, py, pperm, &info FCONE);
78 ERROR_LAPACK_2(zsptrf, info, warn, D);
79 }
80 } else {
81 double *px = REAL(x), *py = REAL(y);
82 memcpy(py, px, sizeof(double) * (size_t) XLENGTH(y));
83 F77_CALL(dsptrf)(&ul, &n, py, pperm, &info FCONE);
84 ERROR_LAPACK_2(dsptrf, info, warn, D);
85 }
86 }
87 SET_SLOT(ans, Matrix_permSym, perm);
88 SET_SLOT(ans, Matrix_xSym, y);
89 UNPROTECT(4); /* y, x, perm, obj */
90 }
91 UNPROTECT(1); /* ans */
92 return ans;
93}
94
95SEXP R_dense_bunchkaufman(SEXP s_obj, SEXP s_warn,
96 SEXP s_uplo, SEXP s_trans)
97{
98 const char *class = Matrix_class(s_obj, valid_dense, 6, __func__);
99 char ul = '\0', ct = '\0';
100 if (s_uplo != R_NilValue)
101 VALID_UPLO (s_uplo , ul);
102 VALID_TRANS(s_trans, ct);
103 int cache = (class[1] == 's') &&
104 (class[0] == 'z' || class[0] == 'd');
105 const char *nm = (class[1] == 's' && class[2] == 'p')
106 ? "denseBunchKaufman-"
107 : "denseBunchKaufman+";
108 SEXP ans = (cache) ? get_factor(s_obj, nm) : R_NilValue;
109 if (ans == R_NilValue) {
110 int warn = Rf_asInteger(s_warn);
111 ans = dense_bunchkaufman(s_obj, class, warn, ul, ct);
112 if (cache) {
113 PROTECT(ans);
114 set_factor(s_obj, nm, ans);
115 UNPROTECT(1);
116 }
117 }
118 return ans;
119}
SEXP dense_force_canonical(SEXP, const char *, int)
SEXP R_dense_bunchkaufman(SEXP s_obj, SEXP s_warn, SEXP s_uplo, SEXP s_trans)
SEXP dense_bunchkaufman(SEXP obj, const char *class, int warn, char ul, char ct)
SEXP dense_as_kind(SEXP, const char *, char, int)
Definition coerce.c:2000
#define FCONE
Definition Lapack-etc.h:13
#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 DIAG(x)
Definition Mdefines.h:111
#define UPLO(x)
Definition Mdefines.h:101
#define SET_DIMNAMES(x, mode, value)
Definition Mdefines.h:98
#define VALID_UPLO(s, c)
Definition Mdefines.h:158
const char * Matrix_class(SEXP, const char **, int, const char *)
Definition objects.c:112
#define DIMNAMES(x, mode)
Definition Mdefines.h:96
#define SET_TRANS(x)
Definition Mdefines.h:108
#define TRANS(x)
Definition Mdefines.h:106
#define DIM(x)
Definition Mdefines.h:85
#define GET_SLOT(x, name)
Definition Mdefines.h:72
#define VALID_TRANS(s, c)
Definition Mdefines.h:166
SEXP newObject(const char *)
Definition objects.c:13
#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
SEXP Matrix_permSym
Definition init.c:623
SEXP Matrix_xSym
Definition init.c:635