/**
         * <p>
         * Adds to A &isin; &real; <sup>m &times; n</sup> the results of an outer product multiplication
         * of the two vectors.  This is also known as a rank 1 update.<br>
         * <br>
         * A = A + &gamma; x * y<sup>T</sup>
         * where x &isin; &real; <sup>m</sup> and y &isin; &real; <sup>n</sup> are vectors.
         * </p>
         * <p>
         * Which is equivalent to: A<sub>ij</sub> = A<sub>ij</sub> + &gamma; x<sub>i</sub>*y<sub>j</sub>
         * </p>
         *
         * <p>
         * These functions are often used inside of highly optimized code and therefor sanity checks are
         * kept to a minimum.  It is not recommended that any of these functions be used directly.
         * </p>
         *
         * @param gamma A multiplication factor for the outer product.
         * @param x A vector with m elements. Not modified.
         * @param y A vector with n elements. Not modified.
         * @param A A Matrix with m by n elements. Modified.
         */
        public static void addOuterProd(double gamma, DMatrixD1 x, DMatrixD1 y, DMatrix1Row A)
        {
            int m = A.numRows;
            int n = A.numCols;

            int index = 0;

            if (gamma == 1.0)
            {
                for (int i = 0; i < m; i++)
                {
                    double xdat = x.get(i);
                    for (int j = 0; j < n; j++)
                    {
                        A.plus(index++, xdat * y.get(j));
                    }
                }
            }
            else
            {
                for (int i = 0; i < m; i++)
                {
                    double xdat = x.get(i);
                    for (int j = 0; j < n; j++)
                    {
                        A.plus(index++, gamma * xdat * y.get(j));
                    }
                }
            }
        }
        public static double elementMin(DMatrixD1 a, ElementLocation loc)
        {
            int size = a.NumElements;

            int    bestIndex = 0;
            double min       = a.get(0);

            for (int i = 1; i < size; i++)
            {
                double val = a.get(i);
                if (val < min)
                {
                    bestIndex = i;
                    min       = val;
                }
            }

            if (loc != null)
            {
                loc.row = bestIndex / a.numCols;
                loc.col = bestIndex % a.numCols;
            }

            return(min);
        }
        /**
         * An alternative implementation of {@link #multTransA_small} that performs well on large
         * matrices.  There is a relative performance hit when used on small matrices.
         *
         * @param A A matrix that is m by n. Not modified.
         * @param B A Vector that has length m. Not modified.
         * @param C A column vector that has length n. Modified.
         */
        public static void multTransA_reorder(DMatrix1Row A, DMatrixD1 B, DMatrixD1 C)
        {
            if (C.numCols != 1)
            {
                throw new MatrixDimensionException("C is not a column vector");
            }
            else if (C.numRows != A.numCols)
            {
                throw new MatrixDimensionException("C is not the expected length");
            }
            if (B.numRows == 1)
            {
                if (A.numRows != B.numCols)
                {
                    throw new MatrixDimensionException("A and B are not compatible");
                }
            }
            else if (B.numCols == 1)
            {
                if (A.numRows != B.numRows)
                {
                    throw new MatrixDimensionException("A and B are not compatible");
                }
            }
            else
            {
                throw new MatrixDimensionException("B is not a vector");
            }

            if (A.numRows == 0)
            {
                CommonOps_DDRM.fill(C, 0);
                return;
            }

            double B_val = B.get(0);

            for (int i = 0; i < A.numCols; i++)
            {
                C.set(i, A.get(i) * B_val);
            }

            int indexA = A.numCols;

            for (int i = 1; i < A.numRows; i++)
            {
                B_val = B.get(i);
                for (int j = 0; j < A.numCols; j++)
                {
                    C.plus(j, A.get(indexA++) * B_val);
                }
            }
        }
        /**
         * <p>
         * Performs a matrix vector multiply.<br>
         * <br>
         * c = A * b <br>
         * and<br>
         * c = A * b<sup>T</sup> <br>
         * <br>
         * c<sub>i</sub> = Sum{ j=1:n, a<sub>ij</sub> * b<sub>j</sub>}<br>
         * <br>
         * where A is a matrix, b is a column or transposed row vector, and c is a column vector.
         * </p>
         *
         * @param A A matrix that is m by n. Not modified.
         * @param B A vector that has length n. Not modified.
         * @param C A column vector that has length m. Modified.
         */
        public static void mult(DMatrix1Row A, DMatrixD1 B, DMatrixD1 C)
        {
            if (C.numCols != 1)
            {
                throw new MatrixDimensionException("C is not a column vector");
            }
            else if (C.numRows != A.numRows)
            {
                throw new MatrixDimensionException("C is not the expected length");
            }

            if (B.numRows == 1)
            {
                if (A.numCols != B.numCols)
                {
                    throw new MatrixDimensionException("A and B are not compatible");
                }
            }
            else if (B.numCols == 1)
            {
                if (A.numCols != B.numRows)
                {
                    throw new MatrixDimensionException("A and B are not compatible");
                }
            }
            else
            {
                throw new MatrixDimensionException("B is not a vector");
            }

            if (A.numCols == 0)
            {
                CommonOps_DDRM.fill(C, 0);
                return;
            }

            int    indexA = 0;
            int    cIndex = 0;
            double b0     = B.get(0);

            for (int i = 0; i < A.numRows; i++)
            {
                double total = A.get(indexA++) * b0;

                for (int j = 1; j < A.numCols; j++)
                {
                    total += A.get(indexA++) * B.get(j);
                }

                C.set(cIndex++, total);
            }
        }
        public static double elementMaxAbs(DMatrixD1 a, ElementLocation loc)
        {
            int size = a.NumElements;

            int    bestIndex = 0;
            double max       = 0;

            for (int i = 0; i < size; i++)
            {
                double val = Math.Abs(a.get(i));
                if (val > max)
                {
                    bestIndex = i;
                    max       = val;
                }
            }

            if (loc != null)
            {
                loc.row = bestIndex / a.numCols;
                loc.col = bestIndex % a.numCols;
            }

            return(max);
        }
        /**
         * <p>
         * return = x<sup>T</sup>*A*y
         * </p>
         *
         * @param x  A vector with n elements. Not modified.
         * @param A  A matrix with n by m elements.  Not modified.
         * @param y  A vector with m elements. Not modified.
         * @return  The results.
         */
        public static double innerProdA(DMatrixD1 x, DMatrixD1 A, DMatrixD1 y)
        {
            int n = A.numRows;
            int m = A.numCols;

            if (x.getNumElements() != n)
            {
                throw new ArgumentException("Unexpected number of elements in x");
            }
            if (y.getNumElements() != m)
            {
                throw new ArgumentException("Unexpected number of elements in y");
            }

            double result = 0;

            for (int i = 0; i < m; i++)
            {
                double total = 0;

                for (int j = 0; j < n; j++)
                {
                    total += x.get(j) * A.unsafe_get(j, i);
                }

                result += total * y.get(i);
            }

            return(result);
        }
        /**
         * <p>
         * x<sup>T</sup>A<sup>T</sup>y
         * </p>
         *
         * @param x A vector with n elements. Not modified.
         * @param A A matrix with n by n elements.  Not modified.
         * @param y A vector with n elements. Not modified.
         * @return The results.
         */
        // TODO better name for this
        public static double innerProdTranA(DMatrixD1 x, DMatrixD1 A, DMatrixD1 y)
        {
            int n = A.numRows;

            if (n != A.numCols)
            {
                throw new ArgumentException("A must be square");
            }

            if (x.NumElements != n)
            {
                throw new ArgumentException("Unexpected number of elements in x");
            }
            if (y.NumElements != n)
            {
                throw new ArgumentException("Unexpected number of elements in y");
            }

            double result = 0;

            for (int i = 0; i < n; i++)
            {
                double total = 0;

                for (int j = 0; j < n; j++)
                {
                    total += x.get(j) * A.unsafe_get(i, j);
                }

                result += total * y.get(i);
            }

            return(result);
        }
        /**
         * <p>
         * Multiplies a householder reflection against a vector:<br>
         * <br>
         * y = (I + &gamma; u u<sup>T</sup>)x<br>
         * </p>
         * <p>
         * The Householder reflection is used in some implementations of QR decomposition.
         * </p>
         *
         * @param u A vector. Not modified.
         * @param x a vector. Not modified.
         * @param y Vector where the result are written to.
         */
        public static void householder(double gamma,
                                       DMatrixD1 u,
                                       DMatrixD1 x, DMatrixD1 y)
        {
            int n = u.NumElements;

            double sum = 0;

            for (int i = 0; i < n; i++)
            {
                sum += u.get(i) * x.get(i);
            }
            for (int i = 0; i < n; i++)
            {
                y.set(i, x.get(i) + gamma * u.get(i) * sum);
            }
        }
