private Matrix SquareMatrixInverse(Matrix argument) { int size = argument.Rows; Matrix original = argument.Clone(); Matrix inverse = new SimpleMatrix(size, size); for (int i = 0; i < size; i++) { inverse[i, i] = 1; } for (int i = 0; i < size; i++) { double reciprocal = 1 / original[i, i]; for (int k = 0; k < size; k++) { original[i, k] *= reciprocal; inverse[i, k] *= reciprocal; } for (int j = 0; j < size; j++) { if (i == j) { continue; } double quotient = original[j, i] / original[i, i]; for (int k = 0; k < size; k++) { original[j, k] = original[j, k] - quotient * original[i, k]; inverse[j, k] = inverse[j, k] - quotient * inverse[i, k]; } } } for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { if ((i == j && original[i, j] != 1) || (i != j && original[i, j] != 0)) { // no inverse found report error throw new Error.Domain(DomainErrorText); } } } return inverse; }
internal static Matrix MatrixFromAType(AType argument) { Matrix result = new SimpleMatrix(new double[argument.Shape[0], argument.Shape[1]]); for (int i = 0; i < argument.Shape[0]; i++) { for (int j = 0; j < argument.Shape[1]; j++) { result[i, j] = argument[i][j].asFloat; } } return result; }
public static Matrix operator *(Matrix matrix1, Matrix matrix2) { int rows = matrix1.Rows; int columns = matrix2.Columns; SimpleMatrix result = new SimpleMatrix(rows, columns); for (int i = 0; i < rows; i++) { for (int j = 0; j < columns; j++) { for (int k = 0; k < matrix1.Columns; k++) { result[i, j] += matrix1[i, k] * matrix2[k, j]; } } } return(result); }
public static Matrix operator *(Matrix matrix1, Matrix matrix2) { int rows = matrix1.Rows; int columns = matrix2.Columns; SimpleMatrix result = new SimpleMatrix(rows, columns); for (int i = 0; i < rows; i++) { for (int j = 0; j < columns; j++) { for (int k = 0; k < matrix1.Columns; k++) { result[i, j] += matrix1[i, k] * matrix2[k, j]; } } } return result; }
private AType SolveEquation(AType constants, AType equations) { AType lhs; AType rhs; if (constants.TryFirstScalar(out lhs, true) && equations.TryFirstScalar(out rhs, true)) { // both left and right values are one element arrays. return AFloat.Create(lhs.asFloat / rhs.asFloat); } Matrix constantsArray = new SimpleMatrix(ExtractConstants(constants)); Matrix originalEquations = new SimpleMatrix(FloatFromAType(equations)); int[] rowsSequence; Matrix eliminatedConstants; GaussianElimination(originalEquations, constantsArray, out rowsSequence, out eliminatedConstants); AType result = AArray.Create(ATypes.AFloat); if (equations.Shape[0] == equations.Shape[1]) { // square equation if (constants.Rank > 1) { foreach (int item in rowsSequence) { AType subArray = AArray.Create(ATypes.AFloat); for (int i = 0; i < eliminatedConstants.Columns; i++) { subArray.Add(AFloat.Create(eliminatedConstants[item, i])); } result.Add(subArray); } } else { foreach (int item in rowsSequence) { result.Add(AFloat.Create(eliminatedConstants[item, 0])); } } } else { double[][] independentConstants = BuildIndependentConstants(rowsSequence, eliminatedConstants); double[] beta; double[] actualconstants; if (constants.Rank == 1) { beta = independentConstants.Select(item => item[0]).ToArray(); actualconstants = constants.Select(item => item.asFloat).ToArray(); double[] solution = OverDeterminedEquationSolve(beta, actualconstants, originalEquations); foreach (double item in solution) { result.Add(AFloat.Create(item)); } } else { for (int objective = 0; objective < constants.Shape[1]; objective++) { beta = independentConstants.Select(item => item[objective]).ToArray(); actualconstants = constants.Select(item => item[objective].asFloat).ToArray(); double[] solution = OverDeterminedEquationSolve(beta, actualconstants, originalEquations); AType solutionArray = AArray.Create(ATypes.AFloat); foreach (double item in solution) { solutionArray.Add(AFloat.Create(item)); } result.Add(solutionArray); } } } return result; }