Exemple #1
0
        /**
         * <p>
         * Performs the following operation:<br>
         * <br>
         * B = A + &alpha;I
         * <p>
         *
         * @param A A square matrix.  Not modified.
         * @param B A square matrix that the results are saved to.  Modified.
         * @param alpha Scaling factor for the identity matrix.
         */
        public static void addIdentity(DMatrix1Row A, DMatrix1Row B, double alpha)
        {
            if (A.numCols != A.numRows)
            {
                throw new ArgumentException("A must be square");
            }
            if (B.numCols != A.numCols || B.numRows != A.numRows)
            {
                throw new ArgumentException("B must be the same shape as A");
            }

            int n = A.numCols;

            int index = 0;

            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++, index++)
                {
                    if (i == j)
                    {
                        B.set(index, A.get(index) + alpha);
                    }
                    else
                    {
                        B.set(index, A.get(index));
                    }
                }
            }
        }
        /**
         * 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);
            }
        }
Exemple #4
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));
            }
        }
 /**
  * <p>
  * Extracts a row or column vector from matrix A.  The first element in the matrix is at element (rowA,colA).
  * The next 'length' elements are extracted along a row or column.  The results are put into vector 'v'
  * start at its element v0.
  * </p>
  *
  * @param A Matrix that the vector is being extracted from.  Not modified.
  * @param rowA Row of the first element that is extracted.
  * @param colA Column of the first element that is extracted.
  * @param length Length of the extracted vector.
  * @param row If true a row vector is extracted, otherwise a column vector is extracted.
  * @param offsetV First element in 'v' where the results are extracted to.
  * @param v Vector where the results are written to. Modified.
  */
 public static void subvector(DMatrix1Row A, int rowA, int colA, int length, bool row, int offsetV, DMatrix1Row v)
 {
     if (row)
     {
         for (int i = 0; i < length; i++)
         {
             v.set(offsetV + i, A.get(rowA, colA + i));
         }
     }
     else
     {
         for (int i = 0; i < length; i++)
         {
             v.set(offsetV + i, A.get(rowA + i, colA));
         }
     }
 }
Exemple #6
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 setSubMatrix(DMatrix1Row src, DMatrix1Row dst,
                                 int srcRow, int srcCol, int dstRow, int dstCol,
                                 int numSubRows, int numSubCols)
 {
     for (int i = 0; i < numSubRows; i++)
     {
         for (int j = 0; j < numSubCols; j++)
         {
             double val = src.get(i + srcRow, j + srcCol);
             dst.set(i + dstRow, j + dstCol, val);
         }
     }
 }
        /**
         * <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);
            }
        }
Exemple #9
0
        private void createMinor(DMatrix1Row mat)
        {
            int w        = minWidth - 1;
            int firstRow = (width - w) * width;

            for (int i = 0; i < numOpen; i++)
            {
                int col      = open[i];
                int srcIndex = firstRow + col;
                int dstIndex = i;

                for (int j = 0; j < w; j++)
                {
                    tempMat.set(dstIndex, mat.get(srcIndex));
                    dstIndex += w;
                    srcIndex += width;
                }
            }
        }
Exemple #10
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);
            }
        }
Exemple #11
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);
                }
            }
        }
Exemple #12
0
        /**
         * Computes the determinant for the specified matrix.  It must be square and have
         * the same width and height as what was specified in the constructor.
         *
         * @param mat The matrix whose determinant is to be computed.
         * @return The determinant.
         */
        public double compute(DMatrix1Row mat)
        {
            if (width != mat.numCols || width != mat.numRows)
            {
                throw new InvalidOperationException("Unexpected matrix dimension");
            }

            // make sure everything is in the proper state before it starts
            initStructures();

//        Array.Copy(mat.data,0,minorMatrix[0],0,mat.data.Length);

            int level = 0;

            while (true)
            {
                int levelWidth = width - level;
                int levelIndex = levelIndexes[level];

                if (levelIndex == levelWidth)
                {
                    if (level == 0)
                    {
                        return(levelResults[0]);
                    }
                    int prevLevelIndex = levelIndexes[level - 1]++;

                    double val = mat.get((level - 1) * width + levelRemoved[level - 1]);
                    if (prevLevelIndex % 2 == 0)
                    {
                        levelResults[level - 1] += val * levelResults[level];
                    }
                    else
                    {
                        levelResults[level - 1] -= val * levelResults[level];
                    }

                    putIntoOpen(level - 1);

                    levelResults[level] = 0;
                    levelIndexes[level] = 0;
                    level--;
                }
                else
                {
                    int excluded = openRemove(levelIndex);

                    levelRemoved[level] = excluded;

                    if (levelWidth == minWidth)
                    {
                        createMinor(mat);
                        double subresult = mat.get(level * width + levelRemoved[level]);

                        subresult *= UnrolledDeterminantFromMinor_DDRM.det(tempMat);

                        if (levelIndex % 2 == 0)
                        {
                            levelResults[level] += subresult;
                        }
                        else
                        {
                            levelResults[level] -= subresult;
                        }

                        // put it back into the list
                        putIntoOpen(level);
                        levelIndexes[level]++;
                    }
                    else
                    {
                        level++;
                    }
                }
            }
        }