cminv.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /* cminv.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. int cminv(Cpx * a, int n)
  11. {
  12. int i, j, k, m, lc, *le;
  13. Cpx *ps, *p, *q, *pa, *pd;
  14. Cpx z, h, *q0;
  15. double s, t, tq = 0., zr = 1.e-15;
  16. le = (int *)calloc(n, sizeof(int));
  17. q0 = (Cpx *) calloc(n, sizeof(Cpx));
  18. pa = pd = a;
  19. for (j = 0; j < n; ++j, ++pa, pd += n + 1) {
  20. if (j > 0) {
  21. for (i = 0, p = pa, q = q0; i < n; ++i, p += n)
  22. *q++ = *p;
  23. for (i = 1; i < n; ++i) {
  24. lc = i < j ? i : j;
  25. z.re = z.im = 0.;
  26. for (k = 0, p = pa + i * n - j, q = q0; k < lc; ++k, ++q, ++p) {
  27. z.re += p->re * q->re - p->im * q->im;
  28. z.im += p->im * q->re + p->re * q->im;
  29. }
  30. q0[i].re -= z.re;
  31. q0[i].im -= z.im;
  32. }
  33. for (i = 0, p = pa, q = q0; i < n; ++i, p += n)
  34. *p = *q++;
  35. }
  36. s = fabs(pd->re) + fabs(pd->im);
  37. lc = j;
  38. for (k = j + 1, ps = pd; k < n; ++k) {
  39. ps += n;
  40. if ((t = fabs(ps->re) + fabs(ps->im)) > s) {
  41. s = t;
  42. lc = k;
  43. }
  44. }
  45. tq = tq > s ? tq : s;
  46. if (s < zr * tq) {
  47. free(le - j);
  48. free(q0);
  49. return -1;
  50. }
  51. *le++ = lc;
  52. if (lc != j) {
  53. p = a + n * j;
  54. q = a + n * lc;
  55. for (k = 0; k < n; ++k, ++p, ++q) {
  56. h = *p;
  57. *p = *q;
  58. *q = h;
  59. }
  60. }
  61. t = pd->re * pd->re + pd->im * pd->im;
  62. h.re = pd->re / t;
  63. h.im = -(pd->im) / t;
  64. for (k = j + 1, ps = pd + n; k < n; ++k, ps += n) {
  65. z.re = ps->re * h.re - ps->im * h.im;
  66. z.im = ps->im * h.re + ps->re * h.im;
  67. *ps = z;
  68. }
  69. *pd = h;
  70. }
  71. for (j = 1, pd = ps = a; j < n; ++j) {
  72. for (k = 0, pd += n + 1, q = ++ps; k < j; ++k, q += n) {
  73. z.re = q->re * pd->re - q->im * pd->im;
  74. z.im = q->im * pd->re + q->re * pd->im;
  75. *q = z;
  76. }
  77. }
  78. for (j = 1, pa = a; j < n; ++j) {
  79. ++pa;
  80. for (i = 0, q = q0, p = pa; i < j; ++i, p += n)
  81. *q++ = *p;
  82. for (k = 0; k < j; ++k) {
  83. h.re = h.im = 0.;
  84. for (i = k, p = pa + k * n + k - j, q = q0 + k; i < j; ++i) {
  85. h.re -= p->re * q->re - p->im * q->im;
  86. h.im -= p->im * q->re + p->re * q->im;
  87. ++p;
  88. ++q;
  89. }
  90. q0[k] = h;
  91. }
  92. for (i = 0, q = q0, p = pa; i < j; ++i, p += n)
  93. *p = *q++;
  94. }
  95. for (j = n - 2, pd = pa = a + n * n - 1; j >= 0; --j) {
  96. --pa;
  97. pd -= n + 1;
  98. for (i = 0, m = n - j - 1, q = q0, p = pd + n; i < m; ++i, p += n)
  99. *q++ = *p;
  100. for (k = n - 1, ps = pa; k > j; --k, ps -= n) {
  101. z.re = -ps->re;
  102. z.im = -ps->im;
  103. for (i = j + 1, p = ps + 1, q = q0; i < k; ++i, ++p, ++q) {
  104. z.re -= p->re * q->re - p->im * q->im;
  105. z.im -= p->im * q->re + p->re * q->im;
  106. }
  107. q0[--m] = z;
  108. }
  109. for (i = 0, m = n - j - 1, q = q0, p = pd + n; i < m; ++i, p += n)
  110. *p = *q++;
  111. }
  112. for (k = 0, pa = a; k < n - 1; ++k, ++pa) {
  113. for (i = 0, q = q0, p = pa; i < n; ++i, p += n)
  114. *q++ = *p;
  115. for (j = 0, ps = a; j < n; ++j, ps += n) {
  116. if (j > k) {
  117. h.re = h.im = 0.;
  118. p = ps + j;
  119. i = j;
  120. }
  121. else {
  122. h = q0[j];
  123. p = ps + k + 1;
  124. i = k + 1;
  125. }
  126. for (; i < n; ++i, ++p) {
  127. h.re += p->re * q0[i].re - p->im * q0[i].im;
  128. h.im += p->im * q0[i].re + p->re * q0[i].im;
  129. }
  130. q0[j] = h;
  131. }
  132. for (i = 0, q = q0, p = pa; i < n; ++i, p += n)
  133. *p = *q++;
  134. }
  135. for (j = n - 2, le--; j >= 0; --j) {
  136. for (k = 0, p = a + j, q = a + *(--le); k < n; ++k, p += n, q += n) {
  137. h = *p;
  138. *p = *q;
  139. *q = h;
  140. }
  141. }
  142. free(le);
  143. free(q0);
  144. return 0;
  145. }