Ejemplo n.º 1
0
        /// <summary>
        /// Constructs and returns a new Cholesky decomposition object for a symmetric and positive definite matrix;
        /// The decomposed matrices can be retrieved via instance methods of the returned decomposition object.
        ///
        /// Return a structure to access <i>L</i> and <i>isSymmetricPositiveDefinite</i> flag.
        /// </summary>
        /// <param name="A">Square, symmetric matrix.</param>
        /// <exception cref="ArgumentException">if <i>A</i> is not square.</exception>
        public CholeskyDecomposition(DoubleMatrix2D A)
        {
            Property.DEFAULT.CheckSquare(A);
            // Initialize.
            //double[][] A = Arg.getArray();

            n = A.Rows;
            //L = new double[n][n];
            mL = A.Like(n, n);
            isSymmetricPositiveDefinite = (A.Columns == n);

            //precompute and cache some views to avoid regenerating them time and again
            DoubleMatrix1D[] Lrows = new DoubleMatrix1D[n];
            for (int j = 0; j < n; j++)
            {
                Lrows[j] = mL.ViewRow(j);
            }

            // Main loop.
            for (int j = 0; j < n; j++)
            {
                //double[] Lrowj = L[j];
                //DoubleMatrix1D Lrowj = L.ViewRow(j);
                double d = 0.0;
                for (int k = 0; k < j; k++)
                {
                    //double[] Lrowk = L[k];
                    double s = Lrows[k].ZDotProduct(Lrows[j], 0, k);

                    /*
                     * DoubleMatrix1D Lrowk = L.ViewRow(k);
                     * double s = 0.0;
                     * for (int i = 0; i < k; i++) {
                     * s += Lrowk.getQuick(i)*Lrowj.getQuick(i);
                     * }
                     */
                    s           = (A[j, k] - s) / mL[k, k];
                    Lrows[j][k] = s;
                    d           = d + s * s;
                    isSymmetricPositiveDefinite = isSymmetricPositiveDefinite && (A[k, j] == A[j, k]);
                }
                d = A[j, j] - d;
                isSymmetricPositiveDefinite = isSymmetricPositiveDefinite && (d > 0.0);
                mL[j, j] = System.Math.Sqrt(System.Math.Max(d, 0.0));

                for (int k = j + 1; k < n; k++)
                {
                    mL[j, k] = 0.0;
                }
            }
        }
Ejemplo n.º 2
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.º 3
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);
        }
Ejemplo n.º 4
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());
        }
 /// <summary>
 /// Construct and returns a new 2-d matrix <i>of the corresponding dynamic type</i>, entirelly independent of the receiver.
 /// For example, if the receiver is an instance of type <see cref="DenseDoubleMatrix1D"/> the new matrix must also be of type <see cref="DenseDoubleMatrix2D"/>,
 /// if the receiver is an instance of type <see cref="SparseDoubleMatrix1D"/> the new matrix must also be of type <see cref="SparseDoubleMatrix2D"/>, etc.
 ///
 ///
 /// </summary>
 /// <param name="rows">the number of rows the matrix shall have.</param>
 /// <param name="columns">the number of columns the matrix shall have.</param>
 /// <returns>a new matrix of the corresponding dynamic type.</returns>
 public override DoubleMatrix2D Like2D(int rows, int columns)
 {
     return(content2D.Like(rows, columns));
 }
Ejemplo n.º 6
0
        /// <summary>
        /// Linear algebraic matrix power; <i>B = A<sup>k</sup> &lt;==> B = A*A*...*A</i>.
        /// <ul>
        /// <li><i>p &gt;= 1: B = A*A*...*A</i>.</li>
        /// <li><i>p == 0: B = identity matrix</i>.</li>
        /// <li><i>p &lt;  0: B = pow(inverse(A),-p)</i>.</li>
        /// </ul>
        /// Implementation: Based on logarithms of 2, memory usage minimized.
        /// </summary>
        /// <param name="A">the source matrix; must be square; stays unaffected by this operation.</param>
        /// <param name="p">the exponent, can be any number.</param>
        /// <returns><i>B</i>, a newly constructed result matrix; storage-independent of <i>A</i>.</returns>
        ///<exception cref="ArgumentException">if <i>!property().isSquare(A)</i>.</exception>
        public static DoubleMatrix2D Pow(DoubleMatrix2D A, int p)
        {
            // matrix multiplication based on log2 method: A*A*....*A is slow, ((A * A)^2)^2 * ..D is faster
            // allocates two auxiliary matrices as work space

            IBlas blas = SmpBlas.smpBlas; // for parallel matrix mult; if not initialized defaults to sequential blas

            Property.DEFAULT.CheckSquare(A);
            if (p < 0)
            {
                A = Inverse(A);
                p = -p;
            }
            if (p == 0)
            {
                return(DoubleFactory2D.Dense.Identity(A.Rows));
            }
            DoubleMatrix2D T = A.Like(); // temporary

            if (p == 1)
            {
                return(T.Assign(A));         // safes one auxiliary matrix allocation
            }
            if (p == 2)
            {
                blas.Dgemm(false, false, 1, A, A, 0, T); // mult(A,A); // safes one auxiliary matrix allocation
                return(T);
            }

            int k = Cern.Colt.Bitvector.QuickBitVector.MostSignificantBit(p); // index of highest bit in state "true"

            /*
             * this is the naive version:
             * DoubleMatrix2D B = A.Copy();
             * for (int i=0; i<p-1; i++) {
             *  B = mult(B,A);
             * }
             * return B;
             */

            // here comes the optimized version:
            //cern.colt.Timer timer = new cern.colt.Timer().start();

            int i = 0;

            while (i <= k && (p & (1 << i)) == 0)
            {                                             // while (bit i of p == false)
              // A = mult(A,A); would allocate a lot of temporary memory
                blas.Dgemm(false, false, 1, A, A, 0, T);  // A.zMult(A,T);
                DoubleMatrix2D swap = A; A = T; T = swap; // swap A with T
                i++;
            }

            DoubleMatrix2D B = A.Copy();

            i++;
            for (; i <= k; i++)
            {
                // A = mult(A,A); would allocate a lot of temporary memory
                blas.Dgemm(false, false, 1, A, A, 0, T);  // A.zMult(A,T);
                DoubleMatrix2D swap = A; A = T; T = swap; // swap A with T

                if ((p & (1 << i)) != 0)
                {                                            // if (bit i of p == true)
                  // B = mult(B,A); would allocate a lot of temporary memory
                    blas.Dgemm(false, false, 1, B, A, 0, T); // B.zMult(A,T);
                    swap = B; B = T; T = swap;               // swap B with T
                }
            }
            //timer.stop().Display();
            return(B);
        }