home *** CD-ROM | disk | FTP | other *** search
- /* rcondest - Estimates reciprocal of condition number. */
- /* XLISP-STAT 2.1 Copyright (c) 1990, by Luke Tierney */
- /* Additions to Xlisp 2.1, Copyright (c) 1989 by David Michael Betz */
- /* You may give out copies of this software; for conditions see the */
- /* file COPYING included with this distribution. */
-
- #include "xlisp.h"
- #include "osdef.h"
- #ifdef ANSI
- #include "xlsproto.h"
- #else
- #include "xlsfun.h"
- #endif ANSI
-
- double rcondest(a, n)
- RMatrix a;
- int n;
- {
- RVector p, pm, x;
- double est, xp, xm, temp, tempm, xnorm;
- int i, j;
-
- for (i = 0; i < n; i++)
- if (a[i][i] == 0.0) return(0.0);
-
- p = rvector(n);
- pm = rvector(n);
- x = rvector(n);
-
- /* Set est to reciprocal of L1 matrix norm of A */
- est = fabs(a[0][0]);
- for (j = 1; j < n; j++) {
- for (i = 0, temp = fabs(a[j][j]); i < j; i++)
- temp += fabs(a[i][j]);
- est = Max(est, temp);
- }
- est = 1.0 / est;
-
- /* Solve A^Tx = e, selecting e as you proceed */
- x[0] = 1.0 / a[0][0];
- for (i = 1; i < n; i++) p[i] = a[0][i] * x[0];
- for (j = 1; j < n; j++) {
- /* select ej and calculate x[j] */
- xp = ( 1.0 - p[j]) / a[j][j];
- xm = (-1.0 - p[j]) / a[j][j];
- temp = fabs(xp);
- tempm = fabs(xm);
- for (i = j + 1; i < n; i++) {
- pm[i] = p[i] + a[j][i] * xm;
- tempm += fabs(pm[i] / a[i][i]);
- p[i] += a[j][i] * xp;
- temp += fabs(p[i] / a[i][i]);
- }
- if (temp >= tempm) x[j] = xp;
- else {
- x[j] = xm;
- for (i = j + 1; i < n; i++) p[i] = pm[i];
- }
- }
-
- for (j = 0, xnorm = 0.0; j < n; j++) xnorm += fabs(x[j]);
- est = est * xnorm;
- backsolve((Matrix)a,(Vector)x, n, RE); /* casts added JKL */
- for (j = 0, xnorm = 0.0; j < n; j++) xnorm += fabs(x[j]);
- if (xnorm > 0) est = est / xnorm;
-
- free_vector((Vector)p); /* casts added JKL */
- free_vector((Vector)pm);
- free_vector((Vector)x);
-
- return(est);
- }
-
- void backsolve(a, b, n, mode)
- Matrix a;
- Vector b;
- int n;
- {
- int i, j;
- RMatrix ra = (RMatrix) a;
- RVector rb = (RVector) b;
- CMatrix ca = (CMatrix) a;
- CVector cb = (CVector) b;
-
- switch (mode) {
- case RE:
- for (i = n - 1; i >= 0; i--) {
- if (ra[i][i] != 0.0) rb[i] = rb[i] / ra[i][i];
- for (j = i + 1; j < n; j++) rb[i] -= ra[i][j] * rb[j];
- }
- break;
- case CX:
- for (i = n - 1; i >= 0; i--) {
- if (modulus(ca[i][i]) != 0.0) cb[i] = cdiv(cb[i], ca[i][i]);
- for (j = i + 1; j < n; j++)
- cb[i] = csub(cb[i], cmul(ca[i][j], cb[j]));
- }
- break;
- }
- }
-