/* Name dsweep - Inverts a positive definite matrix in place by a diagonal sweep. Usage #include "usual.h" #include "tools.h" INTEGER dsweep(REAL *a, INTEGER n, REAL eps) Prototype in tools.h Description a is a symmetric, positive definite, n by n matrix stored columnwise with no unused space and first element in a[0]; i.e., for (j=1; j<=n; j++) for (i=1; i<=n; i++) aij=a[n*(j-1)+(i-1)]; will traverse the matrix with aij being the element in the i-th row and j-th column. On return a contains the inverse of a stored columnwise. eps is an input constant used as a relative tolerance in testing for degenerate rank. A reasonable value for eps is 1.e-13. Remark dsweep.cc is dsweep.f translated to C++. Reference Schatzoff, M. et al. Efficient Calculation of all Possible Regressions. Technometrics, 10. 769-79 (November 1968) Return value The return value ier is an error parameter coded as follows: ier=0, no error, rank of a is n; ier > 0, a is singular, rank of a is n-ier. If ier > 0 then dsweep returns a g-inverse. Functions Library: (none) called Sublib: (none) */ #include "usual.h" #include "tools.h" INTEGER dsweep(REAL *a, INTEGER n, REAL eps) { INTEGER i, j, k, kk, ier; REAL test, d, aik, akj, akk, tol; a--; // Adjust offset to allow Fortran style indexing. tol=0.0; for (i=1; i<=n; i++) { test=a[n*(i-1)+i]; if(test > tol) tol=test; } tol=tol*eps; ier=0; for (k=1; k<=n; k++) { kk=n*(k-1)+k; akk=a[kk]; if (akk < tol) { ier=ier+1; for (j=k; j<=n; j++) // zero out row k of upper triangle a[n*(j-1)+k]=0.0; for (i=1; i<=k-1; i++) // zero out column k of upper triangle a[kk-i]=0.0; } else { // sweep d=1.0/akk; for (i=1; i <= n; i++) { for (j=i; j <= n; j++) { if (i != k && j != k) { if (i