Beispiel #9
0
        /**
         * <p>
         * Performs a matrix vector multiply.<br>
         * <br>
         * C = C + A * B <br>
         * or<br>
         * C = C + A * B<sup>T</sup> <br>
         * <br>
         * c<sub>i</sub> = Sum{ j=1:n, c<sub>i</sub> + a<sub>ij</sub> * b<sub>j</sub>}<br>
         * <br>
         * where A is a matrix, B is a column or transposed row vector, and C is a column vector.
         * </p>
         *
         * @param A A matrix that is m by n. Not modified.
         * @param B A vector that has length n. Not modified.
         * @param C A column vector that has length m. Modified.
         */
        public static void multAdd(DMatrix1Row A, DMatrixD1 B, DMatrixD1 C)
        {
            if (B.numRows == 1)
            {
                if (A.numCols != B.numCols)
                {
                    throw new MatrixDimensionException("A and B are not compatible");
                }
            }
            else if (B.numCols == 1)
            {
                if (A.numCols != B.numRows)
                {
                    throw new MatrixDimensionException("A and B are not compatible");
                }
            }
            else
            {
                throw new MatrixDimensionException("B is not a vector");
            }
            if (A.numRows != C.NumElements)
            {
                throw new MatrixDimensionException("C is not compatible with A");
            }

            if (A.numCols == 0)
            {
                return;
            }

            int indexA = 0;
            int cIndex = 0;

            for (int i = 0; i < A.numRows; i++)
            {
                double total = A.get(indexA++) * B.get(0);

                for (int j = 1; j < A.numCols; j++)
                {
                    total += A.get(indexA++) * B.get(j);
                }

                C.plus(cIndex++, total);
            }
        }
        public static void elementDiv(DMatrixD1 A, DMatrixD1 B)
        {
            UtilEjml.checkSameShape(A, B, true);

            int length = A.NumElements;

            for (int i = 0; i < length; i++)
            {
                A.div(i, B.get(i));
            }
        }
        /**
         * Checks to see if any element in the matrix is NaN.
         *
         * @param m A matrix. Not modified.
         * @return True if any element in the matrix is NaN.
         */
        public static bool hasNaN(DMatrixD1 m)
        {
            int length = m.NumElements;

            for (int i = 0; i < length; i++)
            {
                if (Double.IsNaN(m.get(i)))
                {
                    return(true);
                }
            }
            return(false);
        }
        /**
         * <p>
         * Computes the inner product of the two vectors.  In geometry this is known as the dot product.<br>
         * <br>
         * &sum;<sub>k=1:n</sub> x<sub>k</sub> * y<sub>k</sub><br>
         * where x and y are vectors with n elements.
         * </p>
         *
         * <p>
         * These functions are often used inside of highly optimized code and therefor sanity checks are
         * kept to a minimum.  It is not recommended that any of these functions be used directly.
         * </p>
         *
         * @param x A vector with n elements. Not modified.
         * @param y A vector with n elements. Not modified.
         * @return The inner product of the two vectors.
         */
        public static double innerProd(DMatrixD1 x, DMatrixD1 y)
        {
            int m = x.NumElements;

            double total = 0;

            for (int i = 0; i < m; i++)
            {
                total += x.get(i) * y.get(i);
            }

            return(total);
        }
        public static double elementSumAbs(DMatrixD1 mat)
        {
            double total = 0;

            int size = mat.NumElements;

            for (int i = 0; i < size; i++)
            {
                total += Math.Abs(mat.get(i));
            }

            return(total);
        }
        /**
         * Checks to see all the elements in the matrix are zeros
         *
         * @param m A matrix. Not modified.
         * @return True if all elements are zeros or false if not
         */
        public static bool isZeros(DMatrixD1 m, double tol)
        {
            int length = m.NumElements;

            for (int i = 0; i < length; i++)
            {
                if (Math.Abs(m.get(i)) > tol)
                {
                    return(false);
                }
            }
            return(true);
        }
        /**
         * Checks to see if any element in the matrix is NaN of Infinite.
         *
         * @param m A matrix. Not modified.
         * @return True if any element in the matrix is NaN of Infinite.
         */
        public static bool hasUncountable(DMatrixD1 m)
        {
            int length = m.NumElements;

            for (int i = 0; i < length; i++)
            {
                double a = m.get(i);
                if (Double.IsNaN(a) || Double.IsInfinity(a))
                {
                    return(true);
                }
            }
            return(false);
        }
