home *** CD-ROM | disk | FTP | other *** search
- crout(mc,nr,ncc,a,zmch,dt,ierr,lp)
-
- /* crout (a) operates on a coefficient matrix to solve a system of */
- /* simultaneous equations or to compute an inverse and (2) */
- /* and (b) computes a determinant. */
-
- /* crout reduces the original matrix and right-hand sides until */
- /* upon completion the reduced matrix replaces the original */
- /* matrix and the solutions replace the right-hand sides. */
-
- int *ierr,mc,nr,ncc,lp[];
- float a[],*dt,zmch;
-
- {
-
- int i,j,k,kf,ks,kx,kkx,ky,m,mtx,mca,mcs,mdn,mtr,mtra,mtt,nrs,ntc,nx,
- ii,iisb,iiad,icf,ics,iec,iia,itemp,iy,jf,lpis,ircnt,irev,ixs,
- kcs,nrtad,krs,ix;
-
- float temp,fj,fmc,x;
- extern double fabs();
-
-
- if(nr > mc) goto er2;
- fmc = mc;
- mtx = mc * nr - 1;
- mca = mc + 1;
- mcs = mc - 1;
- mdn = mc - nr;
- mtr = (nr-1) * mc + nr-1;
- mtra = nr;
- *dt = 1.;
- *ierr = 0;
- nrs = nr - 1;
-
- for(i = 0; i <= nrs; i++)
- lp[i] = i + 1;
-
- if(ncc < 0) goto er2;
- if(ncc == 0)
- {
- ntc = nr + nr - 1;
- mtt = mc * (nr -1) + ntc;
- j = mtra;
- for(k = nr; k <= ntc; k++)
- {
- for(kx = 0; kx <= nr-1; kx++)
- {
- kkx = k + kx * mc;
- a[kkx] = 0.;
- }
- a[j] = 1.;
- j = j + mca;
- }
- }
- else
- {
- ntc = nr + ncc;
- mtt = mc * (nr -1) + ntc;
- }
- if(ntc <= nr) goto er2;
-
- for(i = 0; i <= nrs; i++)
- {
- ii = mc * i + i;
- iisb = ii - mc;
- iiad = ii + 1;
- icf = i + ((nr-1) * mc);
- ics = i;
- iia = ii + mc;
- iec = i * mc + ntc ;
- temp = 0.;
-
- for(j = ii; j <= iec; j++)
- {
- if(i != 0)
- {
- kf = j - mc;
- ks = j - (i* mc) ;
- kx = i * mc;
- for(k = ks; k <= kf; k += mc)
- {
- a[j] = a[j] - a[kx] * a[k];
- kx = kx + 1;
- }
- }
- if(j <= (iec-ncc))
- {
- if(fabs(a[j]) > temp)
- {
- temp = fabs(a[j]);
- fj = j;
- x = fj / fmc + .5;
- nx = x;
- nx = j - nx * mc;
- }
- }
- }
- if(i != nr)
- {
- if(nx != i)
- {
- itemp = lp[nx];
- lp[nx] = lp[i];
- lp[i] = itemp;
- lpis = nx;
-
- for(k = ics; k <= icf; k+=mc)
- {
- kx = lpis + k * mc;
- temp = a[k];
- a[k] = a[lpis];
- a[lpis] = temp;
- lpis = lpis + mc;
- *dt = - *dt;
- }
- }
- *dt = *dt * a[ii];
- if(zmch - fabs(a[ii]) > 0) goto er1;
-
- for(j = iiad; j <= iec; j++)
- {
- a[j] = a[j] / a[ii];
- }
-
- if(i == 0) goto ibl;
- {
- if(i == (nr - 1)) goto ibr;
-
- for(m = iia; m <= icf; m += mc)
- {
- if(m < mc) kx = 0;
- else kx = m / mc;
- kx = kx * mc;
- for(ky = ics; ky <= iisb; ky += mc)
- {
- a[m] = a[m] - a[kx] * a[ky];
- kx = kx + 1;
- }
- }
- }
- }
- ibl: ;
- }
- ibr: nrtad = mtr + 1;
- for(i = 1; i <= nrs; i++)
- {
- irev = nrtad - (i * mc);
- iec = irev / mc;
- iec = iec * mc + ntc ;
- krs = irev - i;
- for(ircnt = irev; ircnt <= iec; ircnt ++)
- {
- kcs = ircnt + mc;
- if(kcs > mtx) kcs = kcs/mc +1;
- for(k = krs; k <= (iec-mdn); k++)
- {
- a[ircnt] = a[ircnt] - a[kcs] * a[k];
- kcs = kcs + mc;
- if(kcs > mtx) kcs = kcs/mc +1;
- }
- }
- }
-
- for(i = 1; i <= nrs; i++)
- {
- while (lp[i-1] != i)
- {
- nx = lp[i-1];
- lp [i-1] = lp[nx-1];
- lp[nx-1] = nx;
- ixs = nr + (i-1) * mc;
- iy = nr + (nx-1) * mc;
- iec = ixs / mc;
- iec = iec * mc + ntc ;
- for(ix = ixs; ix <= iec; ix++)
- {
- temp = a[ix];
- a[ix] = a[iy];
- a[iy] = temp;
- iy = iy + 1;
- }
- }
- }
- return ;
-
- er2: *ierr = 2;
- *dt = 999999999.;
- return;
-
- er1: *ierr = 1;
- }