/// <summary> /// Joins two Matrix instances together. /// </summary> /// <param name="m1">The first Matrix to join.</param> /// <param name="m2">The second Matrix to join to the first.</param> /// <param name="dimension">Determines whether the second Matrix should be /// joined to this one by adding rows, columns, or automatically determine /// the most suitable dimension.</param> /// <returns>A Matrix that consists of both input Matrix instances joined /// into one single Matrix.</returns> /// <exception cref="InvalidMatrixDimensionsException">Thrown when the /// two Matrix instances don't share the correct number of elements along /// the specified dimension.</exception> public Matrix Join(Matrix m1, Matrix m2, MatrixDimension dimension) { Matrix result = null; switch (dimension) { case MatrixDimension.Columns: if (m1.Rows != m2.Rows) { throw new InvalidMatrixDimensionsException("Matrix instances cannot be joined as they don't have the same number of rows."); } result = new Matrix(m1.Rows, m1.Columns + m2.Columns); int index = 0, indexM1 = 0, indexM2 = 0; for (int row = 0; row < m1.Rows; row++) { for (int column = 0; column < m1.Columns; column++) { result[index++] = m1[indexM1++]; } for (int column = 0; column < m2.Columns; column++) { result[index++] = m2[indexM2++]; } } break; case MatrixDimension.Rows: if (m1.Columns != m2.Columns) { throw new InvalidMatrixDimensionsException("Matrix instances cannot be joined as they don't have the same number of columns."); } result = new Matrix(m1.Rows + m2.Rows, m1.Columns); for (int i = 0; i < m1.Size; i++) { result[i] = m1[i]; } for (int i = 0; i < m2.Size; i++) { result[i + m1.Size] = m2[i]; } break; case MatrixDimension.Auto: if (m1.Rows == m2.Rows) { goto case MatrixDimension.Columns; } else { goto case MatrixDimension.Rows; } default: break; } return(result); }
public Matrix(double[] vector) { _matrix = new double[vector.Length, 1]; for (int i = 0; i < vector.Length; i++) { _matrix[i, 0] = vector[i]; } Dimension = new MatrixDimension(vector.Length, 1); }
/// Run a given operation on all elements in a particular dimension to reduce that dimension /// to a single row or column. /// </summary> /// <param name="m">The Matrix to operate on.</param> /// <param name="dimension">Indicate whether to operate on rows or columns.</param> /// <param name="op">The delegate method to operate with.</param> /// <returns>A Matrix populated with the results of performing the given operation.</returns> /// <remarks>If the current Matrix is a row or column vector, then a 1*1 Matrix /// will be returned, regardless of which dimension is chosen. If the dimension is /// set to 'Auto', then the first non-singleton dimension is chosen. If no singleton /// dimension exists, then columns are used as the default.</remarks> public Matrix ReduceDimension(Matrix m, MatrixDimension dimension, Func <double, double, double> op) { Matrix result = null; // Process calculations switch (dimension) { case MatrixDimension.Auto: // Inspired by Octave, 'Auto' will process the first non-singleton dimension. if (m.Rows == 1 || m.Columns == 1) { result = new Matrix(1, 1); for (int i = 0; i < m.Size; i++) { result[0] = op(result[0], m[i]); } return(result); } else { // No singleton case? Let's go with columns. goto case MatrixDimension.Columns; } case MatrixDimension.Columns: result = new Matrix(1, m.Columns); for (int i = 0; i < m.Size; i += m.Columns) { for (int j = 0; j < m.Columns; j++) { result[j] = op(result[j], m[i + j]); } } break; case MatrixDimension.Rows: result = new Matrix(m.Rows, 1); int index = 0; for (int i = 0; i < m.Rows; i++) { for (int j = 0; j < m.Columns; j++) { result[i] = op(result[i], m[index++]); } } break; default: break; } return(result); }
public MatrixDriver(ShiftRegister reg, MatrixDimension mat, int segments) { Register = reg; MatrixDim = mat; MatrixLength = segments*8; switch(MatrixDim){ case MatrixDimension.MatrixRow: map = new int[8 * (MatrixLength)]; // 4 segments in a row break; case MatrixDimension.MatrixBlock: map = new int[MatrixLength * MatrixLength]; break; } }
public void Transpose() { double[,] newMatrix = new double[Dimension.columnCount, Dimension.rowCount]; for (int i = 0; i < Dimension.columnCount; i++) { for (int j = i; j < Dimension.rowCount; j++) { newMatrix[i, j] = _matrix[j, i]; } } _matrix = newMatrix; Dimension = new MatrixDimension(Dimension.columnCount, Dimension.rowCount); }
/// <summary> /// Run a set of operations on all elements in a particular dimension to reduce that dimension /// to a single row, and then perform an aggregate operation to produce a statistical result. /// </summary> /// <param name="m">The Matrix to operate on.</param> /// <param name="dimension">Indicate whether to operate on rows or columns.</param> /// <param name="operation">The delegate method to operate with.</param> /// <remarks>If the current Matrix is a row or column vector, then a 1*1 Matrix /// will be returned, regardless of which dimension is chosen. If the dimension is /// set to 'Auto', then the first non-singleton dimension is chosen. If no singleton /// dimension exists, then columns are used as the default.</remarks> public Matrix StatisticalReduce(Matrix m, MatrixDimension dimension, Func <Matrix, double> op) { Matrix result = null; switch (dimension) { case MatrixDimension.Auto: if (m.Rows == 1) { result = new Matrix(1, 1); result[0] = op(m); return(result); } else if (m.Columns == 1) { result = new Matrix(1, 1); result[0] = op(m); return(result); } else { // No singleton case? Let's go with columns. goto case MatrixDimension.Columns; } case MatrixDimension.Columns: result = new Matrix(1, m.Columns); for (int i = 0; i < m.Columns; i++) { result[i] = op(Matrix.ExtractColumns(m, i, 1)); } break; case MatrixDimension.Rows: result = new Matrix(m.Rows, 1); for (int i = 0; i < m.Rows; i++) { result[i] = op(Matrix.ExtractRows(m, i, 1)); } break; default: break; } return(result); }
public Matrix(MatrixDimension dimension) => Dimension = dimension;
public Matrix(int rowCount, int columnCount) { Dimension = new MatrixDimension(rowCount, columnCount); _matrix = new double[rowCount, columnCount]; }
public Matrix(MatrixDimension dimension) { Dimension = dimension; _matrix = new double[dimension.rowCount, dimension.columnCount]; }
public Matrix(double[,] matrix) { _matrix = matrix; Dimension = new MatrixDimension(matrix.GetLength(0), matrix.GetLength(1)); }
public static T[,] Concat <T>([CanBeNull] this T[,] mat, [CanBeNull] T[,] another, MatrixDimension dim) { if (mat == null || mat.Length == 0) { return(another ?? EmptyMatrix <T> .Instance); } if (another == null || another.Length == 0) { return(mat); } if (dim != MatrixDimension.Row && dim != MatrixDimension.Col) { throw new ArgumentException($"Illegal dim: {dim}"); } var concatDim = dim == MatrixDimension.Row ? MatrixDimension.Col : MatrixDimension.Row; var keptDim = dim; var keptDimLength = mat.GetLength((int)keptDim); if (keptDimLength != another.GetLength((int)keptDim)) { throw new ArgumentException("Dimensions of matrices being concatenated are not consistent, " + $"m1: {mat.GetLength(0)}x{mat.GetLength(1)}, m2: {another.GetLength(0)}x{another.GetLength(1)}, " + $"dim: {dim}"); } var m1DimLength = mat.GetLength((int)concatDim); var concatDimLength = m1DimLength + another.GetLength((int)concatDim); var dimLengths = new int[2]; dimLengths[(int)concatDim] = concatDimLength; dimLengths[(int)keptDim] = keptDimLength; var row = dimLengths[0]; var col = dimLengths[1]; var matrix = new T[row, col]; Func <int, int, T> getFunc; if (concatDim == MatrixDimension.Row) { getFunc = (r, c) => r >= m1DimLength ? another[r - m1DimLength, c] : mat[r, c]; } else { getFunc = (r, c) => c >= m1DimLength ? another[r, c - m1DimLength] : mat[r, c]; } for (var r = 0; r < dimLengths[0]; r++) { for (var c = 0; c < dimLengths[1]; c++) { matrix[r, c] = getFunc(r, c); } } return(matrix); }