SCM

SCM Repository

[matrix] Annotation of /pkg/src/dsyMatrix.c
ViewVC logotype

Annotation of /pkg/src/dsyMatrix.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 643 - (view) (download) (as text)

1 : bates 478 #include "dsyMatrix.h"
2 : bates 10
3 : bates 478 SEXP dsyMatrix_validate(SEXP obj)
4 : bates 10 {
5 : bates 592 SEXP val;
6 : bates 10 int *Dim = INTEGER(GET_SLOT(obj, Matrix_DimSym));
7 : maechler 534
8 : bates 592 if (isString(val = check_scalar_string(GET_SLOT(obj, Matrix_uploSym),
9 :     "LU", "uplo"))) return val;
10 : bates 10 if (Dim[0] != Dim[1])
11 : bates 582 return mkString(_("Symmetric matrix must be square"));
12 : bates 10 return ScalarLogical(1);
13 :     }
14 :    
15 : bates 296 double get_norm_sy(SEXP obj, char *typstr)
16 : maechler 534 {
17 : bates 296 char typnm[] = {'\0', '\0'};
18 :     int *dims = INTEGER(GET_SLOT(obj, Matrix_DimSym));
19 :     double *work = (double *) NULL;
20 :    
21 :     typnm[0] = norm_type(typstr);
22 :     if (*typnm == 'I' || *typnm == 'O') {
23 :     work = (double *) R_alloc(dims[0], sizeof(double));
24 :     }
25 :     return F77_CALL(dlansy)(typnm,
26 :     CHAR(asChar(GET_SLOT(obj, Matrix_uploSym))),
27 :     dims, REAL(GET_SLOT(obj, Matrix_xSym)),
28 :     dims, work);
29 :     }
30 :    
31 : bates 478 SEXP dsyMatrix_norm(SEXP obj, SEXP type)
32 : bates 296 {
33 :     return ScalarReal(get_norm_sy(obj, CHAR(asChar(type))));
34 :     }
35 :    
36 :     static
37 :     double set_rcond_sy(SEXP obj, char *typstr)
38 :     {
39 :     char typnm[] = {'\0', '\0'};
40 : bates 338 SEXP rcv = GET_SLOT(obj, Matrix_rcondSym);
41 : bates 296 double rcond;
42 :    
43 :     typnm[0] = rcond_type(typstr);
44 :     rcond = get_double_by_name(rcv, typnm);
45 :    
46 :     if (R_IsNA(rcond)) {
47 : bates 643 SEXP trf = dsyMatrix_trf(obj);
48 : bates 296 int *dims = INTEGER(GET_SLOT(obj, Matrix_DimSym)), info;
49 :     double anorm = get_norm_sy(obj, "O");
50 :    
51 : bates 643 F77_CALL(dsycon)(CHAR(asChar(GET_SLOT(trf, Matrix_uploSym))),
52 :     dims, REAL(GET_SLOT(trf, Matrix_xSym)),
53 :     dims, INTEGER(GET_SLOT(trf, Matrix_permSym)),
54 : maechler 534 &anorm, &rcond,
55 : bates 296 (double *) R_alloc(2*dims[0], sizeof(double)),
56 :     (int *) R_alloc(dims[0], sizeof(int)), &info);
57 : bates 338 SET_SLOT(obj, Matrix_rcondSym,
58 : bates 296 set_double_by_name(rcv, rcond, typnm));
59 :     }
60 :     return rcond;
61 :     }
62 :    
63 : bates 478 SEXP dsyMatrix_rcond(SEXP obj, SEXP type)
64 : bates 296 {
65 : bates 643 return ScalarReal(set_rcond_sy(obj, CHAR(asChar(type))));
66 : bates 296 }
67 :    
68 : maechler 534 static
69 : bates 10 void make_symmetric(double *to, SEXP from, int n)
70 :     {
71 :     int i, j;
72 : maechler 534 if (*CHAR(asChar(GET_SLOT(from, Matrix_uploSym))) == 'U') {
73 : bates 10 for (j = 0; j < n; j++) {
74 :     for (i = j+1; i < n; i++) {
75 :     to[i + j*n] = to[j + i*n];
76 :     }
77 :     }
78 :     } else {
79 :     for (j = 1; j < n; j++) {
80 :     for (i = 0; i < j && i < n; i++) {
81 :     to[i + j*n] = to[j + i*n];
82 :     }
83 :     }
84 :     }
85 :     }
86 : maechler 534
87 : bates 478 SEXP dsyMatrix_solve(SEXP a)
88 : bates 296 {
89 : bates 643 SEXP trf = dsyMatrix_trf(a);
90 :     SEXP val = PROTECT(NEW_OBJECT(MAKE_CLASS("dsyMatrix")));
91 :     int *dims = INTEGER(GET_SLOT(trf, Matrix_DimSym)), info;
92 :    
93 :     SET_SLOT(val, Matrix_uploSym, duplicate(GET_SLOT(trf, Matrix_uploSym)));
94 :     SET_SLOT(val, Matrix_xSym, duplicate(GET_SLOT(trf, Matrix_xSym)));
95 :     SET_SLOT(val, Matrix_DimSym, duplicate(GET_SLOT(trf, Matrix_DimSym)));
96 :     SET_SLOT(val, Matrix_rcondSym, duplicate(GET_SLOT(a, Matrix_rcondSym)));
97 :     F77_CALL(dsytri)(CHAR(asChar(GET_SLOT(val, Matrix_uploSym))),
98 :     dims, REAL(GET_SLOT(val, Matrix_xSym)), dims,
99 :     INTEGER(GET_SLOT(trf, Matrix_permSym)),
100 :     (double *) R_alloc((long) dims[0], sizeof(double)),
101 :     &info);
102 :     UNPROTECT(1);
103 :     return val;
104 : bates 296 }
105 :    
106 : bates 643 SEXP dsyMatrix_dgeMatrix_solve(SEXP a, SEXP b)
107 :     {
108 :     SEXP trf = dsyMatrix_trf(a),
109 :     val = PROTECT(NEW_OBJECT(MAKE_CLASS("dgeMatrix")));
110 :     int *adims = INTEGER(GET_SLOT(a, Matrix_DimSym)),
111 :     *bdims = INTEGER(GET_SLOT(b, Matrix_DimSym)),
112 :     info;
113 :    
114 :     if (*adims != *bdims || bdims[1] < 1 || *adims < 1)
115 :     error(_("Dimensions of system to be solved are inconsistent"));
116 :     SET_SLOT(val, Matrix_DimSym, duplicate(GET_SLOT(b, Matrix_DimSym)));
117 :     SET_SLOT(val, Matrix_xSym, duplicate(GET_SLOT(b, Matrix_xSym)));
118 :     F77_CALL(dsytrs)(CHAR(asChar(GET_SLOT(trf, Matrix_uploSym))),
119 :     adims, bdims + 1,
120 :     REAL(GET_SLOT(trf, Matrix_xSym)), adims,
121 :     INTEGER(GET_SLOT(trf, Matrix_permSym)),
122 :     REAL(GET_SLOT(val, Matrix_xSym)),
123 :     bdims, &info);
124 :     UNPROTECT(1);
125 :     return val;
126 :     }
127 :    
128 : bates 478 SEXP dsyMatrix_matrix_solve(SEXP a, SEXP b)
129 : bates 296 {
130 : bates 643 SEXP trf = dsyMatrix_trf(a),
131 :     val = PROTECT(duplicate(b));
132 :     int *adims = INTEGER(GET_SLOT(a, Matrix_DimSym)),
133 :     *bdims = INTEGER(getAttrib(b, R_DimSymbol)),
134 :     info;
135 :    
136 :     if (!(isReal(b) && isMatrix(b)))
137 :     error(_("Argument b must be a numeric matrix"));
138 :     if (*adims != *bdims || bdims[1] < 1 || *adims < 1)
139 :     error(_("Dimensions of system to be solved are inconsistent"));
140 :     F77_CALL(dsytrs)(CHAR(asChar(GET_SLOT(trf, Matrix_uploSym))),
141 :     adims, bdims + 1,
142 :     REAL(GET_SLOT(trf, Matrix_xSym)), adims,
143 :     INTEGER(GET_SLOT(trf, Matrix_permSym)),
144 :     REAL(val), bdims, &info);
145 :     UNPROTECT(1);
146 :     return val;
147 : bates 296 }
148 :    
149 : bates 478 SEXP dsyMatrix_as_dgeMatrix(SEXP from)
150 : bates 10 {
151 : bates 478 SEXP val = PROTECT(NEW_OBJECT(MAKE_CLASS("dgeMatrix"))),
152 : bates 338 rcondSym = Matrix_rcondSym;
153 : maechler 534
154 : bates 338 SET_SLOT(val, Matrix_rcondSym, allocVector(REALSXP, 0));
155 : bates 476 SET_SLOT(val, Matrix_factorSym, allocVector(VECSXP, 0));
156 : bates 10 SET_SLOT(val, rcondSym, duplicate(GET_SLOT(from, rcondSym)));
157 :     SET_SLOT(val, Matrix_xSym, duplicate(GET_SLOT(from, Matrix_xSym)));
158 :     SET_SLOT(val, Matrix_DimSym,
159 :     duplicate(GET_SLOT(from, Matrix_DimSym)));
160 :     make_symmetric(REAL(GET_SLOT(val, Matrix_xSym)), from,
161 :     INTEGER(GET_SLOT(val, Matrix_DimSym))[0]);
162 :     UNPROTECT(1);
163 :     return val;
164 :     }
165 :    
166 : bates 478 SEXP dsyMatrix_as_matrix(SEXP from)
167 : bates 10 {
168 :     int n = INTEGER(GET_SLOT(from, Matrix_DimSym))[0];
169 :     SEXP val = PROTECT(allocMatrix(REALSXP, n, n));
170 : maechler 534
171 : bates 10 make_symmetric(Memcpy(REAL(val),
172 :     REAL(GET_SLOT(from, Matrix_xSym)), n * n),
173 :     from, n);
174 : maechler 628 setAttrib(val, R_DimNamesSymbol, GET_SLOT(from, Matrix_DimNamesSym));
175 : bates 10 UNPROTECT(1);
176 :     return val;
177 :     }
178 :    
179 : bates 478 SEXP dsyMatrix_dgeMatrix_mm(SEXP a, SEXP b)
180 : bates 10 {
181 :     int *adims = INTEGER(GET_SLOT(a, Matrix_DimSym)),
182 :     *bdims = INTEGER(GET_SLOT(b, Matrix_DimSym)),
183 :     *cdims,
184 :     m = adims[0], n = bdims[1], k = adims[1];
185 : bates 478 SEXP val = PROTECT(NEW_OBJECT(MAKE_CLASS("dgeMatrix")));
186 : bates 10 double one = 1., zero = 0.;
187 : maechler 534
188 : bates 10 if (bdims[0] != k)
189 : bates 582 error(_("Matrices are not conformable for multiplication"));
190 : bates 10 if (m < 1 || n < 1 || k < 1)
191 : bates 582 error(_("Matrices with zero extents cannot be multiplied"));
192 : bates 476 SET_SLOT(val, Matrix_factorSym, allocVector(VECSXP, 0));
193 : bates 338 SET_SLOT(val, Matrix_rcondSym, allocVector(REALSXP, 0));
194 : bates 10 SET_SLOT(val, Matrix_xSym, allocVector(REALSXP, m * n));
195 :     SET_SLOT(val, Matrix_DimSym, allocVector(INTSXP, 2));
196 :     cdims = INTEGER(GET_SLOT(val, Matrix_DimSym));
197 :     cdims[0] = m; cdims[1] = n;
198 :     F77_CALL(dsymm)("L", CHAR(asChar(GET_SLOT(a, Matrix_uploSym))),
199 :     adims, bdims+1, &one,
200 :     REAL(GET_SLOT(a, Matrix_xSym)), adims,
201 :     REAL(GET_SLOT(b, Matrix_xSym)), bdims,
202 :     &zero, REAL(GET_SLOT(val, Matrix_xSym)), adims);
203 :     UNPROTECT(1);
204 :     return val;
205 :     }
206 :    
207 : bates 478 SEXP dsyMatrix_dgeMatrix_mm_R(SEXP a, SEXP b)
208 : bates 10 {
209 :     int *adims = INTEGER(GET_SLOT(a, Matrix_DimSym)),
210 :     *bdims = INTEGER(GET_SLOT(b, Matrix_DimSym)),
211 :     *cdims,
212 :     m = adims[0], n = bdims[1], k = adims[1];
213 : bates 478 SEXP val = PROTECT(NEW_OBJECT(MAKE_CLASS("dgeMatrix")));
214 : bates 10 double one = 1., zero = 0.;
215 : maechler 534
216 : bates 10 if (bdims[0] != k)
217 : bates 582 error(_("Matrices are not conformable for multiplication"));
218 : bates 10 if (m < 1 || n < 1 || k < 1)
219 : bates 582 error(_("Matrices with zero extents cannot be multiplied"));
220 : bates 338 SET_SLOT(val, Matrix_rcondSym, allocVector(REALSXP, 0));
221 : bates 476 SET_SLOT(val, Matrix_factorSym, allocVector(VECSXP, 0));
222 : bates 10 SET_SLOT(val, Matrix_xSym, allocVector(REALSXP, m * n));
223 :     SET_SLOT(val, Matrix_DimSym, allocVector(INTSXP, 2));
224 :     cdims = INTEGER(GET_SLOT(val, Matrix_DimSym));
225 :     cdims[0] = m; cdims[1] = n;
226 :     F77_CALL(dsymm)("R", CHAR(asChar(GET_SLOT(a, Matrix_uploSym))),
227 :     adims, bdims+1, &one,
228 :     REAL(GET_SLOT(a, Matrix_xSym)), adims,
229 :     REAL(GET_SLOT(b, Matrix_xSym)), bdims,
230 :     &zero, REAL(GET_SLOT(val, Matrix_xSym)), adims);
231 :     UNPROTECT(1);
232 :     return val;
233 :     }
234 : maechler 534
235 : bates 631 SEXP dsyMatrix_trf(SEXP x)
236 :     {
237 :     SEXP val = get_factors(x, "BunchKaufman"),
238 :     dimP = GET_SLOT(x, Matrix_DimSym),
239 :     uploP = GET_SLOT(x, Matrix_uploSym);
240 :     int *dims = INTEGER(dimP), *perm, info;
241 :     int lwork = -1, n = dims[0];
242 :     char *uplo = CHAR(STRING_ELT(uploP, 0));
243 :     double tmp, *vx, *work;
244 :    
245 :     if (val != R_NilValue) return val;
246 :     dims = INTEGER(dimP);
247 :     val = PROTECT(NEW_OBJECT(MAKE_CLASS("BunchKaufman")));
248 :     SET_SLOT(val, Matrix_uploSym, duplicate(uploP));
249 :     SET_SLOT(val, Matrix_diagSym, mkString("N"));
250 :     SET_SLOT(val, Matrix_DimSym, duplicate(dimP));
251 :     vx = REAL(ALLOC_SLOT(val, Matrix_xSym, REALSXP, n * n));
252 :     AZERO(vx, n * n);
253 :     F77_CALL(dlacpy)(uplo, &n, &n, REAL(GET_SLOT(x, Matrix_xSym)), &n, vx, &n);
254 :     perm = INTEGER(ALLOC_SLOT(val, Matrix_permSym, INTSXP, n));
255 :     F77_CALL(dsytrf)(uplo, &n, vx, &n, perm, &tmp, &lwork, &info);
256 :     lwork = (int) tmp;
257 :     work = Calloc(lwork, double);
258 :     F77_CALL(dsytrf)(uplo, &n, vx, &n, perm, work, &lwork, &info);
259 :     if (info) error(_("Lapack routine dsytrf returned error code %d"), info);
260 :     UNPROTECT(1);
261 :     Free(work);
262 :     return set_factors(x, val, "BunchKaufman");
263 :     }
264 :    
265 : bates 643 SEXP dsyMatrix_as_dspMatrix(SEXP from)
266 :     {
267 :     SEXP val = PROTECT(NEW_OBJECT(MAKE_CLASS("dspMatrix"))),
268 :     uplo = GET_SLOT(from, Matrix_uploSym),
269 :     dimP = GET_SLOT(from, Matrix_DimSym);
270 :     int n = *INTEGER(dimP);
271 :    
272 :     SET_SLOT(val, Matrix_rcondSym,
273 :     duplicate(GET_SLOT(from, Matrix_rcondSym)));
274 :     SET_SLOT(val, Matrix_DimSym, duplicate(dimP));
275 :     SET_SLOT(val, Matrix_uploSym, duplicate(uplo));
276 :     full_to_packed(REAL(ALLOC_SLOT(val, Matrix_xSym, REALSXP, (n*(n+1))/2)),
277 :     REAL(GET_SLOT(from, Matrix_xSym)), n,
278 :     *CHAR(STRING_ELT(uplo, 0)) == 'U' ? UPP : LOW, NUN);
279 :     UNPROTECT(1);
280 :     return val;
281 :     }

root@r-forge.r-project.org
ViewVC Help
Powered by ViewVC 1.0.0  
Thanks to:
Vienna University of Economics and Business Powered By FusionForge