sv2u1v.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /* sv2u1v.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 sv2u1v(double *d, double *a, int m, double *v, int n)
  11. {
  12. double *p, *p1, *q, *pp, *w, *e;
  13. double s, t, h, r, sv;
  14. int i, j, k, mm, nm, ms;
  15. if (m < n)
  16. return -1;
  17. w = (double *)calloc(m + n, sizeof(double));
  18. e = w + m;
  19. for (i = 0, mm = m, p = a; i < n; ++i, --mm, p += n + 1) {
  20. if (mm > 1) {
  21. sv = h = 0.;
  22. for (j = 0, q = p, s = 0.; j < mm; ++j, q += n) {
  23. w[j] = *q;
  24. s += *q * *q;
  25. }
  26. if (s > 0.) {
  27. h = sqrt(s);
  28. if (*p < 0.)
  29. h = -h;
  30. s += *p * h;
  31. s = 1. / s;
  32. t = 1. / (w[0] += h);
  33. sv = 1. + fabs(*p / h);
  34. for (k = 1, ms = n - i; k < ms; ++k) {
  35. for (j = 0, q = p + k, r = 0.; j < mm; q += n)
  36. r += w[j++] * *q;
  37. r = r * s;
  38. for (j = 0, q = p + k; j < mm; q += n)
  39. *q -= r * w[j++];
  40. }
  41. for (j = 1, q = p; j < mm;)
  42. *(q += n) = w[j++] * t;
  43. }
  44. *p = sv;
  45. d[i] = -h;
  46. }
  47. if (mm == 1)
  48. d[i] = *p;
  49. }
  50. for (i = 0, q = v, p = a; i < n; ++i) {
  51. for (j = 0; j < n; ++j, ++q, ++p) {
  52. if (j < i)
  53. *q = 0.;
  54. else if (j == i)
  55. *q = d[i];
  56. else
  57. *q = *p;
  58. }
  59. }
  60. atou1(a, m, n);
  61. for (i = 0, mm = n, nm = n - 1, p = v; i < n; ++i, --mm, --nm, p += n + 1) {
  62. if (i && mm > 1) {
  63. sv = h = 0.;
  64. for (j = 0, q = p, s = 0.; j < mm; ++j, q += n) {
  65. w[j] = *q;
  66. s += *q * *q;
  67. }
  68. if (s > 0.) {
  69. h = sqrt(s);
  70. if (*p < 0.)
  71. h = -h;
  72. s += *p * h;
  73. s = 1. / s;
  74. t = 1. / (w[0] += h);
  75. sv = 1. + fabs(*p / h);
  76. for (k = 1, ms = n - i; k < ms; ++k) {
  77. for (j = 0, q = p + k, r = 0.; j < mm; q += n)
  78. r += w[j++] * *q;
  79. for (j = 0, q = p + k, r *= s; j < mm; q += n)
  80. *q -= r * w[j++];
  81. }
  82. for (k = 0, p1 = a + i; k < m; ++k, p1 += n) {
  83. for (j = 0, q = p1, r = 0.; j < mm;)
  84. r += w[j++] * *q++;
  85. for (j = 0, q = p1, r *= s; j < mm;)
  86. *q++ -= r * w[j++];
  87. }
  88. }
  89. *p = sv;
  90. d[i] = -h;
  91. }
  92. if (mm == 1)
  93. d[i] = *p;
  94. p1 = p + 1;
  95. if (nm > 1) {
  96. sv = h = 0.;
  97. for (j = 0, q = p1, s = 0.; j < nm; ++j, ++q)
  98. s += *q * *q;
  99. if (s > 0.) {
  100. h = sqrt(s);
  101. if (*p1 < 0.)
  102. h = -h;
  103. sv = 1. + fabs(*p1 / h);
  104. s += *p1 * h;
  105. s = 1. / s;
  106. t = 1. / (*p1 += h);
  107. for (k = n, ms = n * (n - i); k < ms; k += n) {
  108. for (j = 0, q = p1, pp = p1 + k, r = 0.; j < nm; ++j)
  109. r += *q++ * *pp++;
  110. for (j = 0, q = p1, pp = p1 + k, r *= s; j < nm; ++j)
  111. *pp++ -= r * *q++;
  112. }
  113. for (j = 1, q = p1 + 1; j < nm; ++j)
  114. *q++ *= t;
  115. }
  116. *p1 = sv;
  117. e[i] = -h;
  118. }
  119. if (nm == 1)
  120. e[i] = *p1;
  121. }
  122. atovm(v, n);
  123. qrbdu1(d, e, a, m, v, n);
  124. for (i = 0; i < n; ++i) {
  125. if (d[i] < 0.) {
  126. d[i] = -d[i];
  127. for (j = 0, p = v + i; j < n; ++j, p += n)
  128. *p = -*p;
  129. }
  130. }
  131. free(w);
  132. return 0;
  133. }