Matrix r5059
Loading...
Searching...
No Matches
isTriangular.c
Go to the documentation of this file.
1/* C implementation of methods for isTriangular */
2
3#include "Mdefines.h"
4#include "M5.h"
5#include "idz.h"
6
7/* defined in ./isDiagonal.c :*/
8int dense_is_diagonal(SEXP, const char *);
9int sparse_is_diagonal(SEXP, const char *);
10
11int dense_is_triangular(SEXP obj, const char *class, char op_ul)
12{
13 if (class[1] == 't') {
14 char ul = UPLO(obj);
15 if (op_ul == '\0' || op_ul == ul)
16 return ( ul == 'U') ? 1 : -1;
17 else if (dense_is_diagonal(obj, class))
18 return (op_ul == 'U') ? 1 : -1;
19 else
20 return 0;
21 }
22
23 if (class[1] == 's') {
24 if (!dense_is_diagonal(obj, class))
25 return 0;
26 else if (op_ul != '\0')
27 return (op_ul == 'U') ? 1 : -1;
28 else {
29 char ul = UPLO(obj);
30 return ( ul == 'U') ? 1 : -1;
31 }
32 }
33
34 int *pdim = DIM(obj), n = pdim[1];
35 if (pdim[0] != n)
36 return 0;
37 if (n <= 1)
38 return (op_ul == '\0' || op_ul == 'U') ? 1 : -1;
39
40 SEXP x = GET_SLOT(obj, Matrix_xSym);
41
42#define TEMPLATE(c) \
43 do { \
44 c##TYPE *px = c##PTR(x); \
45 if ((op_ul == '\0' || op_ul == 'U') && \
46 !c##NAME(test2)(px, (size_t) n, 'U', '\0', 'N')) \
47 return 1; \
48 if ((op_ul == '\0' || op_ul != 'U') && \
49 !c##NAME(test2)(px, (size_t) n, 'L', '\0', 'N')) \
50 return -1; \
51 } while (0)
52
53 SWITCH4(class[0], TEMPLATE);
54
55#undef TEMPLATE
56
57 return 0;
58}
59
60int sparse_is_triangular(SEXP obj, const char *class, char op_ul)
61{
62 if (class[1] == 't') {
63 char ul = UPLO(obj);
64 if (op_ul == '\0' || op_ul == ul)
65 return ( ul == 'U') ? 1 : -1;
66 else if (sparse_is_diagonal(obj, class))
67 return (op_ul == 'U') ? 1 : -1;
68 else
69 return 0;
70 }
71
72 if (class[1] == 's') {
73 if (!sparse_is_diagonal(obj, class))
74 return 0;
75 else if (op_ul != '\0')
76 return (op_ul == 'U') ? 1 : -1;
77 else {
78 char ul = UPLO(obj);
79 return ( ul == 'U') ? 1 : -1;
80 }
81 }
82
83 int *pdim = DIM(obj), n = pdim[1];
84 if (pdim[0] != n)
85 return 0;
86 if (n <= 1)
87 return ((op_ul == '\0') ? class[2] != 'R' : op_ul == 'U') ? 1 : -1;
88
89 if (class[2] != 'T') {
90
91 SEXP iSym = (class[2] == 'C') ? Matrix_iSym : Matrix_jSym,
92 p = PROTECT(GET_SLOT(obj, Matrix_pSym)),
93 i = PROTECT(GET_SLOT(obj, iSym));
94 int *pp = INTEGER(p), *pi = INTEGER(i), j, k, kend;
95 pp++;
96 UNPROTECT(2); /* i, p */
97
98#define CURL(t) \
99 do { \
100 for (j = 0, k = 0; j < n; ++j) { \
101 kend = pp[j]; \
102 if (k < kend && pi[kend - 1] > j) \
103 break; \
104 k = kend; \
105 } \
106 if (j == n) \
107 return t; \
108 } while (0)
109
110#define CLRU(t) \
111 do { \
112 for (j = 0, k = 0; j < n; ++j) { \
113 kend = pp[j]; \
114 if (k < kend && pi[k] < j) \
115 break; \
116 k = kend; \
117 } \
118 if (j == n) \
119 return t; \
120 } while (0)
121
122 if (op_ul == '\0' || op_ul == 'U') {
123 if (class[2] == 'C')
124 CURL(1);
125 else
126 CLRU(1);
127 }
128 if (op_ul == '\0' || op_ul != 'U') {
129 if (class[2] == 'C')
130 CLRU(-1);
131 else
132 CURL(-1);
133 }
134
135#undef CURL
136#undef CLRU
137
138 } else {
139
140 SEXP i = PROTECT(GET_SLOT(obj, Matrix_iSym)),
141 j = PROTECT(GET_SLOT(obj, Matrix_jSym));
142 int *pi = INTEGER(i), *pj = INTEGER(j);
143 R_xlen_t k, kend = XLENGTH(i);
144 UNPROTECT(2); /* i, j */
145
146 if (op_ul == '\0' || op_ul == 'U') {
147 for (k = 0; k < kend; ++k)
148 if (pi[k] > pj[k])
149 break;
150 if (k == kend)
151 return 1;
152 }
153 if (op_ul == '\0' || op_ul != 'U') {
154 for (k = 0; k < kend; ++k)
155 if (pi[k] < pj[k])
156 break;
157 if (k == kend)
158 return -1;
159 }
160
161 }
162
163 return 0;
164}
165
166SEXP R_dense_is_triangular(SEXP s_obj, SEXP s_upper)
167{
168 if (TYPEOF(s_obj) != OBJSXP) {
169 /* defined in ./coerce.c : */
170 SEXP matrix_as_dense(SEXP, const char *, char, char, char, int, int);
171 s_obj = matrix_as_dense(s_obj, ".ge", '\0', '\0', '\0', 1, 0);
172 }
173 PROTECT(s_obj);
174 const char *class = Matrix_class(s_obj, valid_dense, 6, __func__);
175
176 int up;
177 VALID_LOGIC3(s_upper, up);
178
179 int ans_ = dense_is_triangular(s_obj, class,
180 (up == NA_LOGICAL) ? '\0' : ((up != 0) ? 'U' : 'L'));
181 SEXP ans = Rf_allocVector(LGLSXP, 1);
182 LOGICAL(ans)[0] = ans_ != 0;
183 if (up == NA_LOGICAL && ans_ != 0) {
184 SEXP kind;
185 PROTECT(ans);
186 PROTECT(kind = Rf_mkString((ans_ > 0) ? "U" : "L"));
187 Rf_setAttrib(ans, Matrix_kindSym, kind);
188 UNPROTECT(2);
189 }
190 UNPROTECT(1);
191 return ans;
192}
193
194/* NB: requires triangular nonzero pattern */
195SEXP R_sparse_is_triangular(SEXP s_obj, SEXP s_upper)
196{
197 const char *class = Matrix_class(s_obj, valid_sparse, 6, __func__);
198
199 int up;
200 VALID_LOGIC3(s_upper, up);
201
202 int ans_ = sparse_is_triangular(s_obj, class,
203 (up == NA_LOGICAL) ? '\0' : ((up != 0) ? 'U' : 'L'));
204 SEXP ans = Rf_allocVector(LGLSXP, 1);
205 LOGICAL(ans)[0] = ans_ != 0;
206 if (up == NA_LOGICAL && ans_ != 0) {
207 SEXP kind;
208 PROTECT(ans);
209 PROTECT(kind = Rf_mkString((ans_ > 0) ? "U" : "L"));
210 Rf_setAttrib(ans, Matrix_kindSym, kind);
211 UNPROTECT(2);
212 }
213 return ans;
214}
#define SWITCH4(c, template)
Definition M5.h:315
#define VALID_LOGIC3(s, d)
Definition Mdefines.h:223
const char * valid_dense[]
Definition objects.c:3
#define UPLO(x)
Definition Mdefines.h:101
const char * Matrix_class(SEXP, const char **, int, const char *)
Definition objects.c:112
#define DIM(x)
Definition Mdefines.h:85
#define GET_SLOT(x, name)
Definition Mdefines.h:72
const char * valid_sparse[]
Definition Mdefines.h:328
#define TYPEOF(s)
Definition Mdefines.h:123
SEXP matrix_as_dense(SEXP from, const char *zzz, char ul, char ct, char nu, int mg, int new)
Definition coerce.c:262
SEXP Matrix_kindSym
Definition init.c:611
SEXP Matrix_xSym
Definition init.c:635
SEXP Matrix_iSym
Definition init.c:607
SEXP Matrix_jSym
Definition init.c:610
SEXP Matrix_pSym
Definition init.c:622
int dense_is_diagonal(SEXP, const char *)
Definition isDiagonal.c:7
#define TEMPLATE(c)
#define CLRU(t)
SEXP R_sparse_is_triangular(SEXP s_obj, SEXP s_upper)
int dense_is_triangular(SEXP obj, const char *class, char op_ul)
SEXP R_dense_is_triangular(SEXP s_obj, SEXP s_upper)
int sparse_is_diagonal(SEXP, const char *)
Definition isDiagonal.c:45
int sparse_is_triangular(SEXP obj, const char *class, char op_ul)
#define CURL(t)