sv2val.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /* sv2val.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 sv2val(double *d, double *a, int m, int n)
  11. {
  12. double *p, *p1, *q, *w, *v;
  13. double s, h, u;
  14. int i, j, k, mm, nm, ms;
  15. if (m < n)
  16. return -1;
  17. w = (double *)calloc(m, sizeof(double));
  18. for (i = 0, mm = m, p = a; i < n && mm > 1; ++i, --mm, p += n + 1) {
  19. for (j = 0, q = p, s = 0.; j < mm; ++j, q += n) {
  20. w[j] = *q;
  21. s += *q * *q;
  22. }
  23. if (s > 0.) {
  24. h = sqrt(s);
  25. if (*p < 0.)
  26. h = -h;
  27. s += *p * h;
  28. s = 1. / s;
  29. w[0] += h;
  30. for (k = 1, ms = n - i; k < ms; ++k) {
  31. for (j = 0, q = p + k, u = 0.; j < mm; q += n)
  32. u += w[j++] * *q;
  33. u = u * s;
  34. for (j = 0, q = p + k; j < mm; q += n)
  35. *q -= u * w[j++];
  36. }
  37. *p = -h;
  38. }
  39. }
  40. for (i = 0, p = a; i < n; ++i, p += n) {
  41. for (j = 0, q = p; j < i; ++j)
  42. *q++ = 0.;
  43. }
  44. for (i = 0, mm = n, nm = n - 1, p = a; i < n; ++i, --mm, --nm, p += n + 1) {
  45. if (i && mm > 1) {
  46. for (j = 0, q = p, s = 0.; j < mm; ++j, q += n) {
  47. w[j] = *q;
  48. s += *q * *q;
  49. }
  50. if (s > 0.) {
  51. h = sqrt(s);
  52. if (*p < 0.)
  53. h = -h;
  54. s += *p * h;
  55. s = 1. / s;
  56. w[0] += h;
  57. for (k = 1, ms = n - i; k < ms; ++k) {
  58. for (j = 0, q = p + k, u = 0.; j < mm; q += n)
  59. u += w[j++] * *q;
  60. u *= s;
  61. for (j = 0, q = p + k; j < mm; q += n)
  62. *q -= u * w[j++];
  63. }
  64. *p = -h;
  65. }
  66. }
  67. p1 = p + 1;
  68. if (nm > 1) {
  69. for (j = 0, q = p1, s = 0.; j < nm; ++j, ++q)
  70. s += *q * *q;
  71. if (s > 0.) {
  72. h = sqrt(s);
  73. if (*p1 < 0.)
  74. h = -h;
  75. s += *p1 * h;
  76. s = 1. / s;
  77. *p1 += h;
  78. for (k = n, ms = n * (m - i); k < ms; k += n) {
  79. for (j = 0, q = p1, v = p1 + k, u = 0.; j < nm; ++j)
  80. u += *q++ * *v++;
  81. u *= s;
  82. for (j = 0, q = p1, v = p1 + k; j < nm; ++j)
  83. *v++ -= u * *q++;
  84. }
  85. *p1 = -h;
  86. }
  87. }
  88. }
  89. for (j = 0, p = a; j < n; ++j, p += n + 1) {
  90. d[j] = *p;
  91. if (j < n - 1)
  92. w[j] = *(p + 1);
  93. else
  94. w[j] = 0.;
  95. }
  96. qrbdi(d, w, n);
  97. for (i = 0; i < n; ++i)
  98. if (d[i] < 0.)
  99. d[i] = -d[i];
  100. free(w);
  101. return 0;
  102. }