Esempio n. 1
0
        /// <summary>
        /// Returns <c>this</c> minus <c>m</c>.
        /// </summary>
        /// <param name="m">Matrix to be subtracted.</param>
        /// <returns><c>this - m</c>.</returns>
        /// <exception cref="MatrixDimensionMismatchException"> if <c>m</c> is not the same
        /// size as <c>this</c>.</exception>
        public Array2DRowRealMatrix subtract(Array2DRowRealMatrix m)
        {
            MatrixUtils.checkSubtractionCompatible(this, m);

            int rowCount    = getRowDimension();
            int columnCount = getColumnDimension();

            double[][] outData = new double[rowCount][];
            for (int row = 0; row < rowCount; row++)
            {
                double[] dataRow    = data[row];
                double[] mRow       = m.data[row];
                double[] outDataRow = outData[row];
                for (int col = 0; col < columnCount; col++)
                {
                    outDataRow[col] = dataRow[col] - mRow[col];
                }
            }

            return(new Array2DRowRealMatrix(outData, false));
        }
Esempio n. 2
0
        /// <summary>
        /// Returns the result of postmultiplying <c>this</c> by <c>m</c>.
        /// </summary>
        /// <param name="m">matrix to postmultiply by</param>
        /// <returns><c>this * m</c></returns>
        /// <exception cref="DimensionMismatchException"> if
        /// <c>columnDimension(this) != rowDimension(m)</c></exception>
        public Array2DRowRealMatrix multiply(Array2DRowRealMatrix m)
        {
            MatrixUtils.checkMultiplicationCompatible(this, m);

            int nRows = this.getRowDimension();
            int nCols = m.getColumnDimension();
            int nSum  = this.getColumnDimension();

            double[][] outData = new double[nRows][];
            // Will hold a column of "m".
            double[]   mCol  = new double[nSum];
            double[][] mData = m.data;

            // Multiply.
            for (int col = 0; col < nCols; col++)
            {
                // Copy all elements of column "col" of "m" so that
                // will be in contiguous memory.
                for (int mRow = 0; mRow < nSum; mRow++)
                {
                    mCol[mRow] = mData[mRow][col];
                }

                for (int row = 0; row < nRows; row++)
                {
                    double[] dataRow = data[row];
                    double   sum     = 0;
                    for (int i = 0; i < nSum; i++)
                    {
                        sum += dataRow[i] * mCol[i];
                    }
                    outData[row][col] = sum;
                }
            }

            return(new Array2DRowRealMatrix(outData, false));
        }
        /// <summary>
        /// Returns the n &times; n covariance matrix.
        /// <para>The covariance matrix is V &times; J &times; V^T
        /// where J is the diagonal matrix of the inverse of the squares of
        /// the singular values.</para>
        /// </summary>
        /// <param name="minSingularValue">value below which singular values are ignored
        /// (a 0 or negative value implies all singular value will be used)</param>
        /// <returns>covariance matrix</returns>
        /// <exception cref="IllegalArgumentException"> if minSingularValue is larger than
        /// the largest singular value, meaning all singular values are ignored</exception>
        public RealMatrix getCovariance(double minSingularValue)
        {
            // get the number of singular values to consider
            int p         = singularValues.Length;
            int dimension = 0;

            while (dimension < p &&
                   singularValues[dimension] >= minSingularValue)
            {
                ++dimension;
            }

            if (dimension == 0)
            {
                throw new NumberIsTooLargeException <Double, Double>(new LocalizedFormats("TOO_LARGE_CUTOFF_SINGULAR_VALUE"), minSingularValue, singularValues[0], true);
            }

            double[][] data = new double[dimension][];
            getVT().walkInOptimizedOrder(new DefaultRealMatrixPreservingVisitorAnonymous(data, singularValues), 0, dimension - 1, 0, p - 1);

            RealMatrix jv = new Array2DRowRealMatrix(data, false);

            return(jv.transpose().multiply(jv));
        }
        /// <summary>
        /// Computes the inverse of the given matrix by splitting it into
        /// 4 sub-matrices.
        /// </summary>
        /// <param name="m">Matrix whose inverse must be computed.</param>
        /// <param name="splitIndex">Index that determines the "split" line and
        /// column.
        /// The element corresponding to this index will part of the
        /// upper-left sub-matrix.</param>
        /// <returns>the inverse of <c>m</c>.</returns>
        /// <exception cref="NonSquareMatrixException"> if <c>m</c> is not square.</exception>
        public static RealMatrix blockInverse(RealMatrix m, int splitIndex)
        {
            int n = m.getRowDimension();

            if (m.getColumnDimension() != n)
            {
                throw new NonSquareMatrixException(m.getRowDimension(),
                                                   m.getColumnDimension());
            }

            int splitIndex1 = splitIndex + 1;

            RealMatrix a = m.getSubMatrix(0, splitIndex, 0, splitIndex);
            RealMatrix b = m.getSubMatrix(0, splitIndex, splitIndex1, n - 1);
            RealMatrix c = m.getSubMatrix(splitIndex1, n - 1, 0, splitIndex);
            RealMatrix d = m.getSubMatrix(splitIndex1, n - 1, splitIndex1, n - 1);

            SingularValueDecomposition aDec    = new SingularValueDecomposition(a);
            DecompositionSolver        aSolver = aDec.getSolver();

            if (!aSolver.isNonSingular())
            {
                throw new SingularMatrixException();
            }
            RealMatrix aInv = aSolver.getInverse();

            SingularValueDecomposition dDec    = new SingularValueDecomposition(d);
            DecompositionSolver        dSolver = dDec.getSolver();

            if (!dSolver.isNonSingular())
            {
                throw new SingularMatrixException();
            }
            RealMatrix dInv = dSolver.getInverse();

            RealMatrix tmp1 = a.subtract(b.multiply(dInv).multiply(c));
            SingularValueDecomposition tmp1Dec    = new SingularValueDecomposition(tmp1);
            DecompositionSolver        tmp1Solver = tmp1Dec.getSolver();

            if (!tmp1Solver.isNonSingular())
            {
                throw new SingularMatrixException();
            }
            RealMatrix result00 = tmp1Solver.getInverse();

            RealMatrix tmp2 = d.subtract(c.multiply(aInv).multiply(b));
            SingularValueDecomposition tmp2Dec    = new SingularValueDecomposition(tmp2);
            DecompositionSolver        tmp2Solver = tmp2Dec.getSolver();

            if (!tmp2Solver.isNonSingular())
            {
                throw new SingularMatrixException();
            }
            RealMatrix result11 = tmp2Solver.getInverse();

            RealMatrix result01 = aInv.multiply(b).multiply(result11).scalarMultiply(-1);
            RealMatrix result10 = dInv.multiply(c).multiply(result00).scalarMultiply(-1);

            RealMatrix result = new Array2DRowRealMatrix(n, n);

            result.setSubMatrix(result00.getData(), 0, 0);
            result.setSubMatrix(result01.getData(), 0, splitIndex1);
            result.setSubMatrix(result10.getData(), splitIndex1, 0);
            result.setSubMatrix(result11.getData(), splitIndex1, splitIndex1);

            return(result);
        }