コード例 #1
0
 /**
  * Sets the matrices to operate upon.
  */
 public virtual void SetParameters(DoubleMatrix2D A, DoubleMatrix2D B)
 {
     this.A = A;
     this.B = B;
     this.C = A.Copy();
     this.D = B.Copy();
 }
コード例 #2
0
        /// <summary>
        /// Solves <i>A*X = B</i>; returns <i>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> so that <i>L*L'*X = B</i>.</returns>
        /// <exception cref="ArgumentException">if <i>B.Rows != A.Rows</i>.</exception>
        /// <exception cref="ArgumentException">if <i>!isSymmetricPositiveDefinite()</i>.</exception>
        public DoubleMatrix2D Solve(DoubleMatrix2D B)
        {
            // Copy right hand side.
            DoubleMatrix2D X  = B.Copy();
            int            nx = B.Columns;

            // fix by MG Ferreira <*****@*****.**>
            // old code is in method xxxSolveBuggy()
            for (int c = 0; c < nx; c++)
            {
                // Solve L*Y = B;
                for (int i = 0; i < n; i++)
                {
                    double sum = B[i, c];
                    for (int k = i - 1; k >= 0; k--)
                    {
                        sum -= mL[i, k] * X[k, c];
                    }
                    X[i, c] = sum / mL[i, i];
                }

                // Solve L'*X = Y;
                for (int i = n - 1; i >= 0; i--)
                {
                    double sum = X[i, c];
                    for (int k = i + 1; k < n; k++)
                    {
                        sum -= mL[k, i] * X[k, c];
                    }
                    X[i, c] = sum / mL[i, i];
                }
            }

            return(X);
        }
コード例 #3
0
        /// <summary>
        /// 9 point stencil operation.
        /// Applies a function to a moving <i>3 x 3</i> window.
        /// </summary>
        /// <param name="A">
        /// the matrix to operate on.
        /// </param>
        /// <param name="function">
        /// the function to be applied to each window.
        /// </param>
        /// <param name="maxIterations">
        /// the maximum number of times the stencil shall be applied to the matrixd
        /// Should be a multiple of 2 because two iterations are always done in one atomic step.
        /// </param>
        /// <param name="hasConverged">
        /// Convergence condition; will return before maxIterations are done when <i>hasConverged.apply(A)==true</i>.
        /// Set this parameter to <i>null</i> to indicate that no convergence checks shall be made.
        /// </param>
        /// <param name="convergenceIterations">
        /// the number of iterations to pass between each convergence check.
        /// (Since a convergence may be expensive, you may want to do it only every 2,4 or 8 iterationsd)
        /// </param>
        /// <returns><the number of iterations actually executedd /returns>
        public static int Stencil9(DoubleMatrix2D A, Cern.Colt.Function.Double9Function function, int maxIterations, DoubleMatrix2DProcedure hasConverged, int convergenceIterations)
        {
            DoubleMatrix2D B = A.Copy();

            if (convergenceIterations <= 1)
            {
                convergenceIterations = 2;
            }
            if (convergenceIterations % 2 != 0)
            {
                convergenceIterations++;                                 // odd -> make it even
            }
            int i = 0;

            while (i < maxIterations)
            { // do two steps at a time for efficiency
                A.ZAssign8Neighbors(B, function);
                B.ZAssign8Neighbors(A, function);
                i = i + 2;
                if (i % convergenceIterations == 0 && hasConverged != null)
                {
                    if (hasConverged(A))
                    {
                        return(i);
                    }
                }
            }
            return(i);
        }
コード例 #4
0
ファイル: Algebra.cs プロジェクト: cobaltblueocean/Colt.NET
        /// <summary>
        /// Linear algebraic matrix power; <i>B = A<sup>k</sup> &lt;==> B = A*A*...*A</i>.
        /// </summary>
        /// <param name="A">the source matrix; must be square.</param>
        /// <param name="k">the exponent, can be any number.</param>
        /// <returns>a new result matrix.</returns>
        /// <exception cref="ArgumentException">if <i>!Testing.isSquare(A)</i>.</exception>
        private static DoubleMatrix2D XPowSlow(DoubleMatrix2D A, int k)
        {
            //cern.colt.Timer timer = new cern.colt.Timer().start();
            DoubleMatrix2D result = A.Copy();

            for (int i = 0; i < k - 1; i++)
            {
                result = Mult(result, A);
            }
            //timer.stop().Display();
            return(result);
        }
