/// <inheritdoc/>
        /// <exception cref="NumberIsTooLargeException"> if <c>m</c> is an
        /// <c>OpenMapRealMatrix</c>, and the total number of entries of the product
        /// is larger than <c>Int32.MaxValue</c>.</exception>
        public new RealMatrix multiply(RealMatrix m)
        {
            try
            {
                return(multiply((OpenMapRealMatrix)m));
            }
            catch (InvalidCastException)
            {
                MatrixUtils.checkMultiplicationCompatible(this, m);

                int             outCols = m.getColumnDimension();
                BlockRealMatrix outp    = new BlockRealMatrix(rows, outCols);
                for (OpenIntToDoubleHashMap.Iterator iterator = entries.iterator(); iterator.MoveNext();)
                {
                    double value = iterator.Current.Value;
                    int    key   = iterator.Current.Key;
                    int    i     = key / columns;
                    int    k     = key % columns;
                    for (int j = 0; j < outCols; ++j)
                    {
                        outp.addToEntry(i, j, value * m.getEntry(k, j));
                    }
                }
                return(outp);
            }
        }
        /**
         * {@inheritDoc}
         *
         * @throws NumberIsTooLargeException if {@code m} is an
         * {@code OpenMapRealMatrix}, and the total number of entries of the product
         * is larger than {@code Integer.MAX_VALUE}.
         */
        public override RealMatrix multiply(RealMatrix m)
        {
            try {
                return(multiply((OpenMapRealMatrix)m));
            } catch (InvalidCastException cce) {
                //MatrixUtils.checkMultiplicationCompatible(this, m);

                int             outCols = m.getColumnDimension();
                BlockRealMatrix @out    = new BlockRealMatrix(rows, outCols);
                for (OpenIntToDoubleHashMap.Iterator iterator = entries.iterator(); iterator.hasNext();)
                {
                    iterator.advance();
                    double value = iterator.value();
                    int    key   = iterator.key();
                    int    i     = key / columns;
                    int    k     = key % columns;
                    for (int j = 0; j < outCols; ++j)
                    {
                        @out.addToEntry(i, j, value * m.getEntry(k, j));
                    }
                }

                return(@out);
            }
        }
        /// <summary>
        /// Subtract <c>m</c> from this matrix.
        /// </summary>
        /// <param name="m">Matrix to be subtracted.</param>
        /// <returns><c>this</c> - <c>m</c>.</returns>
        /// <exception cref="MatrixDimensionMismatchException"> if <c>m</c> is not the same
        /// size as <c>this</c>.</exception>
        public OpenMapRealMatrix subtract(OpenMapRealMatrix m)
        {
            MatrixUtils.checkAdditionCompatible(this, m);

            OpenMapRealMatrix outp = new OpenMapRealMatrix(this);

            for (OpenIntToDoubleHashMap.Iterator iterator = m.entries.iterator(); iterator.MoveNext();)
            {
                int row = iterator.Current.Key / columns;
                int col = iterator.Current.Key - row * columns;
                outp.setEntry(row, col, getEntry(row, col) - iterator.Current.Value);
            }

            return(outp);
        }
        /**
         * Compute the sum of this matrix and {@code m}.
         *
         * @param m Matrix to be added.
         * @return {@code this} + {@code m}.
         * @throws MatrixDimensionMismatchException if {@code m} is not the same
         * size as {@code this}.
         */
        public OpenMapRealMatrix add(OpenMapRealMatrix m)
        {
            //MatrixUtils.checkAdditionCompatible(this, m);

            OpenMapRealMatrix @out = new OpenMapRealMatrix(this);

            for (OpenIntToDoubleHashMap.Iterator iterator = m.entries.iterator(); iterator.hasNext();)
            {
                iterator.advance();
                int row = iterator.key() / columns;
                int col = iterator.key() - row * columns;
                @out.setEntry(row, col, getEntry(row, col) + iterator.value());
            }

            return(@out);
        }
        /**
         * Postmultiply this matrix by {@code m}.
         *
         * @param m Matrix to postmultiply by.
         * @return {@code this} * {@code m}.
         * @throws DimensionMismatchException if the number of rows of {@code m}
         * differ from the number of columns of {@code this} matrix.
         * @throws NumberIsTooLargeException if the total number of entries of the
         * product is larger than {@code Integer.MAX_VALUE}.
         */
        public OpenMapRealMatrix multiply(OpenMapRealMatrix m)
        {
            // Safety check.
            //MatrixUtils.checkMultiplicationCompatible(this, m);

            int outCols            = m.getColumnDimension();
            OpenMapRealMatrix @out = new OpenMapRealMatrix(rows, outCols);

            for (OpenIntToDoubleHashMap.Iterator iterator = entries.iterator(); iterator.hasNext();)
            {
                iterator.advance();
                double value = iterator.value();
                int    key   = iterator.key();
                int    i     = key / columns;
                int    k     = key % columns;
                for (int j = 0; j < outCols; ++j)
                {
                    int rightKey = m.computeKey(k, j);
                    if (m.entries.containsKey(rightKey))
                    {
                        int    outKey   = @out.computeKey(i, j);
                        double outValue =
                            @out.entries.get(outKey) + value * m.entries.get(rightKey);
                        if (outValue == 0.0)
                        {
                            @out.entries.remove(outKey);
                        }
                        else
                        {
                            @out.entries.put(outKey, outValue);
                        }
                    }
                }
            }

            return(@out);
        }
        /// <summary>
        /// Postmultiply this matrix by <c>m</c>.
        /// </summary>
        /// <param name="m">Matrix to postmultiply by.</param>
        /// <returns><c>this</c> * <c>m</c>.</returns>
        /// <exception cref="DimensionMismatchException"> if the number of rows of <c>m</c>
        /// differ from the number of columns of <c>this</c> matrix.</exception>
        /// <exception cref="NumberIsTooLargeException"> if the total number of entries of the
        /// product is larger than <c>Int32.MaxValue</c>.</exception>
        public OpenMapRealMatrix multiply(OpenMapRealMatrix m)
        {
            // Safety check.
            MatrixUtils.checkMultiplicationCompatible(this, m);

            int outCols            = m.getColumnDimension();
            OpenMapRealMatrix outp = new OpenMapRealMatrix(rows, outCols);

            for (OpenIntToDoubleHashMap.Iterator iterator = entries.iterator(); iterator.MoveNext();)
            {
                double value = iterator.Current.Value;
                int    key   = iterator.Current.Key;
                int    i     = key / columns;
                int    k     = key % columns;
                for (int j = 0; j < outCols; ++j)
                {
                    int rightKey = m.computeKey(k, j);
                    if (m.entries.containsKey(rightKey))
                    {
                        int    outKey   = outp.computeKey(i, j);
                        double outValue =
                            outp.entries.get(outKey) + value * m.entries.get(rightKey);
                        if (outValue == 0.0)
                        {
                            outp.entries.remove(outKey);
                        }
                        else
                        {
                            outp.entries.put(outKey, outValue);
                        }
                    }
                }
            }

            return(outp);
        }