/**
         * 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);
            }
        }
        /**
         * <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);
            }
        }
        /**
         * <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 (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.set(cIndex++, total);
            }
        }
Beispiel #5
0
 public void set(int row, int col, double value)
 {
     original.set(row + row0, col + col0, value);
 }