unitary.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /* unitary.c CCMATH mathematics library source code.
  2. *
  3. * Copyright (C) 2000 Daniel A. Atkinson All rights reserved.
  4. * This code may be redistributed under the terms of the GNU library
  5. * public license (LGPL). ( See the lgpl.license file for details.)
  6. * ------------------------------------------------------------------------
  7. */
  8. #include <stdlib.h>
  9. #include "ccmath.h"
  10. static double tpi = 6.283185307179586;
  11. static void uortho(double *g, int n);
  12. double unfl();
  13. void unitary(Cpx * u, int n)
  14. {
  15. int i, j, k, m;
  16. Cpx h, *v, *e, *p, *r;
  17. double *g, *q, a;
  18. m = n * n;
  19. g = (double *)calloc(n * n, sizeof(double));
  20. v = (Cpx *) calloc(m + n, sizeof(Cpx));
  21. e = v + m;
  22. h.re = 1.;
  23. h.im = 0.;
  24. for (i = 0; i < n; ++i) {
  25. a = tpi * unfl();
  26. e[i].re = cos(a);
  27. e[i].im = sin(a);
  28. a = h.re * e[i].re - h.im * e[i].im;
  29. h.im = h.im * e[i].re + h.re * e[i].im;
  30. h.re = a;
  31. }
  32. h.im = -h.im;
  33. for (i = 0; i < n; ++i) {
  34. a = e[i].re * h.re - e[i].im * h.im;
  35. e[i].im = e[i].re * h.im + e[i].im * h.re;
  36. e[i].re = a;
  37. }
  38. uortho(g, n);
  39. for (i = 0, p = v, q = g; i < n; ++i) {
  40. for (j = 0; j < n; ++j)
  41. (p++)->re = *q++;
  42. }
  43. for (i = 0, p = v; i < n; ++i) {
  44. for (j = 0, h = e[i]; j < n; ++j, ++p) {
  45. a = h.re * p->re - h.im * p->im;
  46. p->im = h.im * p->re + h.re * p->im;
  47. p->re = a;
  48. }
  49. }
  50. uortho(g, n);
  51. for (i = m = 0, p = u; i < n; ++i, m += n) {
  52. for (j = 0; j < n; ++j, ++p) {
  53. p->re = p->im = 0.;
  54. for (k = 0, q = g + m, r = v + j; k < n; ++k, r += n) {
  55. p->re += *q * r->re;
  56. p->im += *q++ * r->im;
  57. }
  58. }
  59. }
  60. free(g);
  61. free(v);
  62. }
  63. static void uortho(double *g, int n)
  64. {
  65. int i, j, k, m;
  66. double *p, *q, c, s, a;
  67. for (i = 0, p = g; i < n; ++i) {
  68. for (j = 0; j < n; ++j) {
  69. if (i == j)
  70. *p++ = 1.;
  71. else
  72. *p++ = 0.;
  73. }
  74. }
  75. for (i = 0, m = n - 1; i < m; ++i) {
  76. for (j = i + 1; j < n; ++j) {
  77. a = tpi * unfl();
  78. c = cos(a);
  79. s = sin(a);
  80. p = g + n * i;
  81. q = g + n * j;
  82. for (k = 0; k < n; ++k) {
  83. a = *p * c + *q * s;
  84. *q = *q * c - *p * s;
  85. *p++ = a;
  86. ++q;
  87. }
  88. }
  89. }
  90. }