コード例 #5
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));
        }
コード例 #6
0
ファイル: Algebra.cs プロジェクト: cobaltblueocean/Colt.NET
 public static DoubleMatrix2D Inverse(DoubleMatrix2D A)
 {
     if (A.IsSquare && A.IsDiagonal)
     {
         DoubleMatrix2D inv           = A.Copy();
         Boolean        isNonSingular = Diagonal.Inverse(inv);
         if (!isNonSingular)
         {
             throw new ArgumentException("A is singular.");
         }
         return(inv);
     }
     return(Solve(A, DoubleFactory2D.Dense.Identity(A.Rows)));
 }
コード例 #7
0
 public static DoubleMatrix2D Inverse(DoubleMatrix2D A)
 {
     if (A.IsSquare && A.IsDiagonal)
     {
         DoubleMatrix2D inv           = A.Copy();
         Boolean        IsNonSingular = Diagonal.Inverse(inv);
         if (!IsNonSingular)
         {
             throw new ArgumentException(Cern.LocalizedResources.Instance().Exception_MatrixIsSingular);
         }
         return(inv);
     }
     return(Solve(A, DoubleFactory2D.Dense.Identity(A.Rows)));
 }
コード例 #8
0
        /// <summary>
        /// Solves <i>A*X = B</i>; returns <i>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> so that <i>L*L'*X = B</i>.</returns>
        /// <exception cref="ArgumentException">if <i>B.Rows != A.Rows</i>.</exception>
        /// <exception cref="ArgumentException">if <i>!isSymmetricPositiveDefinite()</i>.</exception>
        private DoubleMatrix2D XXXsolveBuggy(DoubleMatrix2D B)
        {
            var F = Cern.Jet.Math.Functions.functions;

            if (B.Rows != n)
            {
                throw new ArgumentException(Cern.LocalizedResources.Instance().Exception_MatrixRowDimensionsMustAgree);
            }
            if (!isSymmetricPositiveDefinite)
            {
                throw new ArgumentException(Cern.LocalizedResources.Instance().Exception_MatrixIsNotSymmetricPositiveDefinite);
            }

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

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

            // Solve L*Y = B;
            for (int k = 0; k < n; k++)
            {
                for (int i = k + 1; i < n; i++)
                {
                    // X[i,j] -= X[k,j]*L[i,k]
                    Xrows[i].Assign(Xrows[k], F2.MinusMult(mL[i, k]));
                }
                Xrows[k].Assign(F1.Div(mL[k, k]));
            }

            // Solve L'*X = Y;
            for (int k = n - 1; k >= 0; k--)
            {
                Xrows[k].Assign(F1.Div(mL[k, k]));
                for (int i = 0; i < k; i++)
                {
                    // X[i,j] -= X[k,j]*L[k,i]
                    Xrows[i].Assign(Xrows[k], F2.MinusMult(mL[k, i]));
                }
            }
            return(X);
        }
コード例 #9
0
        /// <summary>
        /// Constructs and returns a new QR decomposition object;  computed by Householder reflections;
        /// The decomposed matrices can be retrieved via instance methods of the returned decomposition object.
        /// Return a decomposition object to access <i>R</i> and the Householder vectors <i>H</i>, and to compute <i>Q</i>.
        /// </summary>
        /// <param name="A">A rectangular matrix.</param>
        /// <exception cref="ArgumentException">if <i>A.Rows &lt; A.Columns</i>.</exception>
        public QRDecomposition(DoubleMatrix2D A)
        {
            Property.DEFAULT.CheckRectangular(A);

            Functions F = Functions.functions;

            // Initialize.
            QR    = A.Copy();
            m     = A.Rows;
            n     = A.Columns;
            Rdiag = A.Like1D(n);
            //Rdiag = new double[n];
            DoubleDoubleFunction hypot = Algebra.HypotFunction();

            // precompute and cache some views to avoid regenerating them time and again
            DoubleMatrix1D[] QRcolumns     = new DoubleMatrix1D[n];
            DoubleMatrix1D[] QRcolumnsPart = new DoubleMatrix1D[n];
            for (int k = 0; k < n; k++)
            {
                QRcolumns[k]     = QR.ViewColumn(k);
                QRcolumnsPart[k] = QR.ViewColumn(k).ViewPart(k, m - k);
            }

            // Main loop.
            for (int k = 0; k < n; k++)
            {
                //DoubleMatrix1D QRcolk = QR.ViewColumn(k).ViewPart(k,m-k);
                // Compute 2-norm of k-th column without under/overflow.
                double nrm = 0;
                //if (k<m) nrm = QRcolumnsPart[k].aggregate(hypot,F.identity);

                for (int i = k; i < m; i++)
                { // fixes bug reported by [email protected]
                    nrm = Algebra.Hypot(nrm, QR[i, k]);
                }


                if (nrm != 0.0)
                {
                    // Form k-th Householder vector.
                    if (QR[k, k] < 0)
                    {
                        nrm = -nrm;
                    }
                    QRcolumnsPart[k].Assign(F2.Div(nrm));

                    /*
                     * for (int i = k; i < m; i++) {
                     * QR[i][k] /= nrm;
                     * }
                     */

                    QR[k, k] = QR[k, k] + 1;

                    // Apply transformation to remaining columns.
                    for (int j = k + 1; j < n; j++)
                    {
                        DoubleMatrix1D QRcolj = QR.ViewColumn(j).ViewPart(k, m - k);
                        double         s      = QRcolumnsPart[k].ZDotProduct(QRcolj);

                        /*
                         * // fixes bug reported by John Chambers
                         * DoubleMatrix1D QRcolj = QR.ViewColumn(j).ViewPart(k,m-k);
                         * double s = QRcolumnsPart[k].ZDotProduct(QRcolumns[j]);
                         * double s = 0.0;
                         * for (int i = k; i < m; i++) {
                         * s += QR[i][k]*QR[i][j];
                         * }
                         */
                        s = -s / QR[k, k];
                        //QRcolumnsPart[j].Assign(QRcolumns[k], F.PlusMult(s));

                        for (int i = k; i < m; i++)
                        {
                            QR[i, j] = QR[i, j] + s * QR[i, k];
                        }
                    }
                }
                Rdiag[k] = -nrm;
            }
        }
コード例 #10
0
 /// <summary>
 /// Constructs and returns a new LU Decomposition object; 
 /// The decomposed matrices can be retrieved via instance methods of the returned decomposition object.
 /// Return structure to access L, U and piv.
 /// </summary>
 /// <param name="A">Rectangular matrix</param>
 public LUDecomposition(DoubleMatrix2D A)
 {
     quick = new LUDecompositionQuick(0); // zero tolerance for compatibility with Jama
     quick.Decompose(A.Copy());
 }
コード例 #11
0
 /// <summary>
 /// Solves <i>A*X = B</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> so that <i>L*U*X = B(piv,:)</i>.</returns>
 /// <exception cref="ArgumentException">if B.rows() != A.rows().</exception>
 /// <exception cref="ArgumentException">if A is singular, that is, if !this.isNonsingular().</exception>
 /// <exception cref="ArgumentException">if A.rows() &lt; A.columns().</exception>
 public DoubleMatrix2D Solve(DoubleMatrix2D B)
 {
     DoubleMatrix2D X = B.Copy();
     quick.Solve(X);
     return X;
 }
コード例 #12
0
ファイル: Algebra.cs プロジェクト: cobaltblueocean/Colt.NET
        /// <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);
        }