Beispiel #16
0
        /**
         * <p>
         * This implementation of the Frobenius norm is a straight forward implementation and can
         * be susceptible for overflow/underflow issues.  A more resilient implementation is
         * {@link #normF}.
         * </p>
         *
         * @param a The matrix whose norm is computed.  Not modified.
         */
        public static double fastNormF(DMatrixD1 a)
        {
            double total = 0;

            int size = a.getNumElements();

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

            return(Math.Sqrt(total));
        }
        /**
         * <p>
         * Sets A &isin; &real; <sup>m &times; n</sup> equal to an outer product multiplication of the two
         * vectors.  This is also known as a rank-1 operation.<br>
         * <br>
         * A = x * y'
         * where x &isin; &real; <sup>m</sup> and y &isin; &real; <sup>n</sup> are vectors.
         * </p>
         * <p>
         * Which is equivalent to: A<sub>ij</sub> = x<sub>i</sub>*y<sub>j</sub>
         * </p>
         *
         * <p>
         * These functions are often used inside of highly optimized code and therefor sanity checks are
         * kept to a minimum.  It is not recommended that any of these functions be used directly.
         * </p>
         *
         * @param x A vector with m elements. Not modified.
         * @param y A vector with n elements. Not modified.
         * @param A A Matrix with m by n elements. Modified.
         */
        public static void outerProd(DMatrixD1 x, DMatrixD1 y, DMatrix1Row A)
        {
            int m = A.numRows;
            int n = A.numCols;

            int index = 0;

            for (int i = 0; i < m; i++)
            {
                double xdat = x.get(i);
                for (int j = 0; j < n; j++)
                {
                    A.set(index++, xdat * y.get(j));
                }
            }
        }
