|
GRASS Programmer's Manual
6.5.svn(2012)-r51648
|
00001 /* unitary.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 static double tpi = 6.283185307179586; 00011 00012 static void uortho(double *g, int n); 00013 00014 double unfl(); 00015 00016 void unitary(Cpx * u, int n) 00017 { 00018 int i, j, k, m; 00019 00020 Cpx h, *v, *e, *p, *r; 00021 00022 double *g, *q, a; 00023 00024 m = n * n; 00025 g = (double *)calloc(n * n, sizeof(double)); 00026 v = (Cpx *) calloc(m + n, sizeof(Cpx)); 00027 e = v + m; 00028 h.re = 1.; 00029 h.im = 0.; 00030 for (i = 0; i < n; ++i) { 00031 a = tpi * unfl(); 00032 e[i].re = cos(a); 00033 e[i].im = sin(a); 00034 a = h.re * e[i].re - h.im * e[i].im; 00035 h.im = h.im * e[i].re + h.re * e[i].im; 00036 h.re = a; 00037 } 00038 h.im = -h.im; 00039 for (i = 0; i < n; ++i) { 00040 a = e[i].re * h.re - e[i].im * h.im; 00041 e[i].im = e[i].re * h.im + e[i].im * h.re; 00042 e[i].re = a; 00043 } 00044 uortho(g, n); 00045 for (i = 0, p = v, q = g; i < n; ++i) { 00046 for (j = 0; j < n; ++j) 00047 (p++)->re = *q++; 00048 } 00049 for (i = 0, p = v; i < n; ++i) { 00050 for (j = 0, h = e[i]; j < n; ++j, ++p) { 00051 a = h.re * p->re - h.im * p->im; 00052 p->im = h.im * p->re + h.re * p->im; 00053 p->re = a; 00054 } 00055 } 00056 uortho(g, n); 00057 for (i = m = 0, p = u; i < n; ++i, m += n) { 00058 for (j = 0; j < n; ++j, ++p) { 00059 p->re = p->im = 0.; 00060 for (k = 0, q = g + m, r = v + j; k < n; ++k, r += n) { 00061 p->re += *q * r->re; 00062 p->im += *q++ * r->im; 00063 } 00064 } 00065 } 00066 free(g); 00067 free(v); 00068 } 00069 00070 static void uortho(double *g, int n) 00071 { 00072 int i, j, k, m; 00073 00074 double *p, *q, c, s, a; 00075 00076 for (i = 0, p = g; i < n; ++i) { 00077 for (j = 0; j < n; ++j) { 00078 if (i == j) 00079 *p++ = 1.; 00080 else 00081 *p++ = 0.; 00082 } 00083 } 00084 for (i = 0, m = n - 1; i < m; ++i) { 00085 for (j = i + 1; j < n; ++j) { 00086 a = tpi * unfl(); 00087 c = cos(a); 00088 s = sin(a); 00089 p = g + n * i; 00090 q = g + n * j; 00091 for (k = 0; k < n; ++k) { 00092 a = *p * c + *q * s; 00093 *q = *q * c - *p * s; 00094 *p++ = a; 00095 ++q; 00096 } 00097 } 00098 } 00099 }