/// <summary>
        ///   Gets the transpose of a matrix.
        /// </summary>
        ///
        /// <param name="matrix">A matrix.</param>
        ///
        /// <returns>The transpose of the given matrix.</returns>
        ///
        public static TItem[][] Transpose <TCollection, TItem>(this TCollection matrix)
            where TCollection : ICollection, IEnumerable <TItem[]>
        {
            int rows = matrix.Count;

            if (rows == 0)
            {
                return(new TItem[rows][]);
            }
            int cols = matrix.Columns();

#if CHECKS
            if (!IsRectangular(matrix))
            {
                throw new ArgumentException("Only rectangular matrices can be transposed.");
            }
#endif
            TItem[][] result = Jagged.Zeros <TItem>(cols, rows);

            int i = 0;
            foreach (TItem[] row in matrix)
            {
                for (int j = 0; j < result.Length; j++)
                {
                    result[j][i] = row[j];
                }
                i++;
            }

            return(result);
        }
示例#2
0
        /// <summary>
        ///   Removes dimensions of length 1 from the array.
        /// </summary>
        ///
        /// <param name="array">The array.</param>
        ///
        public static Array Squeeze(this Array array)
        {
            int[] dimensions = array.GetLength().Where(x => x != 1).ToArray();
            if (dimensions.Length == 0)
            {
                dimensions = new[] { 1 }
            }
            ;

            Array res;

            if (array.IsJagged())
            {
#if NETSTANDARD1_4
                throw new NotSupportedException("Squeeze with jagged arrays is not supported in .NET Standard 1.4.");
#else
                res = Jagged.Zeros(array.GetInnerMostType(), dimensions);
                Copy(array, res);
#endif
            }
            else
            {
                res = Matrix.Zeros(array.GetInnerMostType(), dimensions);
                Buffer.BlockCopy(array, 0, res, 0, res.GetNumberOfBytes());
            }

            return(res);
        }
        /// <summary>
        ///   Calculates the scatter matrix of a sample matrix.
        /// </summary>
        /// 
        /// <remarks>
        ///   By dividing the Scatter matrix by the sample size, we get the population
        ///   Covariance matrix. By dividing by the sample size minus one, we get the
        ///   sample Covariance matrix.
        /// </remarks>
        /// 
        /// <param name="matrix">A number multi-dimensional array containing the matrix values.</param>
        /// <param name="means">The mean value of the given values, if already known.</param>
        /// <param name="divisor">A real number to divide each member of the matrix.</param>
        /// <param name="dimension">
        ///   Pass 0 if the mean vector is a row vector, 1 otherwise. Default value is 0.
        /// </param>
        /// 
        /// <returns>The covariance matrix.</returns>
        /// 
        public static float[][] Scatter(this float[][] matrix, int dimension, float[] means)
        {
            int rows = matrix.Rows();
            int cols = matrix.Columns();

            float[][] cov;

            if (dimension == 0)
            {
                if (means.Length != cols)
                    throw new ArgumentException("Length of the mean vector should equal the number of columns", "means");

                cov = Jagged.Zeros<float>(cols, cols);
                for (int i = 0; i < cols; i++)
                {
                    for (int j = i; j < cols; j++)
                    {
                        float s = 0;
                        for (int k = 0; k < rows; k++)
                        {
                            var v = matrix[k][j] - means[j];
                            s += v * v;
                        }
                        cov[i][j] = s;
                        cov[j][i] = s;
                    }
                }
            }
            else if (dimension == 1)
            {
                if (means.Length != rows) 
                    throw new ArgumentException("Length of the mean vector should equal the number of rows", "means");

                cov = Jagged.Zeros<float>(rows, rows);
                for (int i = 0; i < rows; i++)
                {
                    for (int j = i; j < rows; j++)
                    {
                        float s = 0;
                        for (int k = 0; k < cols; k++)
                        {
                            var v = matrix[j][k] - means[j];
                            s += v * v;
                        }   
                        cov[i][j] = s;
                        cov[j][i] = s;
                    }
                }
            }
            else
            {
                throw new ArgumentException("Invalid dimension.", "dimension");
            }

            return cov;
        }
示例#4
0
        /// <summary>
        ///   Converts a matrix represented as a nested list of lists into a jagged matrix.
        /// </summary>
        ///
        public static T[][] ToJagged <T>(this IList <IList <T> > values)
        {
            int rows = values.Rows();
            int cols = values.Columns();

            T[][] result = Jagged.Zeros <T>(rows, cols);
            for (int i = 0; i < values.Count; i++)
            {
                for (int j = 0; j < values[i].Count; j++)
                {
                    result[i][j] = values[i][j];
                }
            }

            return(result);
        }