Beispiel #18
0
        /**
         * <p>
         * Computes the F norm of the difference between the two Matrices:<br>
         * <br>
         * Sqrt{&sum;<sub>i=1:m</sub> &sum;<sub>j=1:n</sub> ( a<sub>ij</sub> - b<sub>ij</sub>)<sup>2</sup>}
         * </p>
         * <p>
         * This is often used as a cost function.
         * </p>
         *
         * @see NormOps_DDRM#fastNormF
         *
         * @param a m by n matrix. Not modified.
         * @param b m by n matrix. Not modified.
         *
         * @return The F normal of the difference matrix.
         */
        public static double diffNormF(DMatrixD1 a, DMatrixD1 b)
        {
            if (a.numRows != b.numRows || a.numCols != b.numCols)
            {
                throw new ArgumentException("Both matrices must have the same shape.");
            }

            int size = a.getNumElements();

            DMatrixRMaj diff = new DMatrixRMaj(size, 1);

            for (int i = 0; i < size; i++)
            {
                diff.set(i, b.get(i) - a.get(i));
            }
            return(NormOps_DDRM.normF(diff));
        }
Beispiel #19
0
        /**
         * <p>
         * Computes the p=1 p-norm of the difference between the two Matrices:<br>
         * <br>
         * &sum;<sub>i=1:m</sub> &sum;<sub>j=1:n</sub> | a<sub>ij</sub> - b<sub>ij</sub>| <br>
         * <br>
         * where |x| is the absolute value of x.
         * </p>
         * <p>
         * This is often used as a cost function.
         * </p>
         *
         * @param a m by n matrix. Not modified.
         * @param b m by n matrix. Not modified.
         *
         * @return The p=1 p-norm of the difference matrix.
         */
        public static double diffNormP1(DMatrixD1 a, DMatrixD1 b)
        {
            if (a.numRows != b.numRows || a.numCols != b.numCols)
            {
                throw new ArgumentException("Both matrices must have the same shape.");
            }

            int size = a.getNumElements();

            double total = 0;

            for (int i = 0; i < size; i++)
            {
                total += Math.Abs(b.get(i) - a.get(i));
            }
            return(total);
        }
