public DoubleMatrix2D LowerTriangular(DoubleMatrix2D A)
        {
            int rows    = A.Rows;
            int columns = A.Columns;
            int min     = System.Math.Min(rows, columns);

            for (int r = min; --r >= 0;)
            {
                for (int c = min; --c >= 0;)
                {
                    if (r < c)
                    {
                        A[r, c] = 0;
                    }
                    else if (r == c)
                    {
                        A[r, c] = 1;
                    }
                }
            }
            if (columns > rows)
            {
                A.ViewPart(0, min, rows, columns - min).Assign(0);
            }

            return(A);
        }
Ejemplo n.º 2
0
        public void TestUpdating()
        {
            // first row
            var m          = DoubleFactory2D.Dense.Make(_a.ViewColumn(0).ToArray(), _a.Rows);
            var initialSVD = new SingularValueDecomposition(m);
            var u          = initialSVD.U;
            var s          = initialSVD.S;
            var v          = initialSVD.V;

            // second row
            var d  = DoubleFactory2D.Dense.Make(_a.ViewColumn(1).ToArray(), _a.Rows);
            var l  = u.ViewDice().ZMult(d, null);
            var uu = u.ZMult(u.ViewDice(), null);
            var ul = uu.ZMult(d, null);
            var h  = d.Copy().Assign(uu.ZMult(d, null), BinaryFunctions.Minus);
            var k  = Math.Sqrt(d.Aggregate(BinaryFunctions.Plus, a => a * a) - (2 * l.Aggregate(BinaryFunctions.Plus, a => a * a)) + ul.Aggregate(BinaryFunctions.Plus, a => a * a));
            var j1 = h.Assign(UnaryFunctions.Div(k));

            Assert.AreEqual(j1.Assign(UnaryFunctions.Mult(k)), h);

            var q =
                DoubleFactory2D.Dense.Compose(
                    new[] { new[] { s, l }, new[] { null, DoubleFactory2D.Dense.Make(1, 1, k) } });
            var svdq = new SingularValueDecomposition(q);
            var u2   = DoubleFactory2D.Dense.AppendColumns(u, j1).ZMult(svdq.U, null);
            var s2   = svdq.S;
            var v2   = DoubleFactory2D.Dense.ComposeDiagonal(v, DoubleFactory2D.Dense.Identity(1)).ZMult(
                svdq.V, null);

            var svd = new SingularValueDecomposition(_a.ViewPart(0, 0, _a.Rows, 2));

            Assert.AreEqual(svd.S, s2);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Least squares solution of <i>A*X = B</i>; <i>returns X</i>.
        /// </summary>
        /// <param name="B">A matrix with as many rows as <i>A</i> and any number of columns.</param>
        /// <returns><i>X</i> that minimizes the two norm of <i>Q*R*X - B</i>.</returns>
        /// <exception cref="ArgumentException">if <i>B.Rows != A.Rows</i>.</exception>
        /// <exception cref="ArgumentException">if <i>!this.hasFullRank()</i> (<i>A</i> is rank deficient).</exception>
        public DoubleMatrix2D Solve(DoubleMatrix2D B)
        {
            Functions F = Functions.functions;

            if (B.Rows != m)
            {
                throw new ArgumentException(Cern.LocalizedResources.Instance().Exception_MatrixRowDimensionsMustAgree);
            }
            if (!this.HasFullRank)
            {
                throw new ArgumentException(Cern.LocalizedResources.Instance().Exception_MatrixIsRankDeficient);
            }

            // Copy right hand side
            int            nx = B.Columns;
            DoubleMatrix2D X  = B.Copy();

            // Compute Y = transpose(Q)*B
            for (int k = 0; k < n; k++)
            {
                for (int j = 0; j < nx; j++)
                {
                    double s = 0.0;
                    for (int i = k; i < m; i++)
                    {
                        s += QR[i, k] * X[i, j];
                    }
                    s = -s / QR[k, k];
                    for (int i = k; i < m; i++)
                    {
                        X[i, j] = X[i, j] + s * QR[i, k];
                    }
                }
            }
            // Solve R*X = Y;
            for (int k = n - 1; k >= 0; k--)
            {
                for (int j = 0; j < nx; j++)
                {
                    X[k, j] = X[k, j] / Rdiag[k];
                }
                for (int i = 0; i < k; i++)
                {
                    for (int j = 0; j < nx; j++)
                    {
                        X[i, j] = X[i, j] - X[k, j] * QR[i, k];
                    }
                }
            }
            return(X.ViewPart(0, 0, n, nx));
        }
 /// <summary>
 /// Reduced rank-<code>k</code> decomposition.
 /// Assume that the singular values are ordered.
 /// Discard the lowest singular values and the corresponding columns of U and V.
 /// </summary>
 /// <param name="r">The reduced rank.</param>
 public void Reduce(int r)
 {
     if (r < _n)
     {
         _u = _u.ViewPart(0, 0, _u.Rows, r);
         if (_v != null)
         {
             _v = _v.ViewPart(0, 0, _v.Rows, r);
         }
         var s = new double[r];
         Array.Copy(_s, s, r);
         _s = s;
         _n = r;
     }
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Copies the columns of the indicated rows into a new sub matrix.
        /// <i>sub[0..rowIndexes.Length-1,0..columnTo-columnFrom] = A[rowIndexes(:),columnFrom..columnTo]</i>;
        /// The returned matrix is <i>not backed</i> by this matrix, so changes in the returned matrix are <i>not reflected</i> in this matrix, and vice-versa.
        /// </summary>
        /// <param name="A">the source matrix to copy from.</param>
        /// <param name="rowIndexes">the indexes of the rows to copyd May be unsorted.</param>
        /// <param name="columnFrom">the index of the first column to copy (inclusive).</param>
        /// <param name="columnTo">the index of the last column to copy (inclusive).</param>
        /// <returns>a new sub matrix; with <i>sub.Rows==rowIndexes.Length; sub.Columns==columnTo-columnFrom+1</i>.</returns>
        /// <exception cref="IndexOutOfRangeException">if <i>columnFrom &lt; 0 || columnTo-columnFrom+1 &lt; 0 || columnTo+1>matrix.Columns || for any row=rowIndexes[i]: row  &lt;  0 || row >= matrix.Rows</i>.</exception>
        private static DoubleMatrix2D SubMatrix(DoubleMatrix2D A, int[] rowIndexes, int columnFrom, int columnTo)
        {
            int width = columnTo - columnFrom + 1;
            int rows  = A.Rows;

            A = A.ViewPart(0, columnFrom, rows, width);
            DoubleMatrix2D sub = A.Like(rowIndexes.Length, width);

            for (int r = rowIndexes.Length; --r >= 0;)
            {
                int row = rowIndexes[r];
                if (row < 0 || row >= rows)
                {
                    throw new IndexOutOfRangeException("Illegal Index");
                }
                sub.ViewRow(r).Assign(A.ViewRow(row));
            }
            return(sub);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Copies the rows of the indicated columns into a new sub matrix.
        /// <i>sub[0..rowTo-rowFrom,0..columnIndexes.Length-1] = A[rowFrom..rowTo,columnIndexes(:)]</i>;
        /// The returned matrix is <i>not backed</i> by this matrix, so changes in the returned matrix are <i>not reflected</i> in this matrix, and vice-versa.
        /// </summary>
        /// <param name="A">the source matrix to copy from.</param>
        /// <param name="rowFrom">the index of the first row to copy (inclusive).</param>
        /// <param name="rowTo">the index of the last row to copy (inclusive).</param>
        /// <param name="columnIndexes">the indexes of the columns to copyd May be unsorted.</param>
        /// <returns>a new sub matrix; with <i>sub.Rows==rowTo-rowFrom+1; sub.Columns==columnIndexes.Length</i>.</returns>
        /// <exception cref="IndexOutOfRangeException">if <i>rowFrom &lt; 0 || rowTo-rowFrom + 1 &lt; 0 || rowTo + 1 > matrix.Rows || for any col = columnIndexes[i]: col &lt; 0 || col >= matrix.Columns</i>.</exception>
        private static DoubleMatrix2D SubMatrix(DoubleMatrix2D A, int rowFrom, int rowTo, int[] columnIndexes)
        {
            if (rowTo - rowFrom >= A.Rows)
            {
                throw new IndexOutOfRangeException("Too many rows");
            }
            int height  = rowTo - rowFrom + 1;
            int columns = A.Columns;

            A = A.ViewPart(rowFrom, 0, height, columns);
            DoubleMatrix2D sub = A.Like(height, columnIndexes.Length);

            for (int c = columnIndexes.Length; --c >= 0;)
            {
                int column = columnIndexes[c];
                if (column < 0 || column >= columns)
                {
                    throw new IndexOutOfRangeException("Illegal Index");
                }
                sub.ViewColumn(c).Assign(A.ViewColumn(column));
            }
            return(sub);
        }
        public DoubleMatrix2D UpperTriangular(DoubleMatrix2D A)
        {
            int rows    = A.Rows;
            int columns = A.Columns;
            int min     = System.Math.Min(rows, columns);

            for (int r = min; --r >= 0;)
            {
                for (int c = min; --c >= 0;)
                {
                    if (r > c)
                    {
                        A[r, c] = 0;
                    }
                }
            }
            if (columns < rows)
            {
                A.ViewPart(min, 0, rows - min, columns).Assign(0);
            }

            return(A);
        }
Ejemplo n.º 8
0
        public DoubleMatrix2D[] SplitStridedNN(DoubleMatrix2D A, int threshold, long flops)
        {
            /*
             * determine how to split and parallelize best into blocks
             * if more B.Columns than tasks --> split B.Columns, as follows:
             *
             *      xx|xx|xxx B
             *      xx|xx|xxx
             *      xx|xx|xxx
             * A
             * xxx     xx|xx|xxx C
             * xxx		xx|xx|xxx
             * xxx		xx|xx|xxx
             * xxx		xx|xx|xxx
             * xxx		xx|xx|xxx
             *
             * if less B.Columns than tasks --> split A.rows, as follows:
             *
             *      xxxxxxx B
             *      xxxxxxx
             *      xxxxxxx
             * A
             * xxx     xxxxxxx C
             * xxx     xxxxxxx
             * ---     -------
             * xxx     xxxxxxx
             * xxx     xxxxxxx
             * ---     -------
             * xxx     xxxxxxx
             *
             */
            //long flops = 2L*A.Rows*A.Columns*A.Columns;
            int     noOfTasks  = (int)System.Math.Min(flops / threshold, this.maxThreads); // each thread should process at least 30000 flops
            Boolean splitHoriz = (A.Columns < noOfTasks);
            //Boolean splitHoriz = (A.Columns >= noOfTasks);
            int p = splitHoriz ? A.Rows : A.Columns;

            noOfTasks = System.Math.Min(p, noOfTasks);

            if (noOfTasks < 2)
            { // parallelization doesn't pay off (too much start up overhead)
                return(null);
            }

            // set up concurrent tasks
            int span = p / noOfTasks;

            DoubleMatrix2D[] blocks = new DoubleMatrix2D[noOfTasks];
            for (int i = 0; i < noOfTasks; i++)
            {
                int offset = i * span;
                if (i == noOfTasks - 1)
                {
                    span = p - span * i;                     // last span may be a bit larger
                }
                DoubleMatrix2D AA, BB, CC;
                if (!splitHoriz)
                {
                    // split B along columns into blocks
                    blocks[i] = A.ViewPart(0, i, A.Rows, A.Columns - i).ViewStrides(1, noOfTasks);
                }
                else
                {
                    // split A along rows into blocks
                    blocks[i] = A.ViewPart(i, 0, A.Rows - i, A.Columns).ViewStrides(noOfTasks, 1);
                }
            }
            return(blocks);
        }
Ejemplo n.º 9
0
        public void Dgemv(bool transposeA, double alpha, DoubleMatrix2D A, DoubleMatrix1D x, double beta, DoubleMatrix1D y)
        {
            /*
             * split A, as follows:
             *
             *      x x
             *      x
             *      x
             * A
             * xxx     x y
             * xxx     x
             * ---     -
             * xxx     x
             * xxx     x
             * ---     -
             * xxx     x
             *
             */
            if (transposeA)
            {
                Dgemv(false, alpha, A.ViewDice(), x, beta, y);
                return;
            }
            int  m         = A.Rows;
            int  n         = A.Columns;
            long flops     = 2L * m * n;
            int  noOfTasks = (int)System.Math.Min(flops / 30000, this.maxThreads); // each thread should process at least 30000 flops
            int  width     = A.Rows;

            noOfTasks = System.Math.Min(width, noOfTasks);

            if (noOfTasks < 2)
            { // parallelization doesn't pay off (too much start up overhead)
                seqBlas.Dgemv(transposeA, alpha, A, x, beta, y);
                return;
            }

            // set up concurrent tasks
            int span = width / noOfTasks;

            //FJTask[] subTasks = new FJTask[noOfTasks];
            for (int i = 0; i < noOfTasks; i++)
            {
                int offset = i * span;
                if (i == noOfTasks - 1)
                {
                    span = width - span * i;                     // last span may be a bit larger
                }
                // split A along rows into blocks
                DoubleMatrix2D AA = A.ViewPart(offset, 0, span, n);
                DoubleMatrix1D yy = y.ViewPart(offset, span);

                //    subTasks[i] = new FJTask()
                //    {

                //        public void run()
                //    {
                //        seqBlas.Dgemv(transposeA, alpha, AA, x, beta, yy);
                //        //Console.WriteLine("Hello "+offset);
                //    }
                //};

                Action task = (() =>
                {
                    seqBlas.Dgemv(transposeA, alpha, AA, x, beta, yy);
                });

                // run tasks and wait for completion
                try
                {
                    this.smp.TaskGroup.QueueTask(() => task());
                }
                catch (TaskCanceledException exc) { }
            }
        }
Ejemplo n.º 10
0
        public void Dgemm(bool transposeA, bool transposeB, double alpha, DoubleMatrix2D A, DoubleMatrix2D B, double beta, DoubleMatrix2D C)
        {
            /*
             *  determine how to split and parallelize best into blocks
             *  if more B.columns than tasks --> split B.columns, as follows:
             *
             *                  xx|xx|xxx B
             *                  xx|xx|xxx
             *                  xx|xx|xxx
             *  A
             *  xxx     xx|xx|xxx C
             *  xxx		xx|xx|xxx
             *  xxx		xx|xx|xxx
             *  xxx		xx|xx|xxx
             *  xxx		xx|xx|xxx
             *
             *  if less B.columns than tasks --> split A.rows, as follows:
             *
             *                  xxxxxxx B
             *                  xxxxxxx
             *                  xxxxxxx
             *  A
             *  xxx     xxxxxxx C
             *  xxx     xxxxxxx
             *  ---     -------
             *  xxx     xxxxxxx
             *  xxx     xxxxxxx
             *  ---     -------
             *  xxx     xxxxxxx
             *
             */
            if (transposeA)
            {
                Dgemm(false, transposeB, alpha, A.ViewDice(), B, beta, C);
                return;
            }
            if (transposeB)
            {
                Dgemm(transposeA, false, alpha, A, B.ViewDice(), beta, C);
                return;
            }
            int m = A.Rows;
            int n = A.Columns;
            int p = B.Columns;

            if (B.Rows != n)
            {
                throw new ArgumentException("Matrix2D inner dimensions must agree:" + A.ToStringShort() + ", " + B.ToStringShort());
            }
            if (C.Rows != m || C.Columns != p)
            {
                throw new ArgumentException("Incompatibel result matrix: " + A.ToStringShort() + ", " + B.ToStringShort() + ", " + C.ToStringShort());
            }
            if (A == C || B == C)
            {
                throw new ArgumentException("Matrices must not be identical");
            }

            long    flops     = 2L * m * n * p;
            int     noOfTasks = (int)System.Math.Min(flops / 30000, this.maxThreads); // each thread should process at least 30000 flops
            Boolean splitB    = (p >= noOfTasks);
            int     width     = splitB ? p : m;

            noOfTasks = System.Math.Min(width, noOfTasks);

            if (noOfTasks < 2)
            { // parallelization doesn't pay off (too much start up overhead)
                seqBlas.Dgemm(transposeA, transposeB, alpha, A, B, beta, C);
                return;
            }

            // set up concurrent tasks
            int span = width / noOfTasks;

            //FJTask[] subTasks = new FJTask[noOfTasks];


            for (int i = 0; i < noOfTasks; i++)
            {
                int offset = i * span;
                if (i == noOfTasks - 1)
                {
                    span = width - span * i;                     // last span may be a bit larger
                }
                DoubleMatrix2D AA, BB, CC;
                if (splitB)
                {
                    // split B along columns into blocks
                    AA = A;
                    BB = B.ViewPart(0, offset, n, span);
                    CC = C.ViewPart(0, offset, m, span);
                }
                else
                {
                    // split A along rows into blocks
                    AA = A.ViewPart(offset, 0, span, n);
                    BB = B;
                    CC = C.ViewPart(offset, 0, span, p);
                }

                Action task = (() =>
                {
                    seqBlas.Dgemm(transposeA, transposeB, alpha, AA, BB, beta, CC);
                });

                // run tasks and wait for completion
                try
                {
                    this.smp.TaskGroup.QueueTask(() => task());
                }
                catch (TaskCanceledException exc) { }
            }
        }
Ejemplo n.º 11
0
        ///// <summary>
        /////
        ///// </summary>
        ///// <param name="matrix"></param>
        ///// <param name="rowNames"></param>
        ///// <param name="columnNames"></param>
        ///// <param name="rowAxisName"></param>
        ///// <param name="columnAxisName"></param>
        ///// <param name="title"></param>
        ///// <returns></returns>
        //public String ToTitleString(ObjectMatrix2D matrix, String[] rowNames, String[] columnNames, String rowAxisName, String columnAxisName, String title)
        //{
        //    if (matrix.Size == 0) return "Empty matrix";
        //    String oldFormat = this.formatString;
        //    this.formatString = LEFT;

        //    int rows = matrix.Rows;
        //    int columns = matrix.Columns;

        //    // determine how many rows and columns are needed
        //    int r = 0;
        //    int c = 0;
        //    r += (columnNames == null ? 0 : 1);
        //    c += (rowNames == null ? 0 : 1);
        //    c += (rowAxisName == null ? 0 : 1);
        //    c += (rowNames != null || rowAxisName != null ? 1 : 0);

        //    int height = r + System.Math.Max(rows, rowAxisName == null ? 0 : rowAxisName.Length);
        //    int width = c + columns;

        //    // make larger matrix holding original matrix and naming strings
        //    Cern.Colt.Matrix.ObjectMatrix2D titleMatrix = matrix.Like(height, width);

        //    // insert original matrix into larger matrix
        //    titleMatrix.ViewPart(r, c, rows, columns).Assign(matrix);

        //    // insert column axis name in leading row
        //    if (r > 0) titleMatrix.ViewRow(0).ViewPart(c, columns).Assign(columnNames);

        //    // insert row axis name in leading column
        //    if (rowAxisName != null)
        //    {
        //        String[] rowAxisStrings = new String[rowAxisName.Length];
        //        for (int i = rowAxisName.Length; --i >= 0;) rowAxisStrings[i] = rowAxisName.Substring(i, i + 1);
        //        titleMatrix.ViewColumn(0).ViewPart(r, rowAxisName.Length).Assign(rowAxisStrings);
        //    }
        //    // insert row names in next leading columns
        //    if (rowNames != null) titleMatrix.ViewColumn(c - 2).ViewPart(r, rows).Assign(rowNames);

        //    // insert vertical "---------" separator line in next leading column
        //    if (c > 0) titleMatrix.ViewColumn(c - 2 + 1).ViewPart(0, rows + r).Assign("|");

        //    // convert the large matrix to a string
        //    Boolean oldPrintShape = this.printShape;
        //    this.printShape = false;
        //    String str = ToString(titleMatrix);
        //    this.printShape = oldPrintShape;

        //    // insert horizontal "--------------" separator line
        //    var total = new StringBuilder(str);
        //    if (columnNames != null)
        //    {
        //        int i = str.IndexOf(rowSeparator);
        //        total.Insert(i + 1, Repeat('-', i) + rowSeparator);
        //    }
        //    else if (columnAxisName != null)
        //    {
        //        int i = str.IndexOf(rowSeparator);
        //        total.Insert(0, Repeat('-', i) + rowSeparator);
        //    }

        //    // insert line for column axis name
        //    if (columnAxisName != null)
        //    {
        //        int j = 0;
        //        if (c > 0) j = str.IndexOf('|');
        //        String s = Blanks(j);
        //        if (c > 0) s = s + "| ";
        //        s = s + columnAxisName + "\n";
        //        total.Insert(0, s);
        //    }

        //    // insert title
        //    if (title != null) total.Insert(0, title + "\n");

        //    this.formatString = oldFormat;

        //    return total.ToString();
        //}

        /// <summary>
        /// Same as <i>toTitleString</i> except that additionally statistical aggregates (mean, median, sum, etcd) of rows and columns are printed.
        /// Pass <i>null</i> to one or more parameters to indicate that the corresponding decoration element shall not appear in the string converted matrix.
        /// </summary>
        /// <param name="matrix">The matrix to format.</param>
        /// <param name="rowNames">The headers of all rows (to be put to the left of the matrix).</param>
        /// <param name="columnNames">The headers of all columns (to be put to above the matrix).</param>
        /// <param name="rowAxisName">The label of the y-axis.</param>
        /// <param name="columnAxisName">The label of the x-axis.</param>
        /// <param name="title">The overall title of the matrix to be formatted.</param>
        /// <param name="aggr">the aggregation functions to be applied to columns and rows.</param>
        /// <returns>the matrix converted to a string.</returns>
        /// <see cref="Hep.Aida.Bin.BinFunction1D"/>
        /// <see cref="Hep.Aida.Bin.BinFunctions1D"/>
        public String ToTitleString(DoubleMatrix2D matrix, String[] rowNames, String[] columnNames, String rowAxisName, String columnAxisName, String title, Hep.Aida.Bin.BinFunction1D[] aggr)
        {
            if (matrix.Size == 0)
            {
                return("Empty matrix");
            }
            if (aggr == null || aggr.Length == 0)
            {
                return(ToTitleString(matrix, rowNames, columnNames, rowAxisName, columnAxisName, title));
            }

            DoubleMatrix2D rowStats = matrix.Like(matrix.Rows, aggr.Length);                                      // hold row aggregations
            DoubleMatrix2D colStats = matrix.Like(aggr.Length, matrix.Columns);                                   // hold column aggregations

            Cern.Colt.Matrix.DoubleAlgorithms.Statistics.Aggregate(matrix, aggr, colStats);                       // aggregate an entire column at a time
            Cern.Colt.Matrix.DoubleAlgorithms.Statistics.Aggregate(matrix.ViewDice(), aggr, rowStats.ViewDice()); // aggregate an entire row at a time

            // turn into strings
            // tmp holds "matrix" plus "colStats" below (needed so that numbers in a columns can be decimal point aligned)
            DoubleMatrix2D tmp = matrix.Like(matrix.Rows + aggr.Length, matrix.Columns);

            tmp.ViewPart(0, 0, matrix.Rows, matrix.Columns).Assign(matrix);
            tmp.ViewPart(matrix.Rows, 0, aggr.Length, matrix.Columns).Assign(colStats);

            String[][] s1 = Format(tmp); Align(s1);
            String[][] s2 = Format(rowStats); Align(s2);

            // copy strings into a large matrix holding the source matrix and all aggregations
            Cern.Colt.Matrix.ObjectMatrix2D allStats = Cern.Colt.Matrix.ObjectFactory2D.Dense.Make(matrix.Rows + aggr.Length, matrix.Columns + aggr.Length + 1);
            allStats.ViewPart(0, 0, matrix.Rows + aggr.Length, matrix.Columns).Assign(s1);
            allStats.ViewColumn(matrix.Columns).Assign("|");
            allStats.ViewPart(0, matrix.Columns + 1, matrix.Rows, aggr.Length).Assign(s2);

            // append a vertical "|" separator plus names of aggregation functions to line holding columnNames
            if (columnNames != null)
            {
                var list = new List <Object>(columnNames);
                list.Add("|");
                list.AddRange(aggr.Select(x => x.Method.Name).ToList());
                columnNames = list.ToStringArray();
            }

            // append names of aggregation functions to line holding rowNames
            if (rowNames != null)
            {
                var list = new List <Object>(rowNames);
                list.AddRange(aggr.Select(x => x.Method.Name).ToList());
                rowNames = list.ToStringArray();
            }

            // turn large matrix into string
            String s = new Cern.Colt.Matrix.ObjectAlgorithms.Formatter().ToTitleString(allStats, rowNames, columnNames, rowAxisName, columnAxisName, title);

            // insert a horizontal "----------------------" separation line above the column stats
            // determine insertion position and line width
            int last       = s.Length + 1;
            int secondLast = last;
            int v          = System.Math.Max(0, rowAxisName == null ? 0 : rowAxisName.Length - matrix.Rows - aggr.Length);

            for (int k = 0; k < aggr.Length + 1 + v; k++)
            { // scan "aggr.Length+1+v" lines backwards
                secondLast = last;
                last       = s.LastIndexOf(rowSeparator, last - 1);
            }
            StringBuilder buf = new StringBuilder(s);

            buf.Insert(secondLast, rowSeparator + Repeat('-', secondLast - last - 1));

            return(buf.ToString());
        }
Ejemplo n.º 12
0
 /// <summary>
 /// Constructs and returns a new <i>sub-range view</i> which is the sub matrix <i>A[fromRow..toRow,fromColumn..toColumn]</i>.
 /// The returned matrix is backed by this matrix, so changes in the returned matrix are reflected in this matrix, and vice-versa.
 /// Use idioms like <i>result = subMatrix(..D).Copy()</i> to generate an independent sub matrix.
 /// </summary>
 /// <param name="A">the source matrix.</param>
 /// <param name="fromRow">The index of the first row (inclusive).</param>
 /// <param name="toRow">The index of the last row (inclusive).</param>
 /// <param name="fromColumn">The index of the first column (inclusive).</param>
 /// <param name="toColumn">The index of the last column (inclusive).</param>
 /// <returns>a new sub-range view.</returns>
 /// <exception cref="IndexOutOfRangeException">if <i>fromColumn &lt; 0 || toColumn - fromColumn + 1 &lt; 0 || toColumn >= A.Columns || fromRow &lt; 0 || toRow - fromRow + 1 &lt; 0 || toRow >= A.Rows</i></exception>
 public static DoubleMatrix2D SubMatrix(DoubleMatrix2D A, int fromRow, int toRow, int fromColumn, int toColumn)
 {
     return(A.ViewPart(fromRow, fromColumn, toRow - fromRow + 1, toColumn - fromColumn + 1));
 }