Stoffel

determinant before

Feb 8th, 2013
46
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.23 KB | None | 0 0
  1. using MatrixCalculations.Exceptions;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7.  
  8. namespace MatrixCalculations
  9. {
  10. public class Matrix
  11. {
  12. //private properties
  13. private int _width;
  14. private int _heigth;
  15. private List<MatrixRow> _matrix = new List<MatrixRow>();
  16. private List<MatrixRow> _echelonForm = new List<MatrixRow>();
  17.  
  18. public Matrix(int h, int w)
  19. {
  20. _width = w;
  21. Heigth = h;
  22. }
  23.  
  24.  
  25.  
  26. //Row and Column operations
  27. public Matrix AddRow(MatrixRow r)
  28. {
  29. //Throw Exception if we want to add a row which is not the proper length
  30. if (r.Length() != Width)
  31. throw new FaultyRowSizeException(string.Format("ROW SIZE WRONG. ALLOWED: {0}, GIVEN: {1}", Width, r.Length()));
  32.  
  33. //Throw an exception if we want to add a row to a full matrix
  34. if (Heigth > _matrix.Count)
  35. {
  36. _matrix.Add(r);
  37. return this;
  38. }
  39. else
  40. {
  41. throw new MatrixFullException("MATRIX IS FULL, NOT ABLE TO INSERT");
  42. }
  43. }
  44. public Matrix SwapRows(int i, int k)
  45. {
  46. if (i > (Heigth - 1))
  47. throw new RowIndexOutOfBounds(string.Format("ROW INDEX WAS OUT OF BOUNDS. GIVEN {0}, MATRIXHEIGHT {1}", i, Heigth));
  48. if (k > (Heigth - 1))
  49. throw new RowIndexOutOfBounds(string.Format("ROW INDEX WAS OUT OF BOUNDS. GIVEN {0}, MATRIXHEIGHT {1}", k, Heigth));
  50.  
  51. var temp = _matrix[i];
  52. _matrix[i] = _matrix[k];
  53. _matrix[k] = temp;
  54. return this;
  55. }
  56.  
  57. //Echelon form
  58. public Matrix Rref()
  59. {
  60. double determinantFactor = 1;
  61. var done = false;
  62. var nonzerocoord = new Coordinate(0, 0);
  63.  
  64. //Create a copy of the current matrix
  65. var output = new Matrix(Heigth, Width);
  66. for (int ri = 0; ri < Heigth; ri++)
  67. {
  68. output.AddRow(new MatrixRow(GetRow(ri).GetAllValues().ToArray<double>()));
  69. }
  70.  
  71. while (!done)
  72. {
  73.  
  74. //Step 1: Find the first non-zero column
  75. for (int ci = nonzerocoord.Column; ci < Width; ci++)
  76. {
  77. if (!IsZeroColumn(ci))
  78. {
  79. nonzerocoord.Column = ci;
  80. break;
  81. }
  82. }
  83. //Step 2: Find the pivot-value, make it one, and put it on top
  84. SetPivotOneAndOnTop(ref output, nonzerocoord, ref determinantFactor);
  85.  
  86. //We have a pivot element, we need to make every element below the pivot zero.
  87. SetElementsZeroBelowPivot(ref output, nonzerocoord, ref determinantFactor);
  88.  
  89. //We need to repeat these steps disregarding the previous pivot
  90. //We repeat with next column
  91. nonzerocoord.Column++;
  92. nonzerocoord.Row++;
  93. if (nonzerocoord.Column == output.Width || nonzerocoord.Row == output.Heigth)
  94. done = true;
  95. }
  96. output.PrintMatrix();
  97. //AT this point we are only in echelonform
  98. //To get to row reduced echelonform we need to substract from the bottom up
  99. for (int ri = 0; ri < Heigth; ri++)
  100. {
  101. SetElementsZeroAbovePivot(ref output, new Coordinate(ri, 0), ref determinantFactor);
  102. }
  103. return output;
  104. }
  105. public Matrix Transpose()
  106. {
  107. Matrix transposed = new Matrix(Width, Heigth);
  108. for (int ci = 0; ci < Width; ci++)
  109. {
  110. var values = new List<double>();
  111.  
  112. for (int ri = 0; ri < Heigth; ri++)
  113. {
  114. values.Add(GetRow(ri).GetVal(ci));
  115. }
  116. transposed.AddRow(new MatrixRow(values.ToArray()));
  117. }
  118. return transposed;
  119. }
  120.  
  121.  
  122.  
  123. //Value Manipulation
  124. public double GetVal(int ri, int ci)
  125. {
  126. //Throw Exceptions accordingly.
  127. if (ri > (Heigth - 1))
  128. throw new RowIndexOutOfBounds(string.Format("ROW INDEX WAS OUT OF BOUNDS. GIVEN {0}, MATRIXHEIGHT {1}", ri, Heigth));
  129. if (ci > (Width - 1))
  130. throw new ColumnOutOfBoundsException(string.Format("COLUMN INDEX WAS OUT OF BOUNDS. GIVEN {0}, MATRIXHEIGHT {1}", ci, Width));
  131.  
  132. //Get the value from the row
  133. return this.GetRow(ri).GetVal(ci);
  134. }
  135. public double GetVal(Coordinate c)
  136. {
  137. //Throw Exceptions accordingly.
  138. if (c.Row > (Heigth - 1))
  139. throw new RowIndexOutOfBounds(string.Format("ROW INDEX WAS OUT OF BOUNDS. GIVEN {0}, MATRIXHEIGHT {1}", c.Row, Heigth));
  140. if (c.Column > (Width - 1))
  141. throw new ColumnOutOfBoundsException(string.Format("COLUMN INDEX WAS OUT OF BOUNDS. GIVEN {0}, MATRIXHEIGHT {1}", c.Column, Width));
  142.  
  143. //Get the value from the row
  144. return this.GetRow(c.Row).GetVal(c.Column);
  145. }
  146. public Matrix SetVal(int ri, int ci, double val)
  147. {
  148. if (ri > (Heigth - 1))
  149. throw new RowIndexOutOfBounds(string.Format("ROW INDEX WAS OUT OF BOUNDS. GIVEN {0}, MATRIXHEIGHT {1}", ri, Heigth));
  150. if (ci > (Width - 1))
  151. throw new ColumnOutOfBoundsException(string.Format("COLUMN INDEX WAS OUT OF BOUNDS. GIVEN {0}, MATRIXHEIGHT {1}", ci, Width));
  152. _matrix[ri].SetVal(ci, val);
  153. return this;
  154. }
  155.  
  156. //Public properties
  157. public int RowCount()
  158. {
  159. return _matrix.Count;
  160. }
  161. public int Width
  162. {
  163. get { return _width; }
  164. }
  165. public int Heigth
  166. {
  167. get { return _heigth; }
  168. set { _heigth = value; }
  169. }
  170.  
  171. //Row Manipulation
  172. public MatrixRow GetRow(int ri)
  173. {
  174. return _matrix[ri];
  175. }
  176. public void SetRow(int ri, MatrixRow row)
  177. {
  178. if (ri > (Heigth - 1))
  179. throw new RowIndexOutOfBounds(string.Format("ROW INDEX WAS OUT OF BOUNDS. GIVEN {0}, MATRIXHEIGHT {1}", ri, Heigth));
  180. if (row.Length() > Width)
  181. throw new FaultyRowSizeException(string.Format("ROW SIZE WRONG. ALLOWED: {0}, GIVEN: {1}", Width, row.Length()));
  182.  
  183. _matrix[ri] = row;
  184. }
  185.  
  186.  
  187. //Debug
  188. public void PrintMatrix()
  189. {
  190. Console.WriteLine("Matrix: " + Heigth + " x " + Width);
  191. foreach (var row in _matrix)
  192. {
  193. row.PrintRow();
  194. Console.WriteLine();
  195. }
  196. }
  197.  
  198. //Utilities
  199. private bool IsZeroColumn(int columnIndex)
  200. {
  201. bool foundNonZero = false;
  202. //Iterate through each row to find a non-zero alue
  203. foreach (MatrixRow r in _matrix)
  204. {
  205. if (!r.GetVal(columnIndex).Equals(0.0))
  206. {
  207. foundNonZero = true;
  208. break;
  209. }
  210.  
  211. }
  212. return !foundNonZero;
  213. }
  214. private void SetPivotOneAndOnTop(ref Matrix m, Coordinate coord, ref double determinantFactor)
  215. {
  216. //We will check each row on the corresponding column value
  217. for (int ri = coord.Row; ri < m.Heigth; ri++)
  218. {
  219. var currentRow = m.GetRow(ri);
  220. //If the value is non-zero make it one by scaling
  221. //break;
  222. if (!currentRow.GetVal(coord.Column).Equals(0.00))
  223. {
  224. m.SetRow(ri, currentRow.GetMultipliedInstance((1 / currentRow.GetVal(coord.Column))));
  225.  
  226. //We need to set this row to the first row
  227. m.SwapRows(coord.Row, ri);
  228. break;
  229. }
  230. }
  231. }
  232. private void SetElementsZeroBelowPivot(ref Matrix m, Coordinate pivotposition, ref double determinantFactor)
  233. {
  234. //Get the pivotrow and extract the pivotvalue
  235. var pivotRow = m.GetRow(pivotposition.Row);
  236. var pitvotValue = pivotRow.GetVal(pivotposition.Column);
  237.  
  238. //We will change each row below the pivotrow
  239. //We will substract the pivotrow divided by the value of the current row
  240. //This makes every value zero below the pivot
  241. if (!pitvotValue.Equals(0.00))
  242. {
  243. for (int ri = (pivotposition.Row + 1); ri < m.Heigth; ri++)
  244. {
  245. //Get the current row and determine the pivotvalue
  246. //So we can determine the factor we need to multiply the pivotrow to get an instance to substract
  247. var currentRow = m.GetRow(ri);
  248. var valueBelowPivot = currentRow.GetVal(pivotposition.Column);
  249.  
  250. var factor = valueBelowPivot / pitvotValue;
  251. m.SetRow(ri, currentRow.SubstractRow(pivotRow.GetMultipliedInstance(factor)));
  252. }
  253. }
  254. }
  255. private void SetElementsZeroAbovePivot(ref Matrix m, Coordinate pivotposition, ref double determinantFactor)
  256. {
  257. //Get the pivotrow and extract the pivotvalue
  258. //Get the pivotrow and extract the pivotvalue
  259. var pivotRow = m.GetRow(pivotposition.Row);
  260. var pivotValue = pivotRow.GetLeadingEntryValue();
  261. var pivotIndex = pivotRow.GetLeadingEntryIndex();
  262.  
  263.  
  264. if (!pivotValue.Equals(-1))
  265. {
  266. for (int ri = pivotposition.Row - 1; ri >= 0; ri--)
  267. {
  268. var pivotColVal = m.GetRow(ri).GetVal(pivotIndex);
  269. var factor = pivotColVal / pivotValue;
  270. m.SetRow(ri, m.GetRow(ri).SubstractRow(pivotRow.GetMultipliedInstance(factor)));
  271. }
  272. }
  273. }
  274. }
  275. }
Advertisement
Add Comment
Please, Sign In to add comment