Beispiel #20
0
        /**
         * <p>
         * Returns the absolute value of the digonal element in the matrix that has the largest absolute value.<br>
         * <br>
         * Max{ |a<sub>ij</sub>| } for all i and j<br>
         * </p>
         *
         * @param a A matrix. Not modified.
         * @return The max abs element value of the matrix.
         */
        public static double elementDiagonalMaxAbs(DMatrixD1 a)
        {
            int size = Math.Min(a.numRows, a.numCols);

            double max = 0;

            for (int i = 0; i < size; i++)
            {
                double val = Math.Abs(a.get(i, i));
                if (val > max)
                {
                    max = val;
                }
            }

            return(max);
        }
        /**
         * <p>
         * Performs a matrix vector multiply.<br>
         * <br>
         * C = C + A<sup>T</sup> * B <br>
         * or<br>
         * C = C<sup>T</sup> + A<sup>T</sup> * B<sup>T</sup> <br>
         * <br>
         * c<sub>i</sub> = Sum{ j=1:n, c<sub>i</sub> + a<sub>ji</sub> * b<sub>j</sub>}<br>
         * <br>
         * where A is a matrix, B is a column or transposed row vector, and C is a column vector.
         * </p>
         * <p>
         * This implementation is optimal for small matrices.  There is a huge performance hit when
         * used on large matrices due to CPU cache issues.
         * </p>
         *
         * @param A A matrix that is m by n. Not modified.
         * @param B A vector that has length m. Not modified.
         * @param C A column vector that has length n. Modified.
         */
        public static void multAddTransA_small(DMatrix1Row A, DMatrixD1 B, DMatrixD1 C)
        {
            if (C.numCols != 1)
            {
                throw new MatrixDimensionException("C is not a column vector");
            }
            else if (C.numRows != A.numCols)
            {
                throw new MatrixDimensionException("C is not the expected length");
            }
            if (B.numRows == 1)
            {
                if (A.numRows != B.numCols)
                {
                    throw new MatrixDimensionException("A and B are not compatible");
                }
            }
            else if (B.numCols == 1)
            {
                if (A.numRows != B.numRows)
                {
                    throw new MatrixDimensionException("A and B are not compatible");
                }
            }
            else
            {
                throw new MatrixDimensionException("B is not a vector");
            }

            int cIndex = 0;

            for (int i = 0; i < A.numCols; i++)
            {
                double total = 0.0;

                int indexA = i;
                for (int j = 0; j < A.numRows; j++)
                {
                    total  += A.get(indexA) * B.get(j);
                    indexA += A.numCols;
                }

                C.plus(cIndex++, total);
            }
        }
        public static double diffNormF_fast(DMatrixD1 a, DMatrixD1 b)
        {
            if (a.numRows != b.numRows || a.numCols != b.numCols)
            {
                throw new ArgumentException("Both matrices must have the same shape.");
            }

            int size = a.NumElements;

            double total = 0;

            for (int i = 0; i < size; i++)
            {
                double diff = b.get(i) - a.get(i);
                total += diff * diff;
            }
            return(Math.Sqrt(total));
        }
        /**
         * <p>
         * Checks to see if each element in the two matrices are equal:
         * a<sub>ij</sub> == b<sub>ij</sub>
         * <p>
         *
         * <p>
         * NOTE: If any of the elements are NaN then false is returned.  If two corresponding
         * elements are both positive or negative infinity then they are equal.
         * </p>
         *
         * @param a A matrix. Not modified.
         * @param b A matrix. Not modified.
         * @return true if identical and false otherwise.
         */
        public static bool isEquals(DMatrixD1 a, DMatrixD1 b)
        {
            if (a.numRows != b.numRows || a.numCols != b.numCols)
            {
                return(false);
            }

            int length = a.NumElements;

            for (int i = 0; i < length; i++)
            {
                if (!(a.get(i) == b.get(i)))
                {
                    return(false);
                }
            }

            return(true);
        }
        /**
         * <p>
         * Checks to see if the two matrices are the negative of each other:<br>
         * <br>
         * a<sub>ij</sub> = -b<sub>ij</sub>
         * </p>
         *
         * @param a First matrix.  Not modified.
         * @param b Second matrix.  Not modified.
         * @param tol Numerical tolerance.
         * @return True if they are the negative of each other within tolerance.
         */
        public static bool isNegative(DMatrixD1 a, DMatrixD1 b, double tol)
        {
            if (a.numRows != b.numRows || a.numCols != b.numCols)
            {
                throw new ArgumentException("Matrix dimensions must match");
            }

            int length = a.NumElements;

            for (int i = 0; i < length; i++)
            {
                if (!(Math.Abs(a.get(i) + b.get(i)) <= tol))
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #25
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));
        }
Beispiel #26
0
        /**
         * <p>
         * Performs a matrix vector multiply.<br>
         * <br>
         * C = A<sup>T</sup> * B <br>
         * where B is a column vector.<br>
         * or<br>
         * C = A<sup>T</sup> * B<sup>T</sup> <br>
         * where B is a row vector. <br>
         * <br>
         * c<sub>i</sub> = Sum{ j=1:n, a<sub>ji</sub> * b<sub>j</sub>}<br>
         * <br>
         * where A is a matrix, B is a column or transposed row vector, and C is a column vector.
         * </p>
         * <p>
         * This implementation is optimal for small matrices.  There is a huge performance hit when
         * used on large matrices due to CPU cache issues.
         * </p>
         *
         * @param A A matrix that is m by n. Not modified.
         * @param B A that has length m and is a column. Not modified.
         * @param C A column vector that has length n. Modified.
         */
        public static void multTransA_small(DMatrix1Row A, DMatrixD1 B, DMatrixD1 C)
        {
            if (B.numRows == 1)
            {
                if (A.numRows != B.numCols)
                {
                    throw new MatrixDimensionException("A and B are not compatible");
                }
            }
            else if (B.numCols == 1)
            {
                if (A.numRows != B.numRows)
                {
                    throw new MatrixDimensionException("A and B are not compatible");
                }
            }
            else
            {
                throw new MatrixDimensionException("B is not a vector");
            }

            C.reshape(A.numCols, 1);

            int cIndex = 0;

            for (int i = 0; i < A.numCols; i++)
            {
                double total = 0.0;

                int indexA = i;
                for (int j = 0; j < A.numRows; j++)
                {
                    total  += A.get(indexA) * B.get(j);
                    indexA += A.numCols;
                }

                C.set(cIndex++, total);
            }
        }
