private void WriteToStream(IIndexable2D matrix, StreamWriter writer) { string numberFormat = NumericFormat.GetRealNumberFormat(); writer.Write(ArrayFormat.ArrayStart); // First row writer.Write(ArrayFormat.RowSeparator + ArrayFormat.RowStart); writer.Write(string.Format(numberFormat, matrix[0, 0])); for (int j = 1; j < matrix.NumColumns; ++j) { writer.Write(ArrayFormat.ColSeparator + string.Format(numberFormat, matrix[0, j])); } // Subsequent rows for (int i = 1; i < matrix.NumRows; ++i) { writer.Write(ArrayFormat.RowSeparator + ArrayFormat.RowStart); writer.Write(string.Format(numberFormat, matrix[i, 0])); for (int j = 1; j < matrix.NumColumns; ++j) { writer.Write(ArrayFormat.ColSeparator + string.Format(numberFormat, matrix[i, j])); } } writer.Write(ArrayFormat.RowSeparator + ArrayFormat.ArrayEnd); }
public static void CheckMultiplicationDimensions(IIndexable2D matrix, IVectorView lhsVector, int lhsOffset, IVectorView rhsVector, int rhsOffset, bool transposeMatrix) { int m, n; if (transposeMatrix) { m = matrix.NumColumns; n = matrix.NumRows; } else { m = matrix.NumRows; n = matrix.NumColumns; } if (lhsVector.Length < lhsOffset + n) { throw new NonMatchingDimensionsException( "The left hand side vector's length must be at least as large as the offset plus the number of columns of the " + "matrix (or its transpose)."); } if (rhsVector.Length < rhsOffset + m) { throw new NonMatchingDimensionsException( "The left hand side vector's length must be at least as large as the offset plus the number of rows of the " + "matrix (or its transpose)."); } }
/// <summary> /// See <see cref="IIndexable2D.Equals(IIndexable2D, double)"/>. /// </summary> public bool Equals(IIndexable2D other, double tolerance = 1e-13) { if ((this.NumRows != other.NumRows) || (this.NumColumns != other.NumColumns)) { return(false); } var comparer = new ValueComparer(1e-13); for (int j = 0; j < NumColumns; ++j) { int colStart = colOffsets[j]; // Inclusive int colEnd = colOffsets[j + 1]; // Exclusive int previousRow = 0; for (int k = colStart; k < colEnd; ++k) { int row = rowIndices[k]; for (int i = previousRow; i < row; ++i) // Zero entries between the stored ones { if (!comparer.AreEqual(0.0, other[i, j])) { return(false); } } if (!comparer.AreEqual(values[k], other[row, j])) { return(false); // Non zero entry } previousRow = row + 1; } } return(true); // At this point all entries have been checked and are equal }
public static IIndexable2D <T> Rotate <T>(this IIndexable2D <T> source, int times) { if (times % 4 == 0) { return(source); } return(new RotatedIndexable2D <T>(source, times)); }
public static void CheckSquare(IIndexable2D matrix) { if (matrix.NumRows != matrix.NumColumns) { throw new NonMatchingDimensionsException( $"The matrix must be square, but was {matrix.NumRows}-by-{matrix.NumColumns}"); } }
public static void CheckIndexRow(IIndexable2D matrix, int rowIdx) { if ((rowIdx < 0) || (rowIdx >= matrix.NumRows)) { throw new IndexOutOfRangeException($"Cannot access row {rowIdx} in a" + $" {matrix.NumRows}-by-{matrix.NumColumns} matrix"); } }
/// <summary> /// Iterates over the non-zero entries of the matrix, which are defined as the entries such that: /// <paramref name="matrix"/>[i,j]. /// </summary> /// <param name="matrix">The matrix whose non-zero entries will be iterated over.</param> public static IEnumerable <(int row, int col, double val)> EnumerateNonZeros(this IIndexable2D matrix) { for (int j = 0; j < matrix.NumColumns; ++j) { for (int i = 0; i < matrix.NumRows; ++i) { if (matrix[i, j] != 0.0) { yield return(i, j, matrix[i, j]);
private static void TestWriteOperation(IIndexable2D matrix, string referenceFile, FullMatrixWriter writer) { string tempFile = Guid.NewGuid().ToString() + ".txt"; writer.WriteToFile(matrix, tempFile); bool success = IOUtilities.AreFilesEquivalent(referenceFile, tempFile); File.Delete(tempFile); Assert.True(success); }
public static IEnumerable <T> AsEnumerable <T>(this IIndexable2D <T> source) { for (int x = 0; x < source.Length0; x++) { for (int y = 0; y < source.Length1; y++) { yield return(source[x, y]); } } }
public static void CheckSameRowDimension(IIndexable2D matrix, IVectorView vector) { if (matrix.NumRows != vector.Length) { string message = string.Format( "Matrix has dimensions ({0}x{1}), while vector has dimensions ({2}x{1})", matrix.NumRows, matrix.NumColumns, vector.Length); throw new NonMatchingDimensionsException(message); } }
public static void CheckSystemSolutionDimensions(IIndexable2D matrix, IVectorView rhsVector) { if (matrix.NumRows != rhsVector.Length) { string message = string.Format( "Matrix has dimensions ({0}x{1}), while the right hand side vector has dimensions ({2}x1)", matrix.NumRows, matrix.NumColumns, rhsVector.Length); throw new NonMatchingDimensionsException(message); } }
public static Vector GetRow(IIndexable2D matrix, int rowIdx) { var row = new double[matrix.NumColumns]; for (int j = 0; j < matrix.NumColumns; ++j) { row[j] = matrix[rowIdx, j]; } return(Vector.CreateFromArray(row, false)); }
public static void CheckMultiplicationDimensions(IIndexable2D leftMatrix, IIndexable2D rightMatrix) { if (leftMatrix.NumColumns != rightMatrix.NumRows) { string message = string.Format( "Left matrix has dimensions ({0}x{1}), while right matrix has dimensions ({2}x{3})", leftMatrix.NumRows, leftMatrix.NumColumns, rightMatrix.NumRows, rightMatrix.NumColumns); throw new NonMatchingDimensionsException(message); } }
public static Vector GetColumn(IIndexable2D matrix, int colIdx) { var column = new double[matrix.NumRows]; for (int i = 0; i < matrix.NumRows; ++i) { column[i] = matrix[i, colIdx]; } return(Vector.CreateFromArray(column, false)); }
public static void CheckSameRowDimension(IIndexable2D matrix1, IIndexable2D matrix2) { if (matrix1.NumRows != matrix2.NumRows) { string message = string.Format( "Matrix1 has dimensions ({0}x{1}), while matrix2 has dimensions ({2}x{3})", matrix1.NumRows, matrix1.NumColumns, matrix2.NumRows, matrix2.NumColumns); throw new NonMatchingDimensionsException(message); } }
public static bool AreSameMatrixDimensions(IIndexable2D matrix1, IIndexable2D matrix2) { if ((matrix1.NumRows != matrix2.NumRows) || (matrix1.NumColumns != matrix2.NumColumns)) { return(false); } else { return(true); } }
public static double[,] CopyToArray2D(IIndexable2D matrix) { var result = new double[matrix.NumRows, matrix.NumColumns]; for (int j = 0; j < matrix.NumColumns; ++j) { for (int i = 0; i < matrix.NumRows; ++i) { result[i, j] = matrix[i, j]; } } return(result); }
public static Matrix GetSubmatrix(IIndexable2D matrix, int[] rowIndices, int[] colIndices) { var submatrix = Matrix.CreateZero(rowIndices.Length, colIndices.Length); for (int j = 0; j < colIndices.Length; ++j) { for (int i = 0; i < rowIndices.Length; ++i) { submatrix[i, j] = matrix[rowIndices[i], colIndices[j]]; } } return(submatrix); }
public SubIndexable2D(IIndexable2D <TValue> source, int x, int y, int length0, int length1) { if (source.Length0 < x + length0 || source.Length1 < y + length1) { throw new ArgumentOutOfRangeException(); } _source = source; _x = x; _y = y; Length0 = length0; Length1 = length1; }
private static int GetPatternCode(IIndexable2D <bool> block) { int value = 0; for (int i = 0; i < block.Length0; i++) { for (int j = 0; j < block.Length1; j++) { value = (value << 1) + (block[i, j] ? 1 : 0); } } return(value); }
public static T[,] To2DArray <T>(this IIndexable2D <T> source) { var array = new T[source.Length0, source.Length1]; for (int x = source.Length0 - 1; x >= 0; x--) { for (int y = source.Length1 - 1; y >= 0; y--) { array[x, y] = source[x, y]; } } return(array); }
public static Matrix LinearCombination(IIndexable2D matrix1, double coefficient1, IIndexable2D matrix2, double coefficient2) { Preconditions.CheckSameMatrixDimensions(matrix1, matrix2); var result = Matrix.CreateZero(matrix1.NumRows, matrix1.NumColumns); for (int j = 0; j < matrix1.NumColumns; ++j) { for (int i = 0; i < matrix1.NumRows; ++i) { result[i, j] = coefficient1 * matrix1[i, j] + coefficient2 * matrix2[i, j]; } } return(result); }
public static Matrix DoEntrywise(IIndexable2D matrix1, IIndexable2D matrix2, Func <double, double, double> binaryOperation) { Preconditions.CheckSameMatrixDimensions(matrix1, matrix2); var result = Matrix.CreateZero(matrix1.NumRows, matrix1.NumColumns); for (int j = 0; j < matrix1.NumColumns; ++j) { for (int i = 0; i < matrix1.NumRows; ++i) { result[i, j] = binaryOperation(matrix1[i, j], matrix2[i, j]); } } return(result); }
public static Matrix CopyToFullMatrix(IIndexable2D matrix) { int m = matrix.NumRows; int n = matrix.NumColumns; var result = new double[m * n]; for (int j = 0; j < n; ++j) { for (int i = 0; i < m; ++i) { result[m * j + i] = matrix[i, j]; } } return(Matrix.CreateFromArray(result, m, n, false)); }
public static Matrix GetSubmatrix(IIndexable2D matrix, int rowStartInclusive, int rowEndExclusive, int colStartInclusive, int colEndExclusive) { int numNewRows = rowEndExclusive - rowStartInclusive; int numNewCols = colEndExclusive - colStartInclusive; var submatrix = Matrix.CreateZero(numNewRows, numNewCols); for (int j = 0; j < numNewCols; ++j) { for (int i = 0; i < numNewRows; ++i) { submatrix[i, j] = matrix[rowStartInclusive + i, colStartInclusive + j]; } } return(submatrix); }
public static void CheckMultiplicationDimensionsSection(IIndexable2D matrixLeft, IVectorView vectorRight, int vectorStart, IVectorView result, int resultStart) { if (vectorStart + matrixLeft.NumColumns > vectorRight.Length) { throw new NonMatchingDimensionsException( $"The multiplied vector's length = {vectorRight.Length} must be at least as large as the start index =" + $" {vectorStart} + the matrix' columns = {matrixLeft.NumColumns}"); } if (vectorStart + matrixLeft.NumRows > result.Length) { throw new NonMatchingDimensionsException( $"The result vector's length = {result.Length} must be at least as large as the start index =" + $" {resultStart} + the matrix' rows = {matrixLeft.NumRows}"); } }
public SplittedIndexable2D(IIndexable2D <TValue> source, int size0, int size1) { if (source.Length0 % size0 != 0 || source.Length1 % size1 != 0) { throw new InvalidOperationException(); } _splitted = new IIndexable2D <TValue> [source.Length0 / size0, source.Length1 / size1]; for (int i = 0; i < source.Length0 / size0; i++) { for (int j = 0; j < source.Length1 / size1; j++) { _splitted[i, j] = new SubIndexable2D <TValue>(source, i * size0, j * size0, size0, size1); } } }
/// <summary> /// See <see cref="IIndexable2D.Equals(IIndexable2D, double)"/>. /// </summary> public bool Equals(IIndexable2D other, double tolerance = 1e-13) { var comparer = new ValueComparer(1e-13); if (other is Matrix2by2 casted) { return(comparer.AreEqual(this.data[0, 0], casted.data[0, 0]) && comparer.AreEqual(this.data[0, 1], casted.data[0, 1]) && comparer.AreEqual(this.data[1, 0], casted.data[1, 0]) && comparer.AreEqual(this.data[1, 1], casted.data[1, 1])); } else { return(comparer.AreEqual(this.data[0, 0], other[0, 0]) && comparer.AreEqual(this.data[0, 1], other[0, 1]) && comparer.AreEqual(this.data[1, 0], other[1, 0]) && comparer.AreEqual(this.data[1, 1], other[1, 1])); } }
public MergedIndexable2D(IIndexable2D <IIndexable2D <TValue> > source) { Length0 = 0; Length1 = 0; for (int i = 0; i < source.Length0; i++) { int rowHeight = 0; int currentRowLength = 0; for (int j = 0; j < source.Length1; j++) { IIndexable2D <TValue> block = source[i, j]; if (rowHeight == 0) { rowHeight = block.Length0; } currentRowLength += block.Length1; if (block.Length0 != rowHeight) { throw new FormatException("Variable block height in block row."); } } Length0 += rowHeight; if (Length1 == 0) { Length1 = currentRowLength; } if (currentRowLength != Length1) { throw new FormatException("Variable block length."); } } _blocks = source; }
public static bool AreEqual(IIndexable2D matrix1, IIndexable2D matrix2, double tolerance = 1e-13) { if ((matrix1.NumRows != matrix2.NumRows) || (matrix1.NumColumns != matrix2.NumColumns)) { return(false); } var comparer = new ValueComparer(tolerance); for (int j = 0; j < matrix1.NumColumns; ++j) { for (int i = 0; i < matrix1.NumRows; ++i) { if (!comparer.AreEqual(matrix1[i, j], matrix2[i, j])) { return(false); } } } return(true); }