/**
         * 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);
        }
        /**
         * {@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);
            }
        }
        /**
         * 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);
        }