Advertisement
Guest User

Untitled

a guest
May 28th, 2015
214
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.55 KB | None | 0 0
  1. using System;
  2.  
  3. namespace MathUtil
  4. {
  5. public class Solver
  6. {
  7. static void Main(string[] args)
  8. {
  9. // 方程式
  10. // 3x + 2y + z = 10
  11. // x + 4y + z = 12
  12. // 2x + 2y + 5z = 21
  13.  
  14. // 解
  15. // (x, y, z) = (1, 2, 3)
  16.  
  17. var matrix = new double[,] {
  18. { 3, 2, 1 },
  19. { 1, 4, 1 },
  20. { 2, 2, 5 }
  21. };
  22. var b = new double[] { 10, 12, 21 };
  23. var eps = 1e-15;
  24. var result = Solver.GaussSeidel(matrix, b, 10000, eps);
  25.  
  26.  
  27. Console.WriteLine("Error:" + result.Error);
  28. Console.WriteLine("Count:" + result.Iterator);
  29.  
  30. var xyz = new[] { "x", "y", "z" };
  31. for (int i = 0; i < result.Solution.Length; i++)
  32. {
  33. Console.WriteLine(xyz[i] + " = " + result.Solution[i]);
  34. }
  35. }
  36.  
  37. /// <summary>
  38. /// <para>
  39. /// ガウス=ザイデル法(Gauss-Seidel method)
  40. /// </para>
  41. /// <para>
  42. /// 解が収束するのは
  43. /// ・対角有利(diagonal dominant, 対角要素の絶対値>その行の他の要素の絶対値の和)
  44. /// ・係数行列が対称(symmetric)かつ正定(positive definite)
  45. /// ・Σ_j |a_ij/a_ii| < 1 (i = 1~n, j != i)
  46. /// </para>
  47. /// </summary>
  48. /// <param name="squareMatrix">n×nの係数行列</param>
  49. /// <param name="constantVector">n×1の定数項(b)の行列(定数項ベクトル)</param>
  50. /// <param name="maxIterator">最大反復数</param>
  51. /// <param name="eps">許容誤差</param>
  52. /// <param name="AbsoluteError">[option]収束判定で絶対誤差と相対誤差のどちらを用いるか示す。
  53. /// 真のときは絶対誤差、偽のときは相対誤差を用いる。</param>
  54. /// <returns>解の行列</returns>
  55. public static IterativeResult GaussSeidel(double[,] squareMatrix, double[] constantVector, int maxIterator, double eps, bool AbsoluteError = true)
  56. {
  57. if (squareMatrix.GetLength(0) != squareMatrix.GetLength(1))
  58. {
  59. throw new ArgumentException("引き数の係数行列が正方行列でありません。", "A");
  60. }
  61. if (squareMatrix.GetLength(0) != constantVector.Length)
  62. {
  63. throw new ArgumentException("引き数の定数項行列が係数行列の大きさと一致しません。");
  64. }
  65.  
  66. // 行列の大きさ
  67. int n = squareMatrix.GetLength(0);
  68. // 解。初期値はすべて0
  69. double[] solution = new double[n];
  70. // 誤差
  71. double e = 0.0;
  72. // 現在の反復回数
  73. int k;
  74.  
  75. double tmp;
  76.  
  77. for (k = 0; k < maxIterator; ++k)
  78. {
  79. // 現在の値を代入して次の解候補を計算
  80. e = 0.0;
  81. for (int i = 0; i < n; ++i)
  82. {
  83. tmp = solution[i];
  84. solution[i] = constantVector[i];
  85. for (int j = 0; j < n; ++j)
  86. {
  87. solution[i] -= (j != i ? squareMatrix[i, j] * solution[j] : 0.0);
  88. }
  89. solution[i] /= squareMatrix[i, i];
  90.  
  91. if (AbsoluteError)
  92. {
  93. // 絶対誤差
  94. e += Math.Abs(tmp - solution[i]);
  95. }
  96. else
  97. {
  98. // 相対誤差
  99. e += Math.Abs((tmp - solution[i]) / tmp);
  100. }
  101. }
  102. // 収束判定
  103. if (e <= eps)
  104. {
  105. break;
  106. }
  107. }
  108.  
  109. return new IterativeResult(solution, k, e);
  110. }
  111.  
  112. public struct IterativeResult
  113. {
  114. public IterativeResult(double[] solution, int iterator, double error)
  115. {
  116. this.Solution = solution;
  117. this.Iterator = iterator;
  118. this.Error = error;
  119.  
  120. }
  121.  
  122. /// <summary>
  123. /// 解
  124. /// </summary>
  125. public double[] Solution { get; set; }
  126.  
  127. /// <summary>
  128. /// 反復回数
  129. /// </summary>
  130. public int Iterator { get; set; }
  131.  
  132. /// <summary>
  133. /// 誤差
  134. /// </summary>
  135. public double Error { get; set; }
  136. }
  137. }
  138. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement