Пример #1
0
        /// <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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        /// 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);
        }
Пример #4
0
 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;
     }
 }
Пример #5
0
        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);
        }
Пример #6
0
        /// <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);
        }
Пример #7
0
 public Matrix(MatrixDimension dimension)
 => Dimension = dimension;
Пример #8
0
 public Matrix(int rowCount, int columnCount)
 {
     Dimension = new MatrixDimension(rowCount, columnCount);
     _matrix   = new double[rowCount, columnCount];
 }
Пример #9
0
 public Matrix(MatrixDimension dimension)
 {
     Dimension = dimension;
     _matrix   = new double[dimension.rowCount, dimension.columnCount];
 }
Пример #10
0
 public Matrix(double[,] matrix)
 {
     _matrix   = matrix;
     Dimension = new MatrixDimension(matrix.GetLength(0), matrix.GetLength(1));
 }
Пример #11
0
        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);
        }