/// <summary> /// Multiplies two maricies together /// </summary> /// <param name="A"></param> /// <param name="B"></param> /// <returns>The product of the matrices</returns> public static Matrix Multiply(this Matrix A, Matrix B) { var matrix = new Matrix(A.Rows, B.Columns); for (int i = 0; i < A.Rows; i++) { for (int j = 0; j < B.Columns; j++) { matrix[i, j] = DotProduct(A.GetRow(i), B.GetColumn(j)); } } /* * for (int i = 0; i < A.Rows; i++) * { * for (int k = 0; k < A.Columns; k++) * { * for (int j = 0; j < B.Columns; j++) * { * array[i * A.Columns + j] += A.internalArray[i * A.Columns + k] * B.internalArray[k * B.Columns + j]; * } * } * } */ return(matrix); }
public static Matrix MultiplyMatrices(Matrix matrix1, Matrix matrix2) { int matrix1ColumnsCount = matrix1.GetColumnsCount(); int matrix2RowsCount = matrix2.GetRowsCount(); if (matrix1ColumnsCount != matrix2RowsCount) { throw new ArgumentException($"Матрицы {nameof(matrix1)} и {nameof(matrix2)} не согласованы.", nameof(matrix2)); } int matrix1RowsCount = matrix1.GetRowsCount(); int matrix2ColumnsCount = matrix2.GetColumnsCount(); Matrix newMatrix = new Matrix(matrix2ColumnsCount, matrix1RowsCount); for (int i = 0; i < matrix1RowsCount; i++) { for (int j = 0; j < matrix2ColumnsCount; j++) { newMatrix.rows[i].SetComponent(j, Vector.MultiplyVectors(matrix1.rows[i], matrix2.GetColumn(j))); } } return(newMatrix); }
static void Main(string[] args) { Matrix matrix1 = new Matrix(5, 7); Matrix matrix2 = new Matrix(matrix1); Matrix matrix3 = new Matrix(new double[, ] { { 5, 6 }, { 3, 2 }, { 5, 6 } }); Matrix matrix4 = new Matrix(new Vector[] { new Vector(new double[] { 5.6, 6.4 }), new Vector(new double[] { 3.7, 6.5, 7.8 }) }); Matrix matrix5 = new Matrix(matrix4); Console.WriteLine("Размер матрицы {0} = {1} на {2}", matrix1, matrix1.GetColumnsCount(), matrix1.GetRowsCount()); Console.WriteLine(); Console.WriteLine("Размер матрицы {0} = {1} на {2}", matrix2, matrix2.GetColumnsCount(), matrix2.GetRowsCount()); Console.WriteLine(); Console.WriteLine("Размер матрицы {0} = {1} на {2}", matrix3, matrix3.GetColumnsCount(), matrix3.GetRowsCount()); Console.WriteLine(); Console.WriteLine("Размер матрицы {0} = {1} на {2}", matrix4, matrix4.GetColumnsCount(), matrix4.GetRowsCount()); Console.WriteLine(); Console.WriteLine(); int index = 1; Console.WriteLine("Горизонтальный вектор номер {0} = {1}", index, matrix3.GetRow(index)); Console.WriteLine(); matrix3.SetRow(1, new Vector(new double[] { 2, 3 })); Console.WriteLine("Теперь горизонтальный вектор номер {0} = {1}", index, matrix3.GetRow(index)); Console.WriteLine(); Console.WriteLine("Вертикальный вектор номер {0} = {1}", index, matrix3.GetColumn(index)); Console.WriteLine(); Console.WriteLine(); Console.Write("Результат транспонирования матрицы {0} = ", matrix4); matrix4.Transpose(); Console.WriteLine(matrix4); Console.WriteLine(); Console.Write("Результат умножения матрицы {0} на 10 = ", matrix3); matrix3.MultiplyByScalar(10); Console.WriteLine(matrix3); Console.WriteLine(); Matrix matrix6 = new Matrix(new double[, ] { { 5, 6 }, { 3, 2 } }); Console.WriteLine("Определитель матрицы {0} = {1}", matrix6, matrix6.GetDeterminant()); Console.WriteLine(); Vector vector = new Vector(new double[] { -1, -10 }); Console.Write("Результат умножения матрицы {0} на вектор {1} = {2}", matrix3, vector, matrix3.MultiplyByVector(vector)); Console.WriteLine(); Console.Write("Результат сложения матриц {0} и {1} = ", matrix3, matrix4); matrix3.AddMatrix(matrix4); Console.WriteLine(matrix3); Console.WriteLine(); Console.Write("Разность матриц {0} и {1} = ", matrix3, matrix4); matrix3.SubtractMatrix(matrix4); Console.WriteLine(matrix3); Console.WriteLine(); Console.WriteLine("Результат сложения матриц {0} и {1} = {2}", matrix4, matrix3, Matrix.AddMatrices(matrix4, matrix3)); Console.WriteLine(); Console.WriteLine("Разность матриц {0} и {1} = {2}", matrix4, matrix3, Matrix.SubtractMatrices(matrix4, matrix3)); Console.WriteLine(); Console.WriteLine("Результат умножения матриц {0} и {1} = {2}", matrix6, matrix5, Matrix.MultiplyMatrices(matrix6, matrix5)); Console.ReadKey(); }
/// <summary> /// Performs gaussian elimination on the given matrix. /// </summary> /// <param name="matrix"></param> /// <returns></returns> public static Matrix GaussianElimination(Matrix matrix) { // Derived from ref [1] Theorem 3.5 // identify the row with the first non zero element int nonZeroRowIndex = 0; bool run = true; int nonZeroColumnIndex = 0; while (run && nonZeroColumnIndex < matrix.Columns) { // Check if columns has non-zero entry var col = matrix.GetColumn(nonZeroColumnIndex); for (int j = 0; j < col.Length; j++) { if (Math.Abs(col[j]) > TOLERANCE) { nonZeroRowIndex = j; run = false; break; } } if (run) { nonZeroColumnIndex++; } } // Move this row into the top position if (nonZeroRowIndex != 0) { matrix = SwapRows(matrix, nonZeroRowIndex, 0); } // If the first non zero row does not equal 1 then normalize the if (Math.Abs(matrix[0, nonZeroColumnIndex] - 1.0) > TOLERANCE) { matrix = MultiplyRowByScalar(matrix, 0, 1.0 / matrix[0, nonZeroColumnIndex]); } int iMax = Math.Min(matrix.Columns, matrix.Rows); // Zero-wise columns for (int i = 0, currentCol = 0; i < iMax && currentCol < matrix.Columns; i++, currentCol++) { var currentStartElement = matrix[i, currentCol]; if (Math.Abs(currentStartElement) > TOLERANCE) { for (int j = i + 1; j < iMax; j++) { var modifiedRow = matrix.GetRow(i) .Select(m => - 1 * m * (matrix[j, currentCol] / currentStartElement)) .ToArray(); matrix = AddRows(matrix, modifiedRow, j); } } else { i--; // The test element was zero, do not increment the row } } return(matrix); }