agg_simul_eq.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. //----------------------------------------------------------------------------
  2. // Anti-Grain Geometry - Version 2.4
  3. // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
  4. //
  5. // Permission to copy, use, modify, sell and distribute this software
  6. // is granted provided this copyright notice appears in all copies.
  7. // This software is provided "as is" without express or implied
  8. // warranty, and with no claim as to its suitability for any purpose.
  9. //
  10. //----------------------------------------------------------------------------
  11. // Contact: mcseem@antigrain.com
  12. // mcseemagg@yahoo.com
  13. // http://www.antigrain.com
  14. //----------------------------------------------------------------------------
  15. //
  16. // Solving simultaneous equations
  17. //
  18. //----------------------------------------------------------------------------
  19. #ifndef AGG_SIMUL_EQ_INCLUDED
  20. #define AGG_SIMUL_EQ_INCLUDED
  21. #include <math.h>
  22. #include "agg_basics.h"
  23. namespace agg
  24. {
  25. //=============================================================swap_arrays
  26. template<class T> void swap_arrays(T* a1, T* a2, unsigned n)
  27. {
  28. unsigned i;
  29. for(i = 0; i < n; i++)
  30. {
  31. T tmp = *a1;
  32. *a1++ = *a2;
  33. *a2++ = tmp;
  34. }
  35. }
  36. //============================================================matrix_pivot
  37. template<unsigned Rows, unsigned Cols>
  38. struct matrix_pivot
  39. {
  40. static int pivot(double m[Rows][Cols], unsigned row)
  41. {
  42. int k = int(row);
  43. double max_val, tmp;
  44. max_val = -1.0;
  45. unsigned i;
  46. for(i = row; i < Rows; i++)
  47. {
  48. if((tmp = fabs(m[i][row])) > max_val && tmp != 0.0)
  49. {
  50. max_val = tmp;
  51. k = i;
  52. }
  53. }
  54. if(m[k][row] == 0.0)
  55. {
  56. return -1;
  57. }
  58. if(k != int(row))
  59. {
  60. swap_arrays(m[k], m[row], Cols);
  61. return k;
  62. }
  63. return 0;
  64. }
  65. };
  66. //===============================================================simul_eq
  67. template<unsigned Size, unsigned RightCols>
  68. struct simul_eq
  69. {
  70. static bool solve(const double left[Size][Size],
  71. const double right[Size][RightCols],
  72. double result[Size][RightCols])
  73. {
  74. unsigned i, j, k;
  75. double a1;
  76. double tmp[Size][Size + RightCols];
  77. for(i = 0; i < Size; i++)
  78. {
  79. for(j = 0; j < Size; j++)
  80. {
  81. tmp[i][j] = left[i][j];
  82. }
  83. for(j = 0; j < RightCols; j++)
  84. {
  85. tmp[i][Size + j] = right[i][j];
  86. }
  87. }
  88. for(k = 0; k < Size; k++)
  89. {
  90. if(matrix_pivot<Size, Size + RightCols>::pivot(tmp, k) < 0)
  91. {
  92. return false; // Singularity....
  93. }
  94. a1 = tmp[k][k];
  95. for(j = k; j < Size + RightCols; j++)
  96. {
  97. tmp[k][j] /= a1;
  98. }
  99. for(i = k + 1; i < Size; i++)
  100. {
  101. a1 = tmp[i][k];
  102. for (j = k; j < Size + RightCols; j++)
  103. {
  104. tmp[i][j] -= a1 * tmp[k][j];
  105. }
  106. }
  107. }
  108. for(k = 0; k < RightCols; k++)
  109. {
  110. int m;
  111. for(m = int(Size - 1); m >= 0; m--)
  112. {
  113. result[m][k] = tmp[m][Size + k];
  114. for(j = m + 1; j < Size; j++)
  115. {
  116. result[m][k] -= tmp[m][j] * result[j][k];
  117. }
  118. }
  119. }
  120. return true;
  121. }
  122. };
  123. }
  124. #endif