GRASS Programmer's Manual  6.5.svn(2012)-r51648
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
unitary.c
Go to the documentation of this file.
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 }