Matrix r5059
Loading...
Searching...
No Matches
Schur.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);
6SEXP dense_as_general(SEXP, const char *, int);
7
8SEXP dense_schur(SEXP obj, const char *class, int warn, int vectors)
9{
10 int *pdim = DIM(obj), n = pdim[1];
11 if (pdim[0] != n)
12 Rf_error(_("matrix is not square"));
13 char cl[] = ".denseSchur";
14 cl[0] = (class[0] == 'z') ? 'z' : 'd';
15 SEXP ans = PROTECT(newObject(cl));
16 SET_DIM(ans, n, n);
17 SET_DIMNAMES(ans, -(class[1] == 's'), DIMNAMES(obj, 0));
18 if (n > 0) {
19 PROTECT_INDEX pid;
20 PROTECT_WITH_INDEX(obj, &pid);
21 if (class[0] != 'z' && class[0] != 'd') {
22 REPROTECT(obj = dense_as_kind(obj, class, ',', 1), pid);
23 class = Matrix_class(obj, valid_dense, 6, __func__);
24 }
25 if ((class[1] == 's' && class[0] == 'z' && TRANS(obj) != 'C') ||
26 (class[1] == 't')) {
27 REPROTECT(obj = dense_as_general(obj, class, 1), pid);
28 class = Matrix_class(obj, valid_dense, 6, __func__);
29 }
30 SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)), y, v, w;
31 int info;
32 if (class[1] == 'g') {
33 PROTECT(y = Rf_allocVector(TYPEOF(x), XLENGTH(x)));
34 PROTECT(v = Rf_allocVector(TYPEOF(x), (vectors) ? XLENGTH(x) : 0));
35 PROTECT(w = Rf_allocVector(TYPEOF(x), n));
36 int lwork = -1, zero = 0;
37 double *rwork = (double *) R_alloc((size_t) n, sizeof(double));
38 if (TYPEOF(x) == CPLXSXP) {
39 Rcomplex *px = COMPLEX(x), *py = COMPLEX(y),
40 *pv = COMPLEX(v), *pw = COMPLEX(w), tmp, *work = &tmp;
41 memcpy(py, px, sizeof(Rcomplex) * (size_t) XLENGTH(y));
42 F77_CALL(zgees)((vectors) ? "V" : "N", "N", NULL,
43 &n, py, &n, &zero, pw, pv, &n,
44 work, &lwork, rwork, NULL, &info FCONE FCONE);
45 lwork = (int) tmp.r;
46 work = (Rcomplex *) R_alloc((size_t) lwork, sizeof(Rcomplex));
47 F77_CALL(zgees)((vectors) ? "V" : "N", "N", NULL,
48 &n, py, &n, &zero, pw, pv, &n,
49 work, &lwork, rwork, NULL, &info FCONE FCONE);
50 ERROR_LAPACK_5(zgees, info, warn);
51 } else {
52 double *px = REAL(x), *py = REAL(y),
53 *pv = REAL(v), *pw = REAL(w), tmp, *work = &tmp;
54 memcpy(py, px, sizeof(double) * (size_t) XLENGTH(y));
55 F77_CALL(dgees)((vectors) ? "V" : "N", "N", NULL,
56 &n, py, &n, &zero, pw, rwork, pv, &n,
57 work, &lwork, NULL, &info FCONE FCONE);
58 lwork = (int) tmp;
59 work = (double *) R_alloc((size_t) lwork, sizeof(double));
60 F77_CALL(dgees)((vectors) ? "V" : "N", "N", NULL,
61 &n, py, &n, &zero, pw, rwork, pv, &n,
62 work, &lwork, NULL, &info FCONE FCONE);
63 ERROR_LAPACK_5(dgees, info, warn);
64 for (int j = 0; j < n; ++j) {
65 if (fabs(rwork[j]) > 10.0 * DBL_EPSILON * fabs(pw[j])) {
66 SEXP w_ = Rf_allocVector(CPLXSXP, n);
67 Rcomplex *pw_ = COMPLEX(w_);
68 for (j = 0; j < n; ++j) {
69 pw_[j].r = pw[j];
70 pw_[j].i = rwork[j];
71 }
72 UNPROTECT(1); /* w */
73 PROTECT(w = w_);
74 break;
75 }
76 }
77 }
78 } else if (class[2] != 'p') {
79 PROTECT(y = Rf_allocVector(TYPEOF(x), 0));
80 PROTECT(v = Rf_allocVector(TYPEOF(x), XLENGTH(x)));
81 PROTECT(w = Rf_allocVector(REALSXP, n));
82 char ul = UPLO(obj);
83 int lwork = -1;
84 double *pw = REAL(w);
85 if (TYPEOF(x) == CPLXSXP) {
86 Rcomplex *px = COMPLEX(x), *pv = COMPLEX(v), tmp, *work = &tmp;
87 double *rwork = (double *) R_alloc((size_t) n * 3, sizeof(double));
88 memcpy(pv, px, sizeof(Rcomplex) * (size_t) XLENGTH(v));
89 F77_CALL(zheev)((vectors) ? "V" : "N", &ul,
90 &n, pv, &n, pw, work, &lwork, rwork, &info FCONE FCONE);
91 lwork = (int) tmp.r;
92 work = (Rcomplex *) R_alloc((size_t) lwork, sizeof(Rcomplex));
93 F77_CALL(zheev)((vectors) ? "V" : "N", &ul,
94 &n, pv, &n, pw, work, &lwork, rwork, &info FCONE FCONE);
95 ERROR_LAPACK_5(zheev, info, warn);
96 } else {
97 double *px = REAL(x), *pv = REAL(v), tmp, *work = &tmp;
98 memcpy(pv, px, sizeof(double) * (size_t) XLENGTH(v));
99 F77_CALL(dsyev)((vectors) ? "V" : "N", &ul,
100 &n, pv, &n, pw, work, &lwork, &info FCONE FCONE);
101 lwork = (int) tmp;
102 work = (double *) R_alloc((size_t) lwork, sizeof(double));
103 F77_CALL(dsyev)((vectors) ? "V" : "N", &ul,
104 &n, pv, &n, pw, work, &lwork, &info FCONE FCONE);
105 ERROR_LAPACK_5(dsyev, info, warn);
106 }
107 } else {
108 PROTECT(y = Rf_allocVector(TYPEOF(x), XLENGTH(x)));
109 PROTECT(v = Rf_allocVector(TYPEOF(x), (vectors) ? (R_xlen_t) n * n : 0));
110 PROTECT(w = Rf_allocVector(REALSXP, n));
111 char ul = UPLO(obj);
112 double *pw = REAL(w);
113 if (TYPEOF(x) == CPLXSXP) {
114 Rcomplex *px = COMPLEX(x), *py = COMPLEX(y), *pv = COMPLEX(v),
115 *work = (Rcomplex *) R_alloc((size_t) n * 2, sizeof(Rcomplex));
116 double *rwork = (double *) R_alloc((size_t) n * 3, sizeof(double));
117 memcpy(py, px, sizeof(Rcomplex) * (size_t) XLENGTH(y));
118 F77_CALL(zhpev)((vectors) ? "V" : "N", &ul,
119 &n, py, pw, pv, &n, work, rwork, &info FCONE FCONE);
120 ERROR_LAPACK_5(zhpev, info, warn);
121 } else {
122 double *px = REAL(x), *py = REAL(y), *pv = REAL(v),
123 *work = (double *) R_alloc((size_t) n * 3, sizeof(double));
124 memcpy(py, px, sizeof(double) * (size_t) XLENGTH(y));
125 F77_CALL(dspev)((vectors) ? "V" : "N", &ul,
126 &n, py, pw, pv, &n, work, &info FCONE FCONE);
127 ERROR_LAPACK_5(dspev, info, warn);
128 }
129 }
130 if (class[1] != 's')
131 SET_SLOT(ans, Matrix_xSym, y);
132 if (vectors)
134 SET_SLOT(ans, Matrix_valuesSym, w);
135 UNPROTECT(5); /* w, v, y, x, obj */
136 }
137 UNPROTECT(1); /* ans */
138 return ans;
139}
140
141SEXP R_dense_schur(SEXP s_obj, SEXP s_warn, SEXP s_vectors)
142{
143 const char *class = Matrix_class(s_obj, valid_dense, 6, __func__);
144 int vectors = Rf_asLogical(s_vectors);
145 int cache = vectors &&
146 (class[1] == 'g' || class[1] == 's') &&
147 (class[0] == 'z' || class[0] == 'd');
148 const char *nm = "denseSchur";
149 SEXP ans = (cache) ? get_factor(s_obj, nm) : R_NilValue;
150 if (ans == R_NilValue) {
151 int warn = Rf_asInteger(s_warn);
152 ans = dense_schur(s_obj, class, warn, vectors);
153 if (cache) {
154 PROTECT(ans);
155 set_factor(s_obj, nm, ans);
156 UNPROTECT(1);
157 }
158 }
159 return ans;
160}
#define FCONE
Definition Lapack-etc.h:13
#define ERROR_LAPACK_5(_ROUTINE_, _INFO_, _WARN_)
Definition Lapack-etc.h:64
#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 UPLO(x)
Definition Mdefines.h:101
#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 TRANS(x)
Definition Mdefines.h:106
#define DIM(x)
Definition Mdefines.h:85
#define GET_SLOT(x, name)
Definition Mdefines.h:72
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 dense_schur(SEXP obj, const char *class, int warn, int vectors)
Definition Schur.c:8
SEXP R_dense_schur(SEXP s_obj, SEXP s_warn, SEXP s_vectors)
Definition Schur.c:141
SEXP dense_as_general(SEXP, const char *, int)
Definition coerce.c:2237
SEXP dense_as_kind(SEXP, const char *, char, int)
Definition coerce.c:2000
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_valuesSym
Definition init.c:633
SEXP Matrix_xSym
Definition init.c:635
SEXP Matrix_vectorsSym
Definition init.c:634