SCM

SCM Repository

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

Annotation of /pkg/src/dgeMatrix.c

Parent Directory Parent Directory | Revision Log Revision Log


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

1 : bates 478 #include "dgeMatrix.h"
2 : bates 10
3 : bates 478 SEXP dgeMatrix_validate(SEXP obj)
4 : bates 10 {
5 :     SEXP x = GET_SLOT(obj, Matrix_xSym),
6 : bates 332 Dim = GET_SLOT(obj, Matrix_DimSym),
7 : bates 476 fact = GET_SLOT(obj, Matrix_factorSym),
8 : maechler 534 rc = GET_SLOT(obj, Matrix_rcondSym);
9 : bates 10 int m, n;
10 :    
11 :     if (length(Dim) != 2)
12 : bates 582 return mkString(_("Dim slot must have length 2"));
13 : bates 10 m = INTEGER(Dim)[0]; n = INTEGER(Dim)[1];
14 :     if (m < 0 || n < 0)
15 : bates 582 return mkString(_("Negative value(s) in Dim"));
16 : bates 10 if (length(x) != m * n)
17 : maechler 604 return mkString(_("length of x slot != prod(Dim)"));
18 :     if (!isReal(x))
19 :     return mkString(_("x slot must be numeric \"double\""));
20 : bates 332 if (length(fact) > 0 && getAttrib(fact, R_NamesSymbol) == R_NilValue)
21 : bates 582 return mkString(_("factors slot must be named list"));
22 : bates 332 if (length(rc) > 0 && getAttrib(rc, R_NamesSymbol) == R_NilValue)
23 : bates 582 return mkString(_("rcond slot must be named numeric vector"));
24 : bates 10 return ScalarLogical(1);
25 :     }
26 :    
27 :     static
28 :     double get_norm(SEXP obj, char *typstr)
29 : maechler 534 {
30 : bates 10 char typnm[] = {'\0', '\0'};
31 :     int *dims = INTEGER(GET_SLOT(obj, Matrix_DimSym));
32 :     double *work = (double *) NULL;
33 :    
34 :     typnm[0] = norm_type(typstr);
35 :     if (*typnm == 'I') {
36 :     work = (double *) R_alloc(dims[0], sizeof(double));
37 :     }
38 :     return F77_CALL(dlange)(typstr, dims, dims+1,
39 :     REAL(GET_SLOT(obj, Matrix_xSym)),
40 :     dims, work);
41 :     }
42 :    
43 : bates 478 SEXP dgeMatrix_norm(SEXP obj, SEXP type)
44 : bates 10 {
45 :     return ScalarReal(get_norm(obj, CHAR(asChar(type))));
46 :     }
47 :    
48 :     static
49 :     double set_rcond(SEXP obj, char *typstr)
50 :     {
51 :     char typnm[] = {'\0', '\0'};
52 : bates 332 SEXP rcv = GET_SLOT(obj, Matrix_rcondSym);
53 : bates 10 double rcond = get_double_by_name(rcv, typnm);
54 :    
55 :     typnm[0] = rcond_type(typstr);
56 :     if (R_IsNA(rcond)) {
57 : bates 478 SEXP LU = dgeMatrix_LU(obj);
58 : bates 10 int *dims = INTEGER(GET_SLOT(LU, Matrix_DimSym)), info;
59 :     double anorm = get_norm(obj, typstr);
60 :    
61 :     if (dims[0] != dims[1] || dims[0] < 1)
62 : bates 582 error(_("rcond requires a square, non-empty matrix"));
63 : bates 10 F77_CALL(dgecon)(typnm,
64 :     dims, REAL(GET_SLOT(LU, Matrix_xSym)),
65 :     dims, &anorm, &rcond,
66 :     (double *) R_alloc(4*dims[0], sizeof(double)),
67 :     (int *) R_alloc(dims[0], sizeof(int)), &info);
68 : bates 332 SET_SLOT(obj, Matrix_rcondSym,
69 : bates 10 set_double_by_name(rcv, rcond, typnm));
70 :     }
71 :     return rcond;
72 :     }
73 :    
74 : bates 478 SEXP dgeMatrix_rcond(SEXP obj, SEXP type)
75 : bates 10 {
76 :     return ScalarReal(set_rcond(obj, CHAR(asChar(type))));
77 :     }
78 :    
79 : bates 478 SEXP dgeMatrix_crossprod(SEXP x)
80 : bates 10 {
81 : bates 478 SEXP val = PROTECT(NEW_OBJECT(MAKE_CLASS("dpoMatrix")));
82 : bates 10 int *Dims = INTEGER(GET_SLOT(x, Matrix_DimSym)),
83 : bates 342 *vDims;
84 : bates 343 int i, n = Dims[1];
85 :     int nsqr = n * n;
86 :     double one = 1.0, *xvals, zero = 0.0;
87 : bates 10
88 : bates 476 SET_SLOT(val, Matrix_factorSym, allocVector(VECSXP, 0));
89 : bates 332 SET_SLOT(val, Matrix_rcondSym, allocVector(REALSXP, 0));
90 : maechler 534 SET_SLOT(val, Matrix_uploSym, mkString("U"));
91 : bates 342 SET_SLOT(val, Matrix_DimSym, allocVector(INTSXP, 2));
92 :     vDims = INTEGER(GET_SLOT(val, Matrix_DimSym));
93 : bates 332 vDims[0] = vDims[1] = n;
94 : bates 345 SET_SLOT(val, Matrix_xSym, allocVector(REALSXP, nsqr));
95 : bates 343 xvals = REAL(GET_SLOT(val, Matrix_xSym));
96 :     for (i = 0; i < nsqr; i++) xvals[i] = 0.; /* keep valgrind happy */
97 : bates 345 F77_CALL(dsyrk)("U", "T", vDims, Dims,
98 :     &one, REAL(GET_SLOT(x, Matrix_xSym)), Dims,
99 :     &zero, xvals, vDims);
100 : bates 10 UNPROTECT(1);
101 :     return val;
102 :     }
103 :    
104 : bates 478 SEXP dgeMatrix_dgeMatrix_crossprod(SEXP x, SEXP y)
105 : bates 10 {
106 : bates 478 SEXP val = PROTECT(NEW_OBJECT(MAKE_CLASS("dgeMatrix")));
107 : bates 10 int *xDims = INTEGER(GET_SLOT(x, Matrix_DimSym)),
108 :     *yDims = INTEGER(GET_SLOT(y, Matrix_DimSym)),
109 : bates 332 *vDims;
110 : bates 10 int m = xDims[1], n = yDims[1];
111 :     double one = 1.0, zero = 0.0;
112 :    
113 : bates 332 SET_SLOT(val, Matrix_rcondSym, allocVector(REALSXP, 0));
114 : bates 476 SET_SLOT(val, Matrix_factorSym, allocVector(VECSXP, 0));
115 : bates 332 SET_SLOT(val, Matrix_DimSym, allocVector(INTSXP, 2));
116 :     vDims = INTEGER(GET_SLOT(val, Matrix_DimSym));
117 : bates 10 if ((*xDims) > 0 && (*yDims) > 0 && n > 0 && m > 0) {
118 :     if (*xDims != *yDims)
119 : bates 582 error(_("Dimensions of x and y are not compatible for crossprod"));
120 : bates 10 vDims[0] = m; vDims[1] = n;
121 :     SET_SLOT(val, Matrix_xSym, allocVector(REALSXP, m * n));
122 :     F77_CALL(dgemm)("T", "N", xDims + 1, yDims + 1, xDims, &one,
123 :     REAL(GET_SLOT(x, Matrix_xSym)), xDims,
124 :     REAL(GET_SLOT(y, Matrix_xSym)), yDims,
125 :     &zero, REAL(GET_SLOT(val, Matrix_xSym)),
126 :     xDims + 1);
127 :     }
128 :     UNPROTECT(1);
129 :     return val;
130 :     }
131 :    
132 : bates 478 SEXP dgeMatrix_matrix_crossprod(SEXP x, SEXP y)
133 : bates 10 {
134 : bates 478 SEXP val = PROTECT(NEW_OBJECT(MAKE_CLASS("dgeMatrix")));
135 : bates 10 int *xDims = INTEGER(GET_SLOT(x, Matrix_DimSym)),
136 :     *yDims = INTEGER(getAttrib(y, R_DimSymbol)),
137 : bates 332 *vDims;
138 : bates 10 int m = xDims[1], n = yDims[1];
139 :     double one = 1.0, zero = 0.0;
140 :    
141 :     if (!(isMatrix(y) && isReal(y)))
142 : bates 582 error(_("Argument y must be a numeric (real) matrix"));
143 : bates 332 SET_SLOT(val, Matrix_rcondSym, allocVector(REALSXP, 0));
144 : bates 476 SET_SLOT(val, Matrix_factorSym, allocVector(VECSXP, 0));
145 : bates 332 SET_SLOT(val, Matrix_DimSym, allocVector(INTSXP, 2));
146 :     vDims = INTEGER(GET_SLOT(val, Matrix_DimSym));
147 : bates 10 if ((*xDims) > 0 && (*yDims) > 0 && n > 0 && m > 0) {
148 :     if (*xDims != *yDims)
149 : bates 582 error(_("Dimensions of x and y are not compatible for crossprod"));
150 : bates 10 vDims[0] = m; vDims[1] = n;
151 :     SET_SLOT(val, Matrix_xSym, allocVector(REALSXP, m * n));
152 :     F77_CALL(dgemm)("T", "N", xDims + 1, yDims + 1, xDims, &one,
153 :     REAL(GET_SLOT(x, Matrix_xSym)), xDims,
154 :     REAL(y), yDims,
155 :     &zero, REAL(GET_SLOT(val, Matrix_xSym)),
156 :     xDims + 1);
157 :     }
158 :     UNPROTECT(1);
159 :     return val;
160 :     }
161 :    
162 : bates 478 SEXP dgeMatrix_getDiag(SEXP x)
163 : bates 10 {
164 :     int *dims = INTEGER(GET_SLOT(x, Matrix_DimSym));
165 :     int i, m = dims[0], nret = (m < dims[1]) ? m : dims[1];
166 :     SEXP ret = PROTECT(allocVector(REALSXP, nret)),
167 :     xv = GET_SLOT(x, Matrix_xSym);
168 :    
169 :     for (i = 0; i < nret; i++) {
170 :     REAL(ret)[i] = REAL(xv)[i * (m + 1)];
171 :     }
172 :     UNPROTECT(1);
173 :     return ret;
174 :     }
175 :    
176 : bates 478 SEXP dgeMatrix_LU(SEXP x)
177 : bates 10 {
178 : bates 476 SEXP val = get_factors(x, "LU");
179 : bates 10 int *dims, npiv, info;
180 : maechler 534
181 : bates 10 if (val != R_NilValue) return val;
182 :     dims = INTEGER(GET_SLOT(x, Matrix_DimSym));
183 :     if (dims[0] < 1 || dims[1] < 1)
184 : bates 582 error(_("Cannot factor a matrix with zero extents"));
185 : bates 10 npiv = (dims[0] <dims[1]) ? dims[0] : dims[1];
186 :     val = PROTECT(NEW_OBJECT(MAKE_CLASS("LU")));
187 :     SET_SLOT(val, Matrix_xSym, duplicate(GET_SLOT(x, Matrix_xSym)));
188 :     SET_SLOT(val, Matrix_DimSym, duplicate(GET_SLOT(x, Matrix_DimSym)));
189 :     SET_SLOT(val, install("pivot"), allocVector(INTSXP, npiv));
190 :     F77_CALL(dgetrf)(dims, dims + 1, REAL(GET_SLOT(val, Matrix_xSym)),
191 :     dims, INTEGER(GET_SLOT(val, install("pivot"))),
192 :     &info);
193 : bates 582 if (info) error(_("Lapack routine dgetrf returned error code %d"), info);
194 : bates 10 UNPROTECT(1);
195 : bates 476 return set_factors(x, val, "LU");
196 : bates 10 }
197 :    
198 : bates 478 SEXP dgeMatrix_determinant(SEXP x, SEXP logarithm)
199 : bates 10 {
200 :     int lg = asLogical(logarithm);
201 : bates 478 SEXP lu = dgeMatrix_LU(x);
202 : bates 10 int *dims = INTEGER(GET_SLOT(lu, Matrix_DimSym)),
203 :     *jpvt = INTEGER(GET_SLOT(lu, install("pivot"))),
204 :     i, n = dims[0], sign = 1;
205 :     double *luvals = REAL(GET_SLOT(lu, Matrix_xSym)), modulus;
206 :    
207 :     if (n != dims[1])
208 : bates 582 error(_("Determinant requires a square matrix"));
209 : bates 10 for (i = 0; i < n; i++) if (jpvt[i] != (i + 1)) sign = -sign;
210 :     if (lg) {
211 :     modulus = 0.0;
212 :     for (i = 0; i < n; i++) {
213 :     double dii = luvals[i*(n + 1)]; /* ith diagonal element */
214 :     modulus += log(dii < 0 ? -dii : dii);
215 :     if (dii < 0) sign = -sign;
216 :     }
217 :     } else {
218 :     modulus = 1.0;
219 :     for (i = 0; i < n; i++)
220 :     modulus *= luvals[i*(n + 1)];
221 :     if (modulus < 0) {
222 :     modulus = -modulus;
223 :     sign = -sign;
224 :     }
225 :     }
226 :     return as_det_obj(modulus, lg, sign);
227 :     }
228 :    
229 : bates 478 SEXP dgeMatrix_solve(SEXP a)
230 : bates 10 {
231 : bates 478 SEXP val = PROTECT(NEW_OBJECT(MAKE_CLASS("dgeMatrix"))),
232 :     lu = dgeMatrix_LU(a);
233 : bates 10 int *dims = INTEGER(GET_SLOT(lu, Matrix_DimSym)),
234 :     *pivot = INTEGER(GET_SLOT(lu, install("pivot")));
235 :     double *x, tmp;
236 :     int info, lwork = -1;
237 :    
238 :    
239 : bates 582 if (dims[0] != dims[1]) error(_("Solve requires a square matrix"));
240 : bates 332 SET_SLOT(val, Matrix_rcondSym, allocVector(REALSXP, 0));
241 : bates 476 SET_SLOT(val, Matrix_factorSym, allocVector(VECSXP, 0));
242 : bates 10 SET_SLOT(val, Matrix_xSym, duplicate(GET_SLOT(lu, Matrix_xSym)));
243 :     x = REAL(GET_SLOT(val, Matrix_xSym));
244 :     SET_SLOT(val, Matrix_DimSym, duplicate(GET_SLOT(lu, Matrix_DimSym)));
245 :     F77_CALL(dgetri)(dims, x, dims, pivot, &tmp, &lwork, &info);
246 :     lwork = (int) tmp;
247 :     F77_CALL(dgetri)(dims, x, dims, pivot,
248 :     (double *) R_alloc((size_t) lwork, sizeof(double)),
249 :     &lwork, &info);
250 :     UNPROTECT(1);
251 :     return val;
252 :     }
253 :    
254 : bates 478 SEXP dgeMatrix_dgeMatrix_mm(SEXP a, SEXP b)
255 : bates 10 {
256 :     int *adims = INTEGER(GET_SLOT(a, Matrix_DimSym)),
257 :     *bdims = INTEGER(GET_SLOT(b, Matrix_DimSym)),
258 :     *cdims,
259 :     m = adims[0], n = bdims[1], k = adims[1];
260 : bates 478 SEXP val = PROTECT(NEW_OBJECT(MAKE_CLASS("dgeMatrix")));
261 : bates 10 char *trans = "N";
262 :     double one = 1., zero = 0.;
263 : maechler 534
264 : bates 10 if (bdims[0] != k)
265 : bates 582 error(_("Matrices are not conformable for multiplication"));
266 : bates 10 if (m < 1 || n < 1 || k < 1)
267 : bates 582 error(_("Matrices with zero extents cannot be multiplied"));
268 : bates 332 SET_SLOT(val, Matrix_rcondSym, allocVector(REALSXP, 0));
269 : bates 476 SET_SLOT(val, Matrix_factorSym, allocVector(VECSXP, 0));
270 : bates 10 SET_SLOT(val, Matrix_xSym, allocVector(REALSXP, m * n));
271 :     SET_SLOT(val, Matrix_DimSym, allocVector(INTSXP, 2));
272 :     cdims = INTEGER(GET_SLOT(val, Matrix_DimSym));
273 :     cdims[0] = m; cdims[1] = n;
274 :     F77_CALL(dgemm)(trans, trans, adims, bdims+1, bdims, &one,
275 :     REAL(GET_SLOT(a, Matrix_xSym)), adims,
276 :     REAL(GET_SLOT(b, Matrix_xSym)), bdims,
277 :     &zero, REAL(GET_SLOT(val, Matrix_xSym)), adims);
278 :     UNPROTECT(1);
279 :     return val;
280 :     }
281 : bates 301
282 : bates 478 SEXP dgeMatrix_svd(SEXP x, SEXP nnu, SEXP nnv)
283 : bates 301 {
284 : bates 377 int /* nu = asInteger(nnu),
285 :     nv = asInteger(nnv), */
286 : bates 301 *dims = INTEGER(GET_SLOT(x, Matrix_DimSym));
287 :     double *xx = REAL(GET_SLOT(x, Matrix_xSym));
288 :     SEXP val = PROTECT(allocVector(VECSXP, 3));
289 :    
290 :     if (dims[0] && dims[1]) {
291 :     int m = dims[0], n = dims[1], mm = (m < n)?m:n,
292 :     lwork = -1, info;
293 :     int *iwork = Calloc(8 * mm, int);
294 :     double tmp, *work;
295 : bates 306 /* int bdspac = 3*m*m + 4*m, */
296 :     /* wrkbl, maxwrk, minwrk, itmp, */
297 :     /* ione = 1, iminus1 = -1; */
298 :     /* int i1, i2, i3; */
299 : bates 301
300 :     SET_VECTOR_ELT(val, 0, allocVector(REALSXP, mm));
301 :     SET_VECTOR_ELT(val, 1, allocMatrix(REALSXP, m, mm));
302 :     SET_VECTOR_ELT(val, 2, allocMatrix(REALSXP, mm, n));
303 :     F77_CALL(dgesdd)("S", &m, &n, xx, &m,
304 :     REAL(VECTOR_ELT(val, 0)),
305 :     REAL(VECTOR_ELT(val, 1)), &m,
306 :     REAL(VECTOR_ELT(val, 2)), &mm,
307 :     &tmp, &lwork, iwork, &info);
308 :     lwork = (int) tmp;
309 : bates 306 /* F77_CALL(foo)(&i1, &i2, &i3); */
310 :     /* wrkbl = 3*m+(m+n)*i1; */
311 :     /* if (wrkbl < (itmp = 3*m + m*i2)) wrkbl = itmp; */
312 :     /* if (wrkbl < (itmp = 3*m + m*i3)) wrkbl = itmp; */
313 :     /* itmp = bdspac+3*m; */
314 :     /* maxwrk = (wrkbl > itmp) ? wrkbl : itmp; */
315 :     /* minwrk = 3*m + ((bdspac > n) ? bdspac : n); */
316 : bates 301 work = Calloc(lwork, double);
317 :     F77_CALL(dgesdd)("S", &m, &n, xx, &m,
318 :     REAL(VECTOR_ELT(val, 0)),
319 :     REAL(VECTOR_ELT(val, 1)), &m,
320 :     REAL(VECTOR_ELT(val, 2)), &mm,
321 :     work, &lwork, iwork, &info);
322 :     Free(iwork); Free(work);
323 :     }
324 :     UNPROTECT(1);
325 :     return val;
326 :     }
327 : bates 461
328 :     static double padec [] = /* Constants for matrix exponential calculation. */
329 :     {
330 :     5.0000000000000000e-1,
331 :     1.1666666666666667e-1,
332 :     1.6666666666666667e-2,
333 :     1.6025641025641026e-3,
334 :     1.0683760683760684e-4,
335 :     4.8562548562548563e-6,
336 :     1.3875013875013875e-7,
337 :     1.9270852604185938e-9,
338 :     };
339 :    
340 : maechler 534 /**
341 : bates 461 * Matrix exponential - based on the code for Octave's expm function.
342 : maechler 534 *
343 : bates 461 * @param x real square matrix to exponentiate
344 : maechler 534 *
345 : bates 461 * @return matrix exponential of x
346 :     */
347 : bates 478 SEXP dgeMatrix_exp(SEXP x)
348 : bates 461 {
349 :     SEXP val = PROTECT(duplicate(x));
350 :     int *Dims = INTEGER(GET_SLOT(x, Matrix_DimSym));
351 :     int i, ilo, ilos, ihi, ihis, j, nc = Dims[1], sqpow;
352 :     int ncp1 = Dims[1] + 1, ncsqr = nc * nc;
353 :     int *pivot = Calloc(nc, int);
354 :     int *iperm = Calloc(nc, int);
355 :     double *dpp = Calloc(ncsqr, double), /* denominator power Pade' */
356 :     *npp = Calloc(ncsqr, double), /* numerator power Pade' */
357 :     *perm = Calloc(nc, double),
358 :     *scale = Calloc(nc, double),
359 :     *v = REAL(GET_SLOT(val, Matrix_xSym)),
360 :     *work = Calloc(ncsqr, double), inf_norm, m1_j, /* (-1)^j */
361 :     one = 1., trshift, zero = 0.;
362 : maechler 534
363 : bates 461 if (nc < 1 || Dims[0] != nc)
364 : bates 582 error(_("Matrix exponential requires square, non-null matrix"));
365 : bates 461
366 :     /* FIXME: Add special treatment for nc == 1 */
367 : maechler 534
368 : bates 461 /* Preconditioning 1. Shift diagonal by average diagonal if positive. */
369 :     trshift = 0; /* determine average diagonal element */
370 :     for (i = 0; i < nc; i++) trshift += v[i * ncp1];
371 :     trshift /= nc;
372 :     if (trshift > 0.) { /* shift diagonal by -trshift */
373 :     for (i = 0; i < nc; i++) v[i * ncp1] -= trshift;
374 :     }
375 :    
376 :     /* Preconditioning 2. Balancing with dgebal. */
377 :     F77_CALL(dgebal)("P", &nc, v, &nc, &ilo, &ihi, perm, &j);
378 : bates 582 if (j) error(_("dgeMatrix_exp: LAPACK routine dgebal returned %d"), j);
379 : bates 461 F77_CALL(dgebal)("S", &nc, v, &nc, &ilos, &ihis, scale, &j);
380 : bates 582 if (j) error(_("dgeMatrix_exp: LAPACK routine dgebal returned %d"), j);
381 : bates 461
382 :     /* Preconditioning 3. Scaling according to infinity norm */
383 :     inf_norm = F77_CALL(dlange)("I", &nc, &nc, v, &nc, work);
384 :     sqpow = (inf_norm > 0) ? (int) (1 + log(inf_norm)/log(2.)) : 0;
385 :     if (sqpow < 0) sqpow = 0;
386 :     if (sqpow > 0) {
387 :     double scale_factor = 1.0;
388 :     for (i = 0; i < sqpow; i++) scale_factor *= 2.;
389 :     for (i = 0; i < ncsqr; i++) v[i] /= scale_factor;
390 :     }
391 :    
392 :     /* Pade' approximation. Powers v^8, v^7, ..., v^1 */
393 :     AZERO(npp, ncsqr);
394 :     AZERO(dpp, ncsqr);
395 :     m1_j = -1;
396 :     for (j = 7; j >=0; j--) {
397 :     double mult = padec[j];
398 :     /* npp = m * npp + padec[j] *m */
399 :     F77_CALL(dgemm)("N", "N", &nc, &nc, &nc, &one, v, &nc, npp, &nc,
400 :     &zero, work, &nc);
401 :     for (i = 0; i < ncsqr; i++) npp[i] = work[i] + mult * v[i];
402 :     /* dpp = m * dpp * (m1_j * padec[j]) * m */
403 :     mult *= m1_j;
404 :     F77_CALL(dgemm)("N", "N", &nc, &nc, &nc, &one, v, &nc, dpp, &nc,
405 :     &zero, work, &nc);
406 :     for (i = 0; i < ncsqr; i++) dpp[i] = work[i] + mult * v[i];
407 :     m1_j *= -1;
408 :     }
409 :     /* Zero power */
410 :     for (i = 0; i < ncsqr; i++) dpp[i] *= -1.;
411 :     for (j = 0; j < nc; j++) {
412 :     npp[j * ncp1] += 1.;
413 :     dpp[j * ncp1] += 1.;
414 :     }
415 : maechler 534
416 : bates 461 /* Pade' approximation is solve(dpp, npp) */
417 :     F77_CALL(dgetrf)(&nc, &nc, dpp, &nc, pivot, &j);
418 : bates 582 if (j) error(_("dgeMatrix_exp: dgetrf returned error code %d"), j);
419 : bates 461 F77_CALL(dgetrs)("N", &nc, &nc, dpp, &nc, pivot, npp, &nc, &j);
420 : bates 582 if (j) error(_("dgeMatrix_exp: dgetrs returned error code %d"), j);
421 : bates 461 Memcpy(v, npp, ncsqr);
422 :    
423 :     /* Now undo all of the preconditioning */
424 :     /* Preconditioning 3: square the result for every power of 2 */
425 :     while (sqpow--) {
426 :     F77_CALL(dgemm)("N", "N", &nc, &nc, &nc, &one, v, &nc, v, &nc,
427 :     &zero, work, &nc);
428 :     Memcpy(v, work, ncsqr);
429 :     }
430 :     /* Preconditioning 2: apply inverse scaling */
431 :     for (j = 0; j < nc; j++)
432 :     for (i = 0; i < nc; i++)
433 :     v[i + j * nc] *= scale[i]/scale[j];
434 :     /* Construct balancing permutation vector */
435 :     for (i = 0; i < nc; i++) iperm[i] = i; /* identity permutation */
436 :     /* Leading permutations applied in forward order */
437 :     for (i = 0; i < (ilo - 1); i++) {
438 :     int swapidx = (int) (perm[i]) - 1;
439 :     int tmp = iperm[i];
440 :     iperm[i] = iperm[swapidx];
441 :     iperm[swapidx] = tmp;
442 :     }
443 :     /* Trailing permutations applied in reverse order */
444 :     for (i = nc - 1; i >= ihi; i--) {
445 :     int swapidx = (int) (perm[i]) - 1;
446 :     int tmp = iperm[i];
447 :     iperm[i] = iperm[swapidx];
448 :     iperm[swapidx] = tmp;
449 :     }
450 :     /* Construct inverse balancing permutation vector */
451 :     Memcpy(pivot, iperm, nc);
452 :     for (i = 0; i < nc; i++) iperm[pivot[i]] = i;
453 :     /* Apply inverse permutation */
454 :     Memcpy(work, v, ncsqr);
455 :     for (j = 0; j < nc; j++)
456 :     for (i = 0; i < nc; i++)
457 :     v[i + j * nc] = work[iperm[i] + iperm[j] * nc];
458 : maechler 534
459 : bates 461 /* Preconditioning 1: Trace normalization */
460 :     if (trshift > 0.) {
461 :     double mult = exp(trshift);
462 :     for (i = 0; i < ncsqr; i++) v[i] *= mult;
463 :     }
464 : maechler 534
465 : bates 461 /* Clean up */
466 :     Free(dpp); Free(npp); Free(perm); Free(iperm); Free(pivot); Free(scale); Free(work);
467 :     UNPROTECT(1);
468 :     return val;
469 :     }
470 : bates 495
471 :     SEXP dgeMatrix_Schur(SEXP x, SEXP vectors)
472 :     {
473 :     int *dims = INTEGER(GET_SLOT(x, Matrix_DimSym));
474 :     int vecs = asLogical(vectors), info, izero = 0, lwork = -1, n = dims[0];
475 :     double *work, tmp;
476 :     char *nms[] = {"WR", "WI", "T", "Z", ""};
477 :     SEXP val = PROTECT(Matrix_make_named(VECSXP, nms));
478 : maechler 534
479 : bates 495 if (n != dims[1] || n < 1)
480 : bates 582 error(_("dgeMatrix_Schur: argument x must be a non-null square matrix"));
481 : bates 495 SET_VECTOR_ELT(val, 0, allocVector(REALSXP, n));
482 :     SET_VECTOR_ELT(val, 1, allocVector(REALSXP, n));
483 :     SET_VECTOR_ELT(val, 2, allocMatrix(REALSXP, n, n));
484 :     Memcpy(REAL(VECTOR_ELT(val, 2)), REAL(GET_SLOT(x, Matrix_xSym)), n * n);
485 :     SET_VECTOR_ELT(val, 3, allocMatrix(REALSXP, vecs ? n : 0, vecs ? n : 0));
486 :     F77_CALL(dgees)(vecs ? "V" : "N", "N", NULL, dims, (double *) NULL, dims, &izero,
487 :     (double *) NULL, (double *) NULL, (double *) NULL, dims,
488 :     &tmp, &lwork, (int *) NULL, &info);
489 : bates 582 if (info) error(_("dgeMatrix_Schur: first call to dgees failed"));
490 : bates 495 lwork = (int) tmp;
491 :     work = Calloc(lwork, double);
492 :     F77_CALL(dgees)(vecs ? "V" : "N", "N", NULL, dims, REAL(VECTOR_ELT(val, 2)), dims,
493 :     &izero, REAL(VECTOR_ELT(val, 0)), REAL(VECTOR_ELT(val, 1)),
494 : maechler 534 REAL(VECTOR_ELT(val, 3)), dims, work, &lwork,
495 : bates 495 (int *) NULL, &info);
496 : bates 582 if (info) error(_("dgeMatrix_Schur: dgees returned code %d"), info);
497 : bates 495 Free(work);
498 :     UNPROTECT(1);
499 :     return val;
500 :     }

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