You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

144 lines
3.3 KiB

  1. /* ---------------------------------------------------------------------------
  2. Polynomial regression, freely adapted from:
  3. NUMERICAL METHODS: C Programs, (c) John H. Mathews 1995
  4. Algorithm translated to C by: Dr. Norman Fahrer
  5. NUMERICAL METHODS for Mathematics, Science and Engineering, 2nd Ed, 1992
  6. Prentice Hall, International Editions: ISBN 0-13-625047-5
  7. This free software is compliments of the author.
  8. E-mail address: in%"mathews@fullerton.edu"
  9. */
  10. #include <math.h>
  11. #include "reg.h"
  12. #define DMAX 5 /* Maximum degree of polynomial */
  13. #define NMAX 10 /* Maximum number of points */
  14. static void FactPiv(int N, double A[DMAX][DMAX], double B[], double Cf[]);
  15. void polyreg(const int M, const int N, const double X[], const double Y[], double C[]) {
  16. int R, K, J; /* Loop counters */
  17. double A[DMAX][DMAX]; /* A */
  18. double B[DMAX];
  19. double P[2 * DMAX + 1];
  20. double x, y;
  21. double p;
  22. /* Zero the array */
  23. for (R = 0; R < M + 1; R++)
  24. B[R] = 0;
  25. /* Compute the column vector */
  26. for (K = 0; K < N; K++) {
  27. y = Y[K];
  28. x = X[K];
  29. p = 1.0;
  30. for (R = 0; R < M + 1; R++) {
  31. B[R] += y * p;
  32. p = p * x;
  33. }
  34. }
  35. /* Zero the array */
  36. for (J = 1; J <= 2 * M; J++)
  37. P[J] = 0;
  38. P[0] = N;
  39. /* Compute the sum of powers of x_(K-1) */
  40. for (K = 0; K < N; K++) {
  41. x = X[K];
  42. p = X[K];
  43. for (J = 1; J <= 2 * M; J++) {
  44. P[J] += p;
  45. p = p * x;
  46. }
  47. }
  48. /* Determine the matrix entries */
  49. for (R = 0; R < M + 1; R++) {
  50. for (K = 0; K < M + 1; K++)
  51. A[R][K] = P[R + K];
  52. }
  53. /* Solve the linear system of M + 1 equations: A*C = B
  54. for the coefficient vector C = (c_1,c_2,..,c_M,c_(M+1)) */
  55. FactPiv(M + 1, A, B, C);
  56. } /* end main */
  57. /*--------------------------------------------------------*/
  58. static void FactPiv(int N, double A[DMAX][DMAX], double B[], double Cf[]) {
  59. int K, P, C, J; /* Loop counters */
  60. int Row[NMAX]; /* Field with row-number */
  61. double X[DMAX], Y[DMAX];
  62. double SUM, DET = 1.0;
  63. int T;
  64. /* Initialize the pointer vector */
  65. for (J = 0; J < NMAX; J++)
  66. Row[J] = J;
  67. /* Start LU factorization */
  68. for (P = 0; P < N - 1; P++) {
  69. /* Find pivot element */
  70. for (K = P + 1; K < N; K++) {
  71. if (fabs(A[Row[K]][P]) > fabs(A[Row[P]][P])) {
  72. /* Switch the index for the p-1 th pivot row if necessary */
  73. T = Row[P];
  74. Row[P] = Row[K];
  75. Row[K] = T;
  76. DET = -DET;
  77. }
  78. } /* End of simulated row interchange */
  79. if (A[Row[P]][P] == 0) {
  80. /* The matrix is SINGULAR! */
  81. return;
  82. }
  83. /* Multiply the diagonal elements */
  84. DET = DET * A[Row[P]][P];
  85. /* Form multiplier */
  86. for (K = P + 1; K < N; K++) {
  87. A[Row[K]][P] = A[Row[K]][P] / A[Row[P]][P];
  88. /* Eliminate X_(p-1) */
  89. for (C = P + 1; C < N + 1; C++) {
  90. A[Row[K]][C] -= A[Row[K]][P] * A[Row[P]][C];
  91. }
  92. }
  93. }
  94. /* End of L*U factorization routine */
  95. DET = DET * A[Row[N - 1]][N - 1];
  96. /* Start the forward substitution */
  97. for (K = 0; K < N; K++)
  98. Y[K] = B[K];
  99. Y[0] = B[Row[0]];
  100. for (K = 1; K < N; K++) {
  101. SUM = 0;
  102. for (C = 0; C <= K - 1; C++)
  103. SUM += A[Row[K]][C] * Y[C];
  104. Y[K] = B[Row[K]] - SUM;
  105. }
  106. /* Start the back substitution */
  107. X[N - 1] = Y[N - 1] / A[Row[N - 1]][N - 1];
  108. for (K = N - 2; K >= 0; K--) {
  109. SUM = 0;
  110. for (C = K + 1; C < N; C++) {
  111. SUM += A[Row[K]][C] * X[C];
  112. }
  113. X[K] = (Y[K] - SUM) / A[Row[K]][K];
  114. } /* End of back substitution */
  115. /* Output */
  116. for (K = 0; K < N; K++)
  117. Cf[K] = X[K];
  118. }