数学:《线性代数》矩阵初等行变换及其应用(线性方程求解)
背景
高斯小朋友确实聪明,发明了高斯消元法,进而引入了线性代数,本文给出矩阵的初等行变换代码实现及其应用(线性方程求解)。
实现
代码
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace DataStuctureStudy.Matrixes 8 { 9 class MatrixTest 10 { 11 public static void Test() 12 { 13 var matrix = 14 new Matrix(3, 4) 15 .SetRowData(0, 1, 2, 3, 2) 16 .SetRowData(1, 1, 2, 7, 5) 17 .SetRowData(2, 4, 9, 2, 6); 18 19 matrix.Dispaly(); 20 21 matrix.Simplify().Dispaly(); 22 } 23 class Matrix 24 { 25 private readonly int _m; 26 private readonly int _n; 27 private readonly double[][] _data; 28 29 public Matrix(int m, int n) 30 { 31 _m = m; 32 _n = n; 33 _data = new double[m][]; 34 for (var i = 0; i < m; i++) 35 { 36 _data[i] = new double[n]; 37 } 38 } 39 40 public Matrix SetRowData(int row, params double[] values) 41 { 42 Array.Copy(values, _data[row], _n); 43 44 return this; 45 } 46 47 public Matrix SwapRow(int rowX, int rowY) 48 { 49 var temp = _data[rowX]; 50 _data[rowX] = _data[rowY]; 51 _data[rowY] = temp; 52 53 return this; 54 } 55 56 public Matrix MultiplyRow(int row, double operand) 57 { 58 for (var i = 0; i < _n; i++) 59 { 60 _data[row][i] *= operand; 61 } 62 63 return this; 64 } 65 66 public Matrix AddSourceRowToTargetRow(int sourceRow, double operand, int targetRow) 67 { 68 for (var i = 0; i < _n; i++) 69 { 70 _data[targetRow][i] += _data[sourceRow][i] * operand; 71 } 72 73 return this; 74 } 75 76 public Matrix Simplify() 77 { 78 for (var col = 0; col < _n; col++) 79 { 80 if (col >= _m) 81 { 82 break; 83 } 84 85 if (_data[col][col] == 0) 86 { 87 var nonZeroRowIndex = this.FindNonZeroRowIndex(col, col + 1); 88 if (nonZeroRowIndex == -1) 89 { 90 break; 91 } 92 this.SwapRow(col, nonZeroRowIndex); 93 } 94 95 this.MultiplyRow(col, 1 / _data[col][col]); 96 97 for (var row = 0; row < _m; row++) 98 { 99 if (row == col) 100 { 101 continue; 102 } 103 this.AddSourceRowToTargetRow(col, -1 * _data[row][col], row); 104 } 105 } 106 107 return this; 108 } 109 110 public int FindNonZeroRowIndex(int col, int startRow) 111 { 112 if (startRow >= _m) 113 { 114 return -1; 115 } 116 117 for (var i = startRow; i < _m; i++) 118 { 119 if (_data[i][col] != 0) 120 { 121 return i; 122 } 123 } 124 125 return -1; 126 } 127 128 public void Dispaly() 129 { 130 Console.WriteLine(); 131 foreach (var row in _data) 132 { 133 Console.WriteLine("[ " + String.Join(" , ", row) + " ]"); 134 } 135 Console.WriteLine(); 136 } 137 } 138 } 139 }
输出结果