|
GRASS Programmer's Manual
6.5.svn(2012)-r51648
|
00001 /* csolv.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 csolv(Cpx * a, Cpx * b, int n) 00011 { 00012 int i, j, k, lc; 00013 00014 Cpx *ps, *p, *q, *pa, *pd; 00015 00016 Cpx z, h, *q0; 00017 00018 double s, t, tq = 0., zr = 1.e-15; 00019 00020 q0 = (Cpx *) calloc(n, sizeof(Cpx)); 00021 pa = a; 00022 pd = a; 00023 for (j = 0; j < n; ++j, ++pa, pd += n + 1) { 00024 if (j > 0) { 00025 for (i = 0, p = pa, q = q0; i < n; ++i, p += n) 00026 *q++ = *p; 00027 for (i = 1; i < n; ++i) { 00028 lc = i < j ? i : j; 00029 z.re = z.im = 0.; 00030 for (k = 0, p = pa + i * n - j, q = q0; k < lc; ++k, ++q, ++p) { 00031 z.re += p->re * q->re - p->im * q->im; 00032 z.im += p->im * q->re + p->re * q->im; 00033 } 00034 q0[i].re -= z.re; 00035 q0[i].im -= z.im; 00036 } 00037 for (i = 0, p = pa, q = q0; i < n; ++i, p += n) 00038 *p = *q++; 00039 } 00040 s = fabs(pd->re) + fabs(pd->im); 00041 lc = j; 00042 for (k = j + 1, ps = pd; k < n; ++k) { 00043 ps += n; 00044 if ((t = fabs(ps->re) + fabs(ps->im)) > s) { 00045 s = t; 00046 lc = k; 00047 } 00048 } 00049 tq = tq > s ? tq : s; 00050 if (s < zr * tq) { 00051 free(q0); 00052 return -1; 00053 } 00054 if (lc != j) { 00055 h = b[j]; 00056 b[j] = b[lc]; 00057 b[lc] = h; 00058 p = a + n * j; 00059 q = a + n * lc; 00060 for (k = 0; k < n; ++k) { 00061 h = *p; 00062 *p++ = *q; 00063 *q++ = h; 00064 } 00065 } 00066 t = pd->re * pd->re + pd->im * pd->im; 00067 h.re = pd->re / t; 00068 h.im = -(pd->im) / t; 00069 for (k = j + 1, ps = pd + n; k < n; ++k, ps += n) { 00070 z.re = ps->re * h.re - ps->im * h.im; 00071 z.im = ps->im * h.re + ps->re * h.im; 00072 *ps = z; 00073 } 00074 } 00075 for (j = 1, ps = b + 1; j < n; ++j, ++ps) { 00076 for (k = 0, p = a + n * j, q = b, z.re = z.im = 0.; k < j; ++k) { 00077 z.re += p->re * q->re - p->im * q->im; 00078 z.im += p->im * q->re + p->re * q->im; 00079 ++p; 00080 ++q; 00081 } 00082 ps->re -= z.re; 00083 ps->im -= z.im; 00084 } 00085 for (j = n - 1, --ps, pd = a + n * n - 1; j >= 0; --j, pd -= n + 1) { 00086 for (k = j + 1, p = pd + 1, q = b + j + 1, z.re = z.im = 0.; k < n; 00087 ++k) { 00088 z.re += p->re * q->re - p->im * q->im; 00089 z.im += p->im * q->re + p->re * q->im; 00090 ++p; 00091 ++q; 00092 } 00093 h.re = ps->re - z.re; 00094 h.im = ps->im - z.im; 00095 t = pd->re * pd->re + pd->im * pd->im; 00096 ps->re = (h.re * pd->re + h.im * pd->im) / t; 00097 ps->im = (h.im * pd->re - h.re * pd->im) / t; 00098 --ps; 00099 } 00100 free(q0); 00101 return 0; 00102 }