Beispiel #27
0
        /**
         * Same as {@link #elementP} but runs faster by not mitigating overflow/underflow related problems.
         *
         * @param A Matrix. Not modified.
         * @param p p value.
         * @return The norm's value.
         */
        public static double fastElementP(DMatrixD1 A, double p)
        {
            if (p == 2)
            {
                return(fastNormF(A));
            }
            else
            {
                double total = 0;

                int size = A.getNumElements();

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

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

                return(Math.Pow(total, 1.0 / p));
            }
        }
        /**
         * <p>
         * Checks to see if each element in the two matrices are within tolerance of
         * each other: tol &ge; |a<sub>ij</sub> - b<sub>ij</sub>|.
         * <p>
         *
         * <p>
         * NOTE: If any of the elements are not countable then false is returned.<br>
         * NOTE: If a tolerance of zero is passed in this is equivalent to calling
         * {@link #isEquals(DMatrixD1, DMatrixD1)}
         * </p>
         *
         * @param a A matrix. Not modified.
         * @param b A matrix. Not modified.
         * @param tol How close to being identical each element needs to be.
         * @return true if equals and false otherwise.
         */
        public static bool isEquals(DMatrixD1 a, DMatrixD1 b, double tol)
        {
            if (a.numRows != b.numRows || a.numCols != b.numCols)
            {
                return(false);
            }

            if (tol == 0.0)
            {
                return(isEquals(a, b));
            }

            int length = a.NumElements;

            for (int i = 0; i < length; i++)
            {
                if (!(tol >= Math.Abs(a.get(i) - b.get(i))))
                {
                    return(false);
                }
            }
            return(true);
        }
        /**
         * <p>
         * Checks to see if each corresponding element in the two matrices are
         * within tolerance of each other or have the some symbolic meaning.  This
         * can handle NaN and Infinite numbers.
         * <p>
         *
         * <p>
         * If both elements are countable then the following equality test is used:<br>
         * |a<sub>ij</sub> - b<sub>ij</sub>| &le; tol.<br>
         * Otherwise both numbers must both be Double.NaN, Double.POSITIVE_INFINITY, or
         * Double.NEGATIVE_INFINITY to be identical.
         * </p>
         *
         * @param a A matrix. Not modified.
         * @param b A matrix. Not modified.
         * @param tol Tolerance for equality.
         * @return true if identical and false otherwise.
         */
        public static bool isIdentical(DMatrixD1 a, DMatrixD1 b, double tol)
        {
            if (a.numRows != b.numRows || a.numCols != b.numCols)
            {
                return(false);
            }
            if (tol < 0)
            {
                throw new ArgumentException("Tolerance must be greater than or equal to zero.");
            }

            int length = a.NumElements;

            for (int i = 0; i < length; i++)
            {
                if (!UtilEjml.isIdentical(a.get(i), b.get(i), tol))
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #30
0
        /**
         * An alternative implementation of {@link #multAddTransA_small} that performs well on large
         * matrices.  There is a relative performance hit when used on small matrices.
         *
         * @param A A matrix that is m by n. Not modified.
         * @param B A vector that has length m. Not modified.
         * @param C A column vector that has length n. Modified.
         */
        public static void multAddTransA_reorder(DMatrix1Row A, DMatrixD1 B, DMatrixD1 C)
        {
            if (B.numRows == 1)
            {
                if (A.numRows != B.numCols)
                {
                    throw new MatrixDimensionException("A and B are not compatible");
                }
            }
            else if (B.numCols == 1)
            {
                if (A.numRows != B.numRows)
                {
                    throw new MatrixDimensionException("A and B are not compatible");
                }
            }
            else
            {
                throw new MatrixDimensionException("B is not a vector");
            }
            if (A.numCols != C.NumElements)
            {
                throw new MatrixDimensionException("C is not compatible with A");
            }

            int indexA = 0;

            for (int j = 0; j < A.numRows; j++)
            {
                double B_val = B.get(j);
                for (int i = 0; i < A.numCols; i++)
                {
                    C.plus(i, A.get(indexA++) * B_val);
                }
            }
        }