Stoffel

Matrix without new instance

Feb 8th, 2013
44
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.63 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.             var done = false;
  61.             var nonzerocoord = new Coordinate(0, 0);
  62.             while (!done)
  63.             {
  64.  
  65.                 //Step 1: Find the first non-zero column
  66.                 for (int ci = nonzerocoord.Column; ci < _width; ci++)
  67.                 {
  68.                     if (!IsZeroColumn(ci))
  69.                     {
  70.                         nonzerocoord.Column = ci;
  71.                         break;
  72.                     }
  73.                 }
  74.                 //Step 2: Find the pivot-value, make it one, and put it on top
  75.                 SetPivotOneAndOnTop(nonzerocoord);
  76.  
  77.                 //We have a pivot element, we need to make every element below the pivot zero.
  78.                 SetElementsZeroBelowPivot(nonzerocoord);
  79.  
  80.                 //We need to repeat these steps disregarding the previous pivot
  81.                 //We repeat with next column
  82.                 nonzerocoord.Column++;
  83.                 nonzerocoord.Row++;
  84.                 if (nonzerocoord.Column == _width || nonzerocoord.Row == _heigth)
  85.                     done = true;
  86.             }
  87.             //AT this point we are only in echelonform
  88.             //To get to row reduced echelonform we need to substract from the bottom up
  89.             for (int ri = 0; ri < _heigth; ri++)
  90.             {
  91.                 SetElementsZeroAbovePivot(new Coordinate(ri, 0));
  92.             }
  93.             return this;
  94.         }
  95.         public Matrix Transpose()
  96.         {
  97.             Matrix transposed = new Matrix(Width, Heigth);
  98.             for (int ci = 0; ci < Width; ci++)
  99.             {
  100.                 var values = new List<double>();
  101.  
  102.                 for (int ri = 0; ri < Heigth; ri++)
  103.                 {
  104.                     values.Add(GetRow(ri).GetVal(ci));
  105.                 }
  106.                 transposed.AddRow(new MatrixRow(values.ToArray()));
  107.             }
  108.             return transposed;
  109.         }
  110.  
  111.  
  112.  
  113.         //Value Manipulation
  114.         public double GetVal(int ri, int ci)
  115.         {
  116.             //Throw Exceptions accordingly.
  117.             if (ri > (Heigth - 1))
  118.                 throw new RowIndexOutOfBounds(string.Format("ROW INDEX WAS OUT OF BOUNDS. GIVEN {0}, MATRIXHEIGHT {1}", ri, Heigth));
  119.             if (ci > (Width - 1))
  120.                 throw new ColumnOutOfBoundsException(string.Format("COLUMN INDEX WAS OUT OF BOUNDS. GIVEN {0}, MATRIXHEIGHT {1}", ci, Width));
  121.  
  122.             //Get the value from the row
  123.             return this.GetRow(ri).GetVal(ci);
  124.         }
  125.         public double GetVal(Coordinate c)
  126.         {
  127.             //Throw Exceptions accordingly.
  128.             if (c.Row > (Heigth - 1))
  129.                 throw new RowIndexOutOfBounds(string.Format("ROW INDEX WAS OUT OF BOUNDS. GIVEN {0}, MATRIXHEIGHT {1}", c.Row, Heigth));
  130.             if (c.Column > (Width - 1))
  131.                 throw new ColumnOutOfBoundsException(string.Format("COLUMN INDEX WAS OUT OF BOUNDS. GIVEN {0}, MATRIXHEIGHT {1}", c.Column, Width));
  132.  
  133.             //Get the value from the row
  134.             return this.GetRow(c.Row).GetVal(c.Column);
  135.         }
  136.         public Matrix SetVal(int ri, int ci, double val)
  137.         {
  138.             if (ri > (Heigth - 1))
  139.                 throw new RowIndexOutOfBounds(string.Format("ROW INDEX WAS OUT OF BOUNDS. GIVEN {0}, MATRIXHEIGHT {1}", ri, Heigth));
  140.             if (ci > (Width - 1))
  141.                 throw new ColumnOutOfBoundsException(string.Format("COLUMN INDEX WAS OUT OF BOUNDS. GIVEN {0}, MATRIXHEIGHT {1}", ci, Width));
  142.             _matrix[ri].SetVal(ci, val);
  143.             return this;
  144.         }
  145.  
  146.         //Public properties
  147.         public int RowCount()
  148.         {
  149.             return _matrix.Count;
  150.         }
  151.         public int Width
  152.         {
  153.             get { return _width; }
  154.         }
  155.         public int Heigth
  156.         {
  157.             get { return _heigth; }
  158.             set { _heigth = value; }
  159.         }
  160.  
  161.         //Row Manipulation
  162.         public MatrixRow GetRow(int ri)
  163.         {
  164.             return _matrix[ri];
  165.         }
  166.         public void SetRow(int ri, MatrixRow row)
  167.         {
  168.             if (ri > (Heigth - 1))
  169.                 throw new RowIndexOutOfBounds(string.Format("ROW INDEX WAS OUT OF BOUNDS. GIVEN {0}, MATRIXHEIGHT {1}", ri, Heigth));
  170.             if (row.Length() > Width)
  171.                 throw new FaultyRowSizeException(string.Format("ROW SIZE WRONG. ALLOWED: {0}, GIVEN: {1}", Width, row.Length()));
  172.  
  173.             _matrix[ri] = row;
  174.         }
  175.  
  176.  
  177.         //Debug
  178.         public void PrintMatrix()
  179.         {
  180.             Console.WriteLine("Matrix: " + Heigth + " x " + Width);
  181.             foreach (var row in _matrix)
  182.             {
  183.                 row.PrintRow();
  184.                 Console.WriteLine();
  185.             }
  186.         }
  187.  
  188.         //Utilities
  189.         private bool IsZeroColumn(int columnIndex)
  190.         {
  191.             bool foundNonZero = false;
  192.             //Iterate through each row to find a non-zero alue
  193.             foreach (MatrixRow r in _matrix)
  194.             {
  195.                 if (!r.GetVal(columnIndex).Equals(0.0))
  196.                 {
  197.                     foundNonZero = true;
  198.                     break;
  199.                 }
  200.  
  201.             }
  202.             return !foundNonZero;
  203.         }
  204.         private void SetPivotOneAndOnTop(Coordinate coord)
  205.         {
  206.             //We will check each row on the corresponding column value
  207.             for (int ri = coord.Row; ri < _heigth; ri++)
  208.             {
  209.                 var currentRow = GetRow(ri);
  210.                 //If the value is non-zero make it one by scaling
  211.                 //break;
  212.                 if (!currentRow.GetVal(coord.Column).Equals(0.00))
  213.                 {
  214.                     SetRow(ri, currentRow.GetMultipliedInstance((1 / currentRow.GetVal(coord.Column))));
  215.  
  216.                     //We need to set this row to the first row
  217.                     SwapRows(coord.Row, ri);
  218.                     break;
  219.                 }
  220.             }
  221.         }
  222.         private void SetElementsZeroBelowPivot(Coordinate pivotposition)
  223.         {
  224.             //Get the pivotrow and extract the pivotvalue
  225.             var pivotRow = GetRow(pivotposition.Row);
  226.             var pitvotValue = pivotRow.GetVal(pivotposition.Column);
  227.  
  228.             //We will change each row below the pivotrow
  229.             //We will substract the pivotrow divided by the value of the current row
  230.             //This makes every value zero below the pivot
  231.             if (!pitvotValue.Equals(0.00))
  232.             {
  233.                 for (int ri = (pivotposition.Row + 1); ri < _heigth; ri++)
  234.                 {
  235.                     //Get the current row and determine the pivotvalue
  236.                     //So we can determine the factor we need to multiply the pivotrow to get an instance to substract
  237.                     var currentRow = GetRow(ri);
  238.                     var valueBelowPivot = currentRow.GetVal(pivotposition.Column);
  239.  
  240.                     var factor = valueBelowPivot / pitvotValue;
  241.                     SetRow(ri, currentRow.SubstractRow(pivotRow.GetMultipliedInstance(factor)));
  242.                 }
  243.             }
  244.         }
  245.         private void SetElementsZeroAbovePivot(Coordinate pivotposition)
  246.         {
  247.             //Get the pivotrow and extract the pivotvalue
  248.             //Get the pivotrow and extract the pivotvalue
  249.             var pivotRow = GetRow(pivotposition.Row);
  250.             var pivotValue = pivotRow.GetLeadingEntryValue();
  251.             var pivotIndex = pivotRow.GetLeadingEntryIndex();
  252.            
  253.  
  254.             if (!pivotValue.Equals(-1))
  255.             {
  256.                 for (int ri = pivotposition.Row - 1; ri >= 0; ri--)
  257.                 {
  258.                     var pivotColVal = GetRow(ri).GetVal(pivotIndex);
  259.                     var factor = pivotColVal / pivotValue;
  260.                     SetRow(ri, GetRow(ri).SubstractRow(pivotRow.GetMultipliedInstance(factor)));
  261.                 }
  262.             }
  263.         }
  264.     }
  265. }
Advertisement
Add Comment
Please, Sign In to add comment