コード例 #1
0
        /**
         * <p>
         * Returns true if the matrix is symmetric within the tolerance.  Only square matrices can be
         * symmetric.
         * </p>
         * <p>
         * A matrix is symmetric if:<br>
         * |a<sub>ij</sub> - a<sub>ji</sub>| &le; tol
         * </p>
         *
         * @param m A matrix. Not modified.
         * @param tol Tolerance for how similar two elements need to be.
         * @return true if it is symmetric and false if it is not.
         */
        public static bool isSymmetric(DMatrixRMaj m, double tol)
        {
            if (m.numCols != m.numRows)
            {
                return(false);
            }

            double max = CommonOps_DDRM.elementMaxAbs(m);

            for (int i = 0; i < m.numRows; i++)
            {
                for (int j = 0; j < i; j++)
                {
                    double a = m.get(i, j) / max;
                    double b = m.get(j, i) / max;

                    double diff = Math.Abs(a - b);

                    if (!(diff <= tol))
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
コード例 #2
0
        /**
         * <p>
         * Element wise p-norm:<br>
         * <br>
         * norm = {&sum;<sub>i=1:m</sub> &sum;<sub>j=1:n</sub> { |a<sub>ij</sub>|<sup>p</sup>}}<sup>1/p</sup>
         * </p>
         *
         * <p>
         * This is not the same as the induced p-norm used on matrices, but is the same as the vector p-norm.
         * </p>
         *
         * @param A Matrix. Not modified.
         * @param p p value.
         * @return The norm's value.
         */
        public static double elementP(DMatrix1Row A, double p)
        {
            if (p == 1)
            {
                return(CommonOps_DDRM.elementSumAbs(A));
            }
            if (p == 2)
            {
                return(normF(A));
            }
            else
            {
                double max = CommonOps_DDRM.elementMaxAbs(A);

                if (max == 0.0)
                {
                    return(0.0);
                }

                double total = 0;

                int size = A.getNumElements();

                for (int i = 0; i < size; i++)
                {
                    double a = A.get(i) / max;

                    total += Math.Pow(Math.Abs(a), p);
                }

                return(max * Math.Pow(total, 1.0 / p));
            }
        }
コード例 #3
0
        /**
         * <p>
         * To decompose the matrix 'A' it must have full rank.  'A' is a 'm' by 'n' matrix.
         * It requires about 2n*m<sup>2</sup>-2m<sup>2</sup>/3 flops.
         * </p>
         *
         * <p>
         * The matrix provided here can be of different
         * dimension than the one specified in the constructor.  It just has to be smaller than or equal
         * to it.
         * </p>
         */
        public override bool decompose(DMatrixRMaj A)
        {
            setExpectedMaxSize(A.numRows, A.numCols);

            convertToColumnMajor(A);

            maxAbs = CommonOps_DDRM.elementMaxAbs(A);
            // initialize pivot variables
            setupPivotInfo();

            // go through each column and perform the decomposition
            for (int j = 0; j < minLength; j++)
            {
                if (j > 0)
                {
                    updateNorms(j);
                }
                swapColumns(j);
                // if its degenerate stop processing
                if (!householderPivot(j))
                {
                    break;
                }
                updateA(j);
                rank = j + 1;
            }

            return(true);
        }
コード例 #4
0
 /**
  * Computes the p=&#8734; norm.  If A is a matrix then the induced norm is computed.
  *
  * @param A Matrix or vector.
  * @return The norm.
  */
 public static double normPInf(DMatrixRMaj A)
 {
     if (MatrixFeatures_DDRM.isVector(A))
     {
         return(CommonOps_DDRM.elementMaxAbs(A));
     }
     else
     {
         return(inducedPInf(A));
     }
 }
コード例 #5
0
        /**
         * <p>
         * Computes the Frobenius matrix norm:<br>
         * <br>
         * normF = Sqrt{  &sum;<sub>i=1:m</sub> &sum;<sub>j=1:n</sub> { a<sub>ij</sub><sup>2</sup>}   }
         * </p>
         * <p>
         * This is equivalent to the element wise p=2 norm.  See {@link #fastNormF} for another implementation
         * that is faster, but more prone to underflow/overflow errors.
         * </p>
         *
         * @param a The matrix whose norm is computed.  Not modified.
         * @return The norm's value.
         */
        public static double normF(DMatrixD1 a)
        {
            double total = 0;

            double scale = CommonOps_DDRM.elementMaxAbs(a);

            if (scale == 0.0)
            {
                return(0.0);
            }

            int size = a.getNumElements();

            for (int i = 0; i < size; i++)
            {
                double val = a.get(i) / scale;
                total += val * val;
            }

            return(scale * Math.Sqrt(total));
        }
コード例 #6
0
        /**
         * Sums up the square of each element in the matrix.  This is equivalent to the
         * Frobenius norm squared.
         *
         * @param m Matrix.
         * @return Sum of elements squared.
         */
        public static double elementSumSq(DMatrixD1 m)
        {
            // minimize round off error
            double maxAbs = CommonOps_DDRM.elementMaxAbs(m);

            if (maxAbs == 0)
            {
                return(0);
            }

            double total = 0;

            int N = m.NumElements;

            for (int i = 0; i < N; i++)
            {
                double d = m.data[i] / maxAbs;
                total += d * d;
            }

            return(maxAbs * total * maxAbs);
        }
コード例 #7
0
 public double elementMaxAbs(Matrix A)
 {
     return(CommonOps_DDRM.elementMaxAbs((DMatrixRMaj)A));
 }
コード例 #8
0
        /**
         * Computes the QR decomposition of the provided matrix.
         *
         * @param A Matrix which is to be decomposed.  Not modified.
         */
        public void decompose(DMatrixRMaj A)
        {
            this.QR = (DMatrixRMaj)A.copy();

            int N = Math.Min(A.numCols, A.numRows);

            gammas = new double[A.numCols];

            DMatrixRMaj A_small = new DMatrixRMaj(A.numRows, A.numCols);
            DMatrixRMaj A_mod   = new DMatrixRMaj(A.numRows, A.numCols);
            DMatrixRMaj v       = new DMatrixRMaj(A.numRows, 1);
            DMatrixRMaj Q_k     = new DMatrixRMaj(A.numRows, A.numRows);

            for (int i = 0; i < N; i++)
            {
                // reshape temporary variables
                A_small.reshape(QR.numRows - i, QR.numCols - i, false);
                A_mod.reshape(A_small.numRows, A_small.numCols, false);
                v.reshape(A_small.numRows, 1, false);
                Q_k.reshape(v.getNumElements(), v.getNumElements(), false);

                // use extract matrix to get the column that is to be zeroed
                CommonOps_DDRM.extract(QR, i, QR.numRows, i, i + 1, v, 0, 0);

                double max = CommonOps_DDRM.elementMaxAbs(v);

                if (max > 0 && v.getNumElements() > 1)
                {
                    // normalize to reduce overflow issues
                    CommonOps_DDRM.divide(v, max);

                    // compute the magnitude of the vector
                    double tau = NormOps_DDRM.normF(v);

                    if (v.get(0) < 0)
                    {
                        tau *= -1.0;
                    }

                    double u_0   = v.get(0) + tau;
                    double gamma = u_0 / tau;

                    CommonOps_DDRM.divide(v, u_0);
                    v.set(0, 1.0);

                    // extract the submatrix of A which is being operated on
                    CommonOps_DDRM.extract(QR, i, QR.numRows, i, QR.numCols, A_small, 0, 0);

                    // A = (I - &gamma;*u*u<sup>T</sup>)A
                    CommonOps_DDRM.setIdentity(Q_k);
                    CommonOps_DDRM.multAddTransB(-gamma, v, v, Q_k);
                    CommonOps_DDRM.mult(Q_k, A_small, A_mod);

                    // save the results
                    CommonOps_DDRM.insert(A_mod, QR, i, i);
                    CommonOps_DDRM.insert(v, QR, i, i);
                    QR.unsafe_set(i, i, -tau * max);

                    // save gamma for recomputing Q later on
                    gammas[i] = gamma;
                }
            }
        }