GRASS Programmer's Manual  6.5.svn(2012)-r51648
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
minv.c
Go to the documentation of this file.
00001 /*  minv.c    CCMATH mathematics library source code.
00002  *
00003  *  Copyright (C)  2000   Daniel A. Atkinson    All rights reserved.
00004  *  This code may be redistributed under the terms of the GNU library
00005  *  public license (LGPL). ( See the lgpl.license file for details.)
00006  * ------------------------------------------------------------------------
00007  */
00008 #include <stdlib.h>
00009 #include "ccmath.h"
00010 int minv(double *a, int n)
00011 {
00012     int lc, *le;
00013 
00014     double s, t, tq = 0., zr = 1.e-15;
00015 
00016     double *pa, *pd, *ps, *p, *q, *q0;
00017 
00018     int i, j, k, m;
00019 
00020     le = (int *)malloc(n * sizeof(int));
00021     q0 = (double *)malloc(n * sizeof(double));
00022     for (j = 0, pa = pd = a; j < n; ++j, ++pa, pd += n + 1) {
00023         if (j > 0) {
00024             for (i = 0, q = q0, p = pa; i < n; ++i, p += n)
00025                 *q++ = *p;
00026             for (i = 1; i < n; ++i) {
00027                 lc = i < j ? i : j;
00028                 for (k = 0, p = pa + i * n - j, q = q0, t = 0.; k < lc; ++k)
00029                     t += *p++ * *q++;
00030                 q0[i] -= t;
00031             }
00032             for (i = 0, q = q0, p = pa; i < n; ++i, p += n)
00033                 *p = *q++;
00034         }
00035         s = fabs(*pd);
00036         lc = j;
00037         for (k = j + 1, ps = pd; k < n; ++k) {
00038             if ((t = fabs(*(ps += n))) > s) {
00039                 s = t;
00040                 lc = k;
00041             }
00042         }
00043         tq = tq > s ? tq : s;
00044         if (s < zr * tq) {
00045             free(le - j);
00046             free(q0);
00047             return -1;
00048         }
00049         *le++ = lc;
00050         if (lc != j) {
00051             for (k = 0, p = a + n * j, q = a + n * lc; k < n; ++k) {
00052                 t = *p;
00053                 *p++ = *q;
00054                 *q++ = t;
00055             }
00056         }
00057         for (k = j + 1, ps = pd, t = 1. / *pd; k < n; ++k)
00058             *(ps += n) *= t;
00059         *pd = t;
00060     }
00061     for (j = 1, pd = ps = a; j < n; ++j) {
00062         for (k = 0, pd += n + 1, q = ++ps; k < j; ++k, q += n)
00063             *q *= *pd;
00064     }
00065     for (j = 1, pa = a; j < n; ++j) {
00066         ++pa;
00067         for (i = 0, q = q0, p = pa; i < j; ++i, p += n)
00068             *q++ = *p;
00069         for (k = 0; k < j; ++k) {
00070             t = 0.;
00071             for (i = k, p = pa + k * n + k - j, q = q0 + k; i < j; ++i)
00072                 t -= *p++ * *q++;
00073             q0[k] = t;
00074         }
00075         for (i = 0, q = q0, p = pa; i < j; ++i, p += n)
00076             *p = *q++;
00077     }
00078     for (j = n - 2, pd = pa = a + n * n - 1; j >= 0; --j) {
00079         --pa;
00080         pd -= n + 1;
00081         for (i = 0, m = n - j - 1, q = q0, p = pd + n; i < m; ++i, p += n)
00082             *q++ = *p;
00083         for (k = n - 1, ps = pa; k > j; --k, ps -= n) {
00084             t = -(*ps);
00085             for (i = j + 1, p = ps, q = q0; i < k; ++i)
00086                 t -= *++p * *q++;
00087             q0[--m] = t;
00088         }
00089         for (i = 0, m = n - j - 1, q = q0, p = pd + n; i < m; ++i, p += n)
00090             *p = *q++;
00091     }
00092     for (k = 0, pa = a; k < n - 1; ++k, ++pa) {
00093         for (i = 0, q = q0, p = pa; i < n; ++i, p += n)
00094             *q++ = *p;
00095         for (j = 0, ps = a; j < n; ++j, ps += n) {
00096             if (j > k) {
00097                 t = 0.;
00098                 p = ps + j;
00099                 i = j;
00100             }
00101             else {
00102                 t = q0[j];
00103                 p = ps + k + 1;
00104                 i = k + 1;
00105             }
00106             for (; i < n;)
00107                 t += *p++ * q0[i++];
00108             q0[j] = t;
00109         }
00110         for (i = 0, q = q0, p = pa; i < n; ++i, p += n)
00111             *p = *q++;
00112     }
00113     for (j = n - 2, le--; j >= 0; --j) {
00114         for (k = 0, p = a + j, q = a + *(--le); k < n; ++k, p += n, q += n) {
00115             t = *p;
00116             *p = *q;
00117             *q = t;
00118         }
00119     }
00120     free(le);
00121     free(q0);
00122     return 0;
00123 }