public static MatrixX CombineColumns(List <MatrixX> spaces) { int width = 0; foreach (var space in spaces) { width += space.Width; } MatrixX matrix = new MatrixX(width, spaces[0].Height); for (int i = 0; i < width; i++) { foreach (var space in spaces) { for (int j = 0; j < space.Width; j++) { for (int k = 0; k < space.Height; k++) { matrix[i, k] = space[j, k]; } i++; } } } return(matrix); }
MatrixX GetMinorsMatrixX() { DateTime t0 = DateTime.Now; MatrixX minorsMatrixX = new MatrixX(Width, Height); MatrixX minorMatrixX = new MatrixX(Width - 1, Height - 1); int numerator = Width * Height; byte size = (byte)numerator.ToString().Length; for (int i = 0; i < Width; i++) { for (int j = 0; j < Height; j++) { if (j + i != 0) { DateTime t = DateTime.Now; TimeSpan dt = t - t0; double ratio = numerator / (i * Width + j + 0d); Console.WriteLine("Get Minors Matrix: {0}/{1} = {2}% Complete. ETA: {3}", (i * Width + j).ToString().PadLeft(size), numerator, Math.Round(100 / ratio, 4).ToString().PadRight(8) , t0.Add(TimeSpan.FromMilliseconds(dt.TotalMilliseconds * ratio))); } GetMinor(i, j, ref minorMatrixX); minorsMatrixX[i, j] = minorMatrixX.Determinant(); } } Console.WriteLine("Ending time: {0}", DateTime.Now); return(minorsMatrixX); }
void GetMinor(int i, int j, ref MatrixX destination) { int k = 0; for (; k < i; k++) { int h = 0; for (; h < j; h++) { destination[k, h] = Elements[k, h]; } h++; for (; h < Height; h++) { destination[k, h - 1] = Elements[k, h]; } } k++; for (; k < Width; k++) { int h = 0; for (; h < j; h++) { destination[k - 1, h] = Elements[k, h]; } h++; for (; h < Height; h++) { destination[k - 1, h - 1] = Elements[k, h]; } } }
//private methods MatrixX GetMinor(int i, int j) { MatrixX m = new MatrixX(Width - 1, Height - 1); GetMinor(i, j, ref m); return(m); }
public static MatrixX operator *(IntX a, MatrixX b) { MatrixX product = new MatrixX(b.Width, b.Height); for (int i = 0; i < product.Width; i++) { for (int j = 0; j < product.Height; j++) { product[i, j] = a * b[i, j]; } } return(product); }
//MatrixX RowReducedEchelonForm() //{ // var copy = Copy(); // int row = 0; // for (int column = 0; column < Width; column++) // { // //finding canidate row // var r = row; // for (; r < Height; r++) // if (copy[r, column] != 0) // break; // //moving canidate row to proper row location // //and dividing out magnitude // if (r == Height) // continue; // var mlt = 1 / copy[r, column]; // for (int j = column; j < Width; j++) // { // var swap = copy[r, j]; // copy[r, j] = copy[row, j]; // copy[row, j] = swap * mlt; // } // //Normalizing Column // for (int i = 0; i < Height; i++) // { // var m = copy[i, column]; // for (int j = column; j < Width; j++) // { // copy[j, i] -= m * copy[row, j]; // } // } // row++; // if (row == Height) // break; // } // return copy; //} //FractionX[] FindEigenValues() //{ // var poly = FindCharacteristicPolynomial(); // return poly.FindAllRoots(); //} //MatrixX GetEigenSpace(FractionX eigenValue, int dimensions) //{ // MatrixX m = (this - eigenValue * DiagonalMatrixX.IdentityMatrixX(Width)); // m = m.RowReducedEchelonForm(); // MatrixX eigenSpace = new MatrixX(dimensions, Height); // int basis = 0; // for (int i = 0; i + basis < Width; i++) // { // if (m[i + basis, i] != 1) // { // int j = 0; // for (; j < i + basis; j++) // eigenSpace[i, j] = -m[i, j]; // eigenSpace[i, j++] = (FractionX)1; // for (; j < Height; j++) // eigenSpace[i, j] = -m[i, j]; // basis++; // } // } // return eigenSpace; //} //Vector[] GetColumns() //{ // Vector[] columns = new Vector[Width]; // for (int i = 0; i < Width; i++) // { // FractionX[] elements = new FractionX[Height]; // for (int j = 0; j < Height; j++) // elements[j] = this[i, j]; // columns[i] = new Vector(elements); // } // return columns; //} //MatrixX GramSchmit() //{ // Vector[] vectors = GetColumns(); // Vector[] normalized = new Vector[vectors.Length - 1]; // for (int i = 0; i < vectors.Length; i++) // { // for (int j = 0; j < i; j++) // vectors[i] -= normalized[j] * vectors[i] * normalized[j]; // if (i < normalized.Length) // normalized[i] = vectors[i].Normalize(); // } // return CombineColumns(vectors); //} //public void Diagonalize(out MatrixX basis, out DiagonalMatrixX diagonal) //{ // var eigenValues = FindEigenValues(); // var l = eigenValues.ToList(); // l.Sort((FractionX a, FractionX b) => { return a.Real < b.Real ? 1 : 0; }); // eigenValues = l.ToArray(); // int m = 0; // List<MatrixX> spaces = new List<MatrixX>(); // for (int i = 0; i < eigenValues.Length; i += m) // { // m = 1;//multiplicity // while (i + m < eigenValues.Length && eigenValues[i] == eigenValues[i + m]) // m++; // //finding eigen space // var space = GetEigenSpace(eigenValues[i], m); // //using Gram Schmit to orthogonalize stuff. // space.GramSchmit(); // spaces.Add(space); // } // basis = CombineColumns(spaces); // diagonal = new DiagonalMatrixX(eigenValues); //} MatrixX Copy() { MatrixX matrix = new MatrixX(Width, Height); for (int i = 0; i < matrix.Width; i++) { for (int j = 0; j < matrix.Height; j++) { matrix[i, j] = this[i, j]; } } return(matrix); }
public MatrixX Transpose() { MatrixX m = new MatrixX(Width, Height); for (int i = 0; i < Width; i++) { for (int j = 0; j < Height; j++) { m[i, j] = this[j, i]; } } return(m); }
//public static MatrixX CombineColumns(Vector[] columns) //{ // MatrixX matrix = new MatrixX(columns.Length, columns[0].Dimensions); // for (int i = 0; i < matrix.Width; i++) // for (int j = 0; j < matrix.Height; j++) // matrix[i, j] = columns[i][j]; // return matrix; //} //public methods /// <summary> /// /// </summary> /// <returns>Inverse matrix if invertable, else returns NULL</returns> public MatrixX GetAdjointMatrix() { MatrixX adjointMatrix = GetMinorsMatrixX(); for (int i = 0; i < adjointMatrix.Width; i++) { for (int j = 0; j < adjointMatrix.Height; j++) { if ((i + j) % 2 == 1) { adjointMatrix[i, j] = -adjointMatrix[i, j]; } } } adjointMatrix = adjointMatrix.Transpose(); return(adjointMatrix); }
//public MatrixX Pow(FractionX exp) => Pow(this, exp); //public static MatrixX Pow(MatrixX a, FractionX exp) //{ // a.Diagonalize(out MatrixX s, out DiagonalMatrixX b); // var s1 = s.Invert(); // return s * DiagonalMatrixX.Pow(b, exp) * s1; //} //Operators public static MatrixX operator *(MatrixX a, MatrixX b) { if (a.Width != b.Height) { return(null); } MatrixX product = new MatrixX(a.Height, b.Width); for (int i = 0; i < product.Width; i++) { for (int j = 0; j < product.Height; j++) { product[i, j] = 0; for (int h = 0; h < a.Width; h++) { product[i, j] += a[h, i] * b[j, h]; } } } return(product); }
public static PolynomialX Generate(IntX[] input, IntX[] output) { if (input.Length != output.Length) { return(null); } MatrixX A = new MatrixX(input.Length, input.Length); MatrixX column = new MatrixX(1, input.Length); for (int i = 0; i < input.Length; i++) { IntX prod = 1; for (int j = 0; j < input.Length; j++) { A[j, i] = prod; prod *= input[i]; } column[0, i] = output[i]; } var det = A.Determinant(); if (det == 0) { return(null); } var adjoint = A.GetAdjointMatrix(); PolynomialX poly = new PolynomialX(input.Length); var result = adjoint * column; for (int i = 0; i < input.Length; i++) { poly.Coefficients[i] = (FractionX)result[i, 0] / det; } return(poly); }