home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
fish
/
applications
/
xlispstat
/
src
/
src2.lzh
/
XLisp-Stat
/
ludecomp.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-10-04
|
5KB
|
180 lines
/* ludecomp - LU decomposition and backsolving routines. */
/* Taken from Numerical Recipes. */
/* 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
int crludcmp(mat, n, indx, mode, d)
Matrix mat;
IVector indx;
int n, mode;
double *d;
{
int i, imax, j, k, singular = FALSE;
double big, temp;
Complex cdum, csum;
double rdum, rsum;
CMatrix cmat = (CMatrix) mat;
RMatrix rmat = (RMatrix) mat;
RVector vv;
vv = rvector(n);
*d = 1.0;
/* set up the pivot permutation vector */
for (i = 0; i < n; i++) indx[i] = i;
/* get scaling information for implicit pivoting */
for (i = 0; i < n; i++) {
big = 0.0;
for (j = 0; j < n; j++) {
temp = (mode == RE) ? fabs(rmat[i][j]) : modulus(cmat[i][j]);
if (temp > big) big = temp;
}
if (big == 0.0) {
vv[i] = 1.0; /* no scaling for zero rows */
singular = TRUE;
}
else vv[i] = 1.0 / big;
}
/* loop over columns for Crout's method */
for (j = 0; j < n; j++) {
for (i = 0; i < j; i++) {
if (mode == RE) rsum = rmat[i][j];
else csum = cmat[i][j];
for (k = 0; k < i; k++)
if (mode == RE) rsum -= rmat[i][k] * rmat[k][j];
else csum = csub(csum, cmul(cmat[i][k], cmat[k][j]));
if (mode == RE) rmat[i][j] = rsum;
else cmat[i][j] = csum;
}
big = 0.0;
for (i = j; i < n; i++) {
if (mode == RE) rsum = rmat[i][j];
else csum = cmat[i][j];
for (k = 0; k < j; k++)
if (mode == RE) rsum -= rmat[i][k] * rmat[k][j];
else csum = csub(csum, cmul(cmat[i][k], cmat[k][j]));
if (mode == RE) rmat[i][j] = rsum;
else cmat[i][j] = csum;
temp = vv[i] * ((mode == RE) ? fabs(rsum) : modulus(csum));
if (temp >= big) { big = temp; imax = i; }
}
/* interchange rows if needed */
if (j != imax) {
for (k = 0; k < n; k++) {
if (mode == RE) {
rdum = rmat[imax][k];
rmat[imax][k] = rmat[j][k];
rmat[j][k] = rdum;
}
else {
cdum = cmat[imax][k];
cmat[imax][k] = cmat[j][k];
cmat[j][k] = cdum;
}
}
*d = -(*d);
vv[imax] = vv[j];
}
indx[j] = imax;
/* divide by the pivot element */
temp = (mode == RE) ? fabs(rmat[j][j]) : modulus(cmat[j][j]);
if (temp == 0.0) singular = TRUE;
else if (j < n - 1) {
if (mode == RE) {
rdum = 1.0 / rmat[j][j];
for (i = j + 1; i < n; i++) rmat[i][j] *= rdum;
}
else {
cdum = cdiv(cart2complex(1.0, 0.0), cmat[j][j]);
for (i = j + 1; i < n; i++) cmat[i][j] = cmul(cmat[i][j], cdum);
}
}
}
free_vector((Vector)vv);/* cast added JKL */
return(singular);
}
int crlubksb(a, n, indx, b, mode)
Matrix a;
IVector indx;
Vector b;
int n, mode;
{
int i, ii, ip, j, singular = FALSE;
CMatrix ca = (CMatrix) a;
CVector cb = (CVector) b;
RMatrix ra = (RMatrix) a;
RVector rb = (RVector) b;
double rsum;
Complex csum;
/* forward substitute using L part */
for (i = 0, ii = -1; i < n; i++) {
ip = indx[i];
if (mode == RE) {
rsum = rb[ip];
rb[ip] = rb[i];
}
else {
csum = cb[ip];
cb[ip] = cb[i];
}
if (ii >= 0)
for (j = ii; j <= i - 1; j++)
if (mode == RE) rsum -= ra[i][j] * rb[j];
else csum = csub(csum, cmul(ca[i][j], cb[j]));
else {
if (mode == RE) {
if (rsum != 0.0) ii = i;
}
else if (csum.real != 0.0 || csum.imag != 0.0) ii = i;
}
if (mode == RE) rb[i] = rsum;
else cb[i] = csum;
}
/* back substitute using the U part */
for (i = n - 1; i >= 0; i--) {
if (mode == RE) {
rsum = rb[i];
for (j = i + 1; j < n; j++) rsum -= ra[i][j] * rb[j];
if (ra[i][i] == 0.0) {
singular = TRUE;
break;
}
else rb[i] = rsum / ra[i][i];
}
else {
csum = cb[i];
for (j = i + 1; j < n; j++) csum = csub(csum, cmul(ca[i][j], cb[j]));
if (modulus(ca[i][i]) == 0.0) {
singular = TRUE;
break;
}
else cb[i] = cdiv(csum, ca[i][i]);
}
}
return(singular);
}