You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by er...@apache.org on 2019/10/28 01:45:59 UTC

[commons-math] branch master updated (3fc2520 -> 471d4d6)

This is an automated email from the ASF dual-hosted git repository.

erans pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/commons-math.git.


    from 3fc2520  Use a generator with a low overhead.
     new 78e4c98  Remove redundant declarations/definitions.
     new 7acf4d9  Add "default" methods.
     new 2e219c3  Use methods defined in "AnyMatrix".
     new 1285231  MATH-1499: Matrix whose entries are elements of a field.
     new 407f1e7  Code upgraded following MATH-1499.
     new ec77f54  MATH-1500: LU decomposition for a matrix whose entries are elements of a field.
     new 9988a5b  Code upgraded following MATH-1500.
     new 471d4d6  MATH-1500 (unit tests).

The 8 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../field/linalg/FieldDecompositionSolver.java     |  59 ++++
 .../math4/field/linalg/FieldDenseMatrix.java       | 343 ++++++++++++++++++++
 .../math4/field/linalg/FieldLUDecomposition.java   | 361 +++++++++++++++++++++
 .../linalg}/package-info.java                      |   7 +-
 .../interpolation => field}/package-info.java      |   8 +-
 .../commons/math4/linear/AbstractFieldMatrix.java  |  66 +---
 .../commons/math4/linear/AbstractRealMatrix.java   |  28 +-
 .../org/apache/commons/math4/linear/AnyMatrix.java |  66 +++-
 .../math4/linear/Array2DRowFieldMatrix.java        |   6 +-
 .../commons/math4/linear/Array2DRowRealMatrix.java |   6 +-
 .../commons/math4/linear/BlockFieldMatrix.java     |  12 +-
 .../commons/math4/linear/BlockRealMatrix.java      |  12 +-
 .../apache/commons/math4/linear/MatrixUtils.java   |  27 +-
 .../ode/nonstiff/AdamsNordsieckTransformer.java    |  72 ++--
 .../stat/inference/KolmogorovSmirnovTest.java      |  12 +-
 .../field/linalg/FP64FieldDenseMatrixTest.java     | 285 ++++++++++++++++
 .../field/linalg/FieldLUDecompositionTest.java     | 314 ++++++++++++++++++
 17 files changed, 1503 insertions(+), 181 deletions(-)
 create mode 100644 src/main/java/org/apache/commons/math4/field/linalg/FieldDecompositionSolver.java
 create mode 100644 src/main/java/org/apache/commons/math4/field/linalg/FieldDenseMatrix.java
 create mode 100644 src/main/java/org/apache/commons/math4/field/linalg/FieldLUDecomposition.java
 copy src/main/java/org/apache/commons/math4/{analysis/interpolation => field/linalg}/package-info.java (81%)
 copy src/main/java/org/apache/commons/math4/{analysis/interpolation => field}/package-info.java (78%)
 create mode 100644 src/test/java/org/apache/commons/math4/field/linalg/FP64FieldDenseMatrixTest.java
 create mode 100644 src/test/java/org/apache/commons/math4/field/linalg/FieldLUDecompositionTest.java


[commons-math] 06/08: MATH-1500: LU decomposition for a matrix whose entries are elements of a field.

Posted by er...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

erans pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-math.git

commit ec77f54bef7e60de920307bd75ce44a2fa104670
Author: Gilles Sadowski <gi...@harfang.homelinux.org>
AuthorDate: Sun Oct 27 15:10:11 2019 +0100

    MATH-1500: LU decomposition for a matrix whose entries are elements of a field.
---
 .../field/linalg/FieldDecompositionSolver.java     |  59 ++++
 .../math4/field/linalg/FieldLUDecomposition.java   | 361 +++++++++++++++++++++
 .../field/linalg/FieldLUDecompositionTest.java     | 267 +++++++++++++++
 3 files changed, 687 insertions(+)

diff --git a/src/main/java/org/apache/commons/math4/field/linalg/FieldDecompositionSolver.java b/src/main/java/org/apache/commons/math4/field/linalg/FieldDecompositionSolver.java
new file mode 100644
index 0000000..0136062
--- /dev/null
+++ b/src/main/java/org/apache/commons/math4/field/linalg/FieldDecompositionSolver.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.math4.field.linalg;
+
+import java.util.List;
+
+/**
+ * Interface handling decomposition algorithms that can solve {@code A X = B}.
+ *
+ * <p>Decomposition algorithms decompose an A matrix has a product of several specific
+ * matrices from which they can solve the above system of equations in a least-squares
+ * sense: Find X such that {@code ||A X - B||} is minimal.</p>
+ *
+ * <p>Some solvers like {@link FieldLUDecomposition} can only find the solution for
+ * square matrices and when the solution is an exact linear solution, i.e. when
+ * {@code ||A X - B||} is exactly 0.
+ * Other solvers can also find solutions with non-square matrix {@code A} and with
+ * non-zero minimal norm.
+ * If an exact linear solution exists it is also the minimal norm solution.</p>
+ *
+ * @param <T> Type of the field elements.
+ *
+ * @since 4.0
+ */
+public interface FieldDecompositionSolver<T> {
+    /**
+     * Solves the linear equation {@code A X = B}.
+     *
+     * <p>Matrix {@code A} is implicit: It is provided by the underlying
+     * decomposition algorithm.</p>
+     *
+     * @param b Right-hand side of the equation.
+     * @return the matrix {@code X} that minimizes {@code ||A X - B||}.
+     * @throws IllegalArgumentException if the dimensions do not match.
+     */
+    FieldDenseMatrix<T> solve(final FieldDenseMatrix<T> b);
+
+    /**
+     * Computes the inverse of a decomposed (square) matrix.
+     *
+     * @return the inverse matrix.
+     */
+    FieldDenseMatrix<T> getInverse();
+}
diff --git a/src/main/java/org/apache/commons/math4/field/linalg/FieldLUDecomposition.java b/src/main/java/org/apache/commons/math4/field/linalg/FieldLUDecomposition.java
new file mode 100644
index 0000000..ab53e29
--- /dev/null
+++ b/src/main/java/org/apache/commons/math4/field/linalg/FieldLUDecomposition.java
@@ -0,0 +1,361 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.math4.field.linalg;
+
+import java.util.List;
+import java.util.ArrayList;
+import org.apache.commons.numbers.field.Field;
+import org.apache.commons.math4.linear.SingularMatrixException;
+import org.apache.commons.math4.exception.DimensionMismatchException;
+
+/**
+ * Calculates the LUP-decomposition of a square matrix.
+ *
+ * <p>The LUP-decomposition of a matrix A consists of three matrices
+ * L, U and P that satisfy: PA = LU, L is lower triangular, and U is
+ * upper triangular and P is a permutation matrix. All matrices are
+ * m&times;m.</p>
+ *
+ * <p>Since {@link Field field} elements do not provide an ordering
+ * operator, the permutation matrix is computed here only in order to
+ * avoid a zero pivot element, no attempt is done to get the largest
+ * pivot element.</p>
+ *
+ * @param <T> Type of the field elements.
+ *
+ * @see <a href="http://mathworld.wolfram.com/LUDecomposition.html">MathWorld</a>
+ * @see <a href="http://en.wikipedia.org/wiki/LU_decomposition">Wikipedia</a>
+ *
+ * @since 4.0
+ */
+public class FieldLUDecomposition<T> {
+    /** Field to which the elements belong. */
+    private final Field<T> field;
+    /** Entries of LU decomposition. */
+    private final FieldDenseMatrix<T> mLU;
+    /** Pivot permutation associated with LU decomposition. */
+    private final int[] pivot;
+    /** Singularity indicator. */
+    private final boolean isSingular;
+    /** Parity of the permutation associated with the LU decomposition. */
+    private final boolean isEven;
+
+    /**
+     * Calculates the LU-decomposition of the given {@code matrix}.
+     *
+     * @param matrix Matrix to decompose.
+     * @throws IllegalArgumentException if the matrix is not square.
+     */
+    private FieldLUDecomposition(FieldDenseMatrix<T> matrix) {
+        matrix.checkMultiply(matrix);
+
+        field = matrix.getField();
+        final int m = matrix.getRowDimension();
+        pivot = new int[m];
+
+        // Initialize permutation array and parity.
+        for (int row = 0; row < m; row++) {
+            pivot[row] = row;
+        }
+        mLU = matrix.copy();
+
+        boolean even = true;
+        boolean singular = false;
+        // Loop over columns.
+        for (int col = 0; col < m; col++) {
+            T sum = field.zero();
+
+            // Upper.
+            for (int row = 0; row < col; row++) {
+                sum = mLU.get(row, col);
+                for (int i = 0; i < row; i++) {
+                    sum = field.subtract(sum,
+                                         field.multiply(mLU.get(row, i),
+                                                        mLU.get(i, col)));
+                }
+                mLU.set(row, col, sum);
+            }
+
+            // Lower.
+            int nonZero = col; // Permutation row.
+            for (int row = col; row < m; row++) {
+                sum = mLU.get(row, col);
+                for (int i = 0; i < col; i++) {
+                    sum = field.subtract(sum,
+                                         field.multiply(mLU.get(row, i),
+                                                        mLU.get(i, col)));
+                }
+                mLU.set(row, col, sum);
+
+                if (mLU.get(nonZero, col).equals(field.zero())) {
+                    // try to select a better permutation choice
+                    ++nonZero;
+                }
+            }
+
+            // Singularity check.
+            if (nonZero >= m) {
+                singular = true;
+            } else {
+                // Pivot if necessary.
+                if (nonZero != col) {
+                    T tmp = field.zero();
+                    for (int i = 0; i < m; i++) {
+                        tmp = mLU.get(nonZero, i);
+                        mLU.set(nonZero, i, mLU.get(col, i));
+                        mLU.set(col, i, tmp);
+                    }
+                    int temp = pivot[nonZero];
+                    pivot[nonZero] = pivot[col];
+                    pivot[col] = temp;
+                    even = !even;
+                }
+
+                // Divide the lower elements by the "winning" diagonal element.
+                final T luDiag = mLU.get(col, col);
+                for (int row = col + 1; row < m; row++) {
+                    mLU.set(row, col, field.divide(mLU.get(row, col),
+                                                   luDiag));
+                }
+            }
+        }
+
+        isSingular = singular;
+        isEven = even;
+    }
+
+    /**
+     * Factory method.
+     *
+     * @param m Matrix to decompose.
+     * @return a new instance.
+     */
+    public static <T> FieldLUDecomposition<T> of(FieldDenseMatrix<T> m) {
+        return new FieldLUDecomposition<>(m);
+    }
+
+    /**
+     * @return {@code true} if the matrix is singular.
+     */
+    public boolean isSingular() {
+        return isSingular;
+    }
+
+    /**
+     * Builds the "L" matrix of the decomposition.
+     *
+     * @return the lower triangular matrix.
+     * @throws SingularMatrixException if the matrix is singular.
+     */
+    public FieldDenseMatrix<T> getL() {
+        if (isSingular) {
+            throw new SingularMatrixException();
+        }
+
+        final int m = pivot.length;
+        final FieldDenseMatrix<T> mL = FieldDenseMatrix.zero(field, m, m);
+        for (int i = 0; i < m; i++) {
+            for (int j = 0; j < i; j++) {
+                mL.set(i, j, mLU.get(i, j));
+            }
+            mL.set(i, i, field.one());
+        }
+
+        return mL;
+    }
+
+    /**
+     * Builds the "U" matrix of the decomposition.
+     *
+     * @return the upper triangular matrix.
+     * @throws SingularMatrixException if the matrix is singular.
+     */
+    public FieldDenseMatrix<T> getU() {
+        if (isSingular) {
+            throw new SingularMatrixException();
+        }
+
+        final int m = pivot.length;
+        final FieldDenseMatrix<T> mU = FieldDenseMatrix.zero(field, m, m);
+        for (int i = 0; i < m; i++) {
+            for (int j = i; j < m; j++) {
+                mU.set(i, j, mLU.get(i, j));
+            }
+        }
+
+        return mU;
+    }
+
+    /**
+     * Builds the "P" matrix.
+     *
+     * <p>P is a matrix with exactly one element set to {@link Field#one() one} in
+     * each row and each column, all other elements being set to {@link Field#zero() zero}.
+     * The positions of the "one" elements are given by the {@link #getPivot()
+     * pivot permutation vector}.</p>
+     * @return the "P" rows permutation matrix.
+     * @throws SingularMatrixException if the matrix is singular.
+     *
+     * @see #getPivot()
+     */
+    public FieldDenseMatrix<T> getP() {
+        if (isSingular) {
+            throw new SingularMatrixException();
+        }
+
+        final int m = pivot.length;
+        final FieldDenseMatrix<T> mP = FieldDenseMatrix.zero(field, m, m);
+
+        for (int i = 0; i < m; i++) {
+            mP.set(i, pivot[i], field.one());
+        }
+
+        return mP;
+    }
+
+    /**
+     * Gets the pivot permutation vector.
+     *
+     * @return the pivot permutation vector.
+     *
+     * @see #getP()
+     */
+    public int[] getPivot() {
+        return pivot.clone();
+    }
+
+    /**
+     * Return the determinant of the matrix.
+     * @return determinant of the matrix
+     */
+    public T getDeterminant() {
+        if (isSingular) {
+            return field.zero();
+        } else {
+            final int m = pivot.length;
+            T determinant = isEven ?
+                field.one() :
+                field.negate(field.one());
+
+            for (int i = 0; i < m; i++) {
+                determinant = field.multiply(determinant,
+                                             mLU.get(i, i));
+            }
+
+            return determinant;
+        }
+    }
+
+    /**
+     * Creates a solver for finding the solution {@code X} of the linear
+     * system of equations {@code A X = B}.
+     *
+     * @return a solver.
+     * @throws SingularMatrixException if the matrix is singular.
+     */
+    public FieldDecompositionSolver<T> getSolver() {
+        if (isSingular) {
+            throw new SingularMatrixException();
+        }
+
+        return new Solver<>(mLU, pivot);
+    }
+
+    /**
+     * Specialized solver.
+     *
+     * @param <T> Type of the field elements.
+     */
+    private static class Solver<T> implements FieldDecompositionSolver<T> {
+        /** Field to which the elements belong. */
+        private final Field<T> field;
+        /** LU decomposition. */
+        private final FieldDenseMatrix<T> mLU;
+        /** Pivot permutation associated with LU decomposition. */
+        private final int[] pivot;
+
+        /**
+         * Builds a solver from a LU-decomposed matrix.
+         *
+         * @param mLU LU matrix.
+         * @param pivot Pivot permutation associated with the decomposition.
+         */
+        private Solver(final FieldDenseMatrix<T> mLU,
+                       final int[] pivot) {
+            field = mLU.getField();
+            this.mLU = mLU.copy();
+            this.pivot = pivot.clone();
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public FieldDenseMatrix<T> solve(final FieldDenseMatrix<T> b) {
+            mLU.checkMultiply(b);
+
+            final FieldDenseMatrix<T> bp = b.copy();
+            final int nColB = b.getColumnDimension();
+            final int m = pivot.length;
+
+            // Apply permutations.
+            for (int row = 0; row < m; row++) {
+                final int pRow = pivot[row];
+                for (int col = 0; col < nColB; col++) {
+                    bp.set(row, col,
+                           b.get(row, col));
+                }
+            }
+
+            // Solve LY = b
+            for (int col = 0; col < m; col++) {
+                for (int i = col + 1; i < m; i++) {
+                    for (int j = 0; j < nColB; j++) {
+                        bp.set(i, j,
+                               field.subtract(bp.get(i, j),
+                                              field.multiply(bp.get(col, j),
+                                                             mLU.get(i, col))));
+                    }
+                }
+            }
+
+            // Solve UX = Y
+            for (int col = m - 1; col >= 0; col--) {
+                for (int j = 0; j < nColB; j++) {
+                    bp.set(col, j,
+                           field.divide(bp.get(col, j),
+                                        mLU.get(col, col)));
+                }
+                for (int i = 0; i < col; i++) {
+                    for (int j = 0; j < nColB; j++) {
+                        bp.set(i, j,
+                               field.subtract(bp.get(i, j),
+                                              field.multiply(bp.get(col, j),
+                                                             mLU.get(i, col))));
+                    }
+                }
+            }
+
+            return bp;
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public FieldDenseMatrix<T> getInverse() {
+            return solve(FieldDenseMatrix.identity(field, pivot.length));
+        }
+    }
+}
diff --git a/src/test/java/org/apache/commons/math4/field/linalg/FieldLUDecompositionTest.java b/src/test/java/org/apache/commons/math4/field/linalg/FieldLUDecompositionTest.java
new file mode 100644
index 0000000..b756643
--- /dev/null
+++ b/src/test/java/org/apache/commons/math4/field/linalg/FieldLUDecompositionTest.java
@@ -0,0 +1,267 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.math4.field.linalg;
+
+import org.apache.commons.numbers.fraction.Fraction;
+import org.apache.commons.numbers.field.FractionField;
+import org.junit.Test;
+import org.junit.Assert;
+import org.apache.commons.math4.linear.NonSquareMatrixException;
+import org.apache.commons.math4.linear.SingularMatrixException;
+
+public class FieldLUDecompositionTest {
+    private final Fraction[][] testData = {
+            { Fraction.of(1), Fraction.of(2), Fraction.of(3)},
+            { Fraction.of(2), Fraction.of(5), Fraction.of(3)},
+            { Fraction.of(1), Fraction.of(0), Fraction.of(8)}
+    };
+    private final Fraction[][] testDataMinus = {
+            { Fraction.of(-1), Fraction.of(-2), Fraction.of(-3)},
+            { Fraction.of(-2), Fraction.of(-5), Fraction.of(-3)},
+            { Fraction.of(-1), Fraction.of(0), Fraction.of(-8)}
+    };
+    private final Fraction[][] luData = {
+            { Fraction.of(2), Fraction.of(3), Fraction.of(3) },
+            { Fraction.of(2), Fraction.of(3), Fraction.of(7) },
+            { Fraction.of(6), Fraction.of(6), Fraction.of(8) }
+    };
+
+    // singular matrices
+    private final Fraction[][] singular = {
+            { Fraction.of(2), Fraction.of(3) },
+            { Fraction.of(2), Fraction.of(3) }
+    };
+    private final Fraction[][] bigSingular = {
+            { Fraction.of(1), Fraction.of(2), Fraction.of(3), Fraction.of(4) },
+            { Fraction.of(2), Fraction.of(5), Fraction.of(3), Fraction.of(4) },
+            { Fraction.of(7), Fraction.of(3), Fraction.of(256), Fraction.of(1930) },
+            { Fraction.of(3), Fraction.of(7), Fraction.of(6), Fraction.of(8) }
+    }; // 4th row = 1st + 2nd
+
+    /**
+     * @param data Matrix.
+     * @return a {@link FieldDenseMatrix} instance.
+     */
+    private FieldDenseMatrix<Fraction> create(Fraction[][] data) {
+        final FieldDenseMatrix<Fraction> m = FieldDenseMatrix.create(FractionField.get(),
+                                                                     data.length,
+                                                                     data[0].length);
+        for (int i = 0; i < data.length; i++) {
+            for (int j = 0; j < data.length; j++) {
+                m.set(i, j, data[i][j]);
+            }
+        }
+
+        return m;
+    }
+
+    /** test dimensions */
+    @Test
+    public void testDimensions() {
+        FieldDenseMatrix<Fraction> matrix = create(testData);
+        FieldLUDecomposition<Fraction> LU = FieldLUDecomposition.of(matrix);
+        Assert.assertEquals(testData.length, LU.getL().getRowDimension());
+        Assert.assertEquals(testData.length, LU.getU().getRowDimension());
+        Assert.assertEquals(testData.length, LU.getP().getRowDimension());
+    }
+
+    /** test PA = LU */
+    @Test
+    public void testPAEqualLU() {
+        FieldDenseMatrix<Fraction> matrix = create(testData);
+        FieldLUDecomposition<Fraction> lu = FieldLUDecomposition.of(matrix);
+        FieldDenseMatrix<Fraction> l = lu.getL();
+        FieldDenseMatrix<Fraction> u = lu.getU();
+        FieldDenseMatrix<Fraction> p = lu.getP();
+        Assert.assertEquals(p.multiply(matrix), l.multiply(u));
+
+        matrix = create(testDataMinus);
+        lu = FieldLUDecomposition.of(matrix);
+        l = lu.getL();
+        u = lu.getU();
+        p = lu.getP();
+        Assert.assertEquals(p.multiply(matrix), l.multiply(u));
+
+        matrix = FieldDenseMatrix.identity(FractionField.get(), 17);
+        lu = FieldLUDecomposition.of(matrix);
+        l = lu.getL();
+        u = lu.getU();
+        p = lu.getP();
+        Assert.assertEquals(p.multiply(matrix), l.multiply(u));
+    }
+
+    /** test that L is lower triangular with unit diagonal */
+    @Test
+    public void testLLowerTriangular() {
+        FieldDenseMatrix<Fraction> matrix = create(testData);
+        FieldDenseMatrix<Fraction> l = FieldLUDecomposition.of(matrix).getL();
+        for (int i = 0; i < l.getRowDimension(); i++) {
+            Assert.assertEquals(Fraction.ONE, l.get(i, i));
+            for (int j = i + 1; j < l.getColumnDimension(); j++) {
+                Assert.assertEquals(Fraction.ZERO, l.get(i, j));
+            }
+        }
+    }
+
+    /** test that U is upper triangular */
+    @Test
+    public void testUUpperTriangular() {
+        FieldDenseMatrix<Fraction> matrix = create(testData);
+        FieldDenseMatrix<Fraction> u = FieldLUDecomposition.of(matrix).getU();
+        for (int i = 0; i < u.getRowDimension(); i++) {
+            for (int j = 0; j < i; j++) {
+                Assert.assertEquals(Fraction.ZERO, u.get(i, j));
+            }
+        }
+    }
+
+    /** test that P is a permutation matrix */
+    @Test
+    public void testPPermutation() {
+        FieldDenseMatrix<Fraction> matrix = create(testData);
+        FieldDenseMatrix<Fraction> p = FieldLUDecomposition.of(matrix).getP();
+
+        FieldDenseMatrix<Fraction> ppT = p.multiply(p.transpose());
+        FieldDenseMatrix<Fraction> id = FieldDenseMatrix.identity(FractionField.get(),
+                                                                  p.getRowDimension());
+        Assert.assertEquals(id, ppT);
+
+        for (int i = 0; i < p.getRowDimension(); i++) {
+            int zeroCount = 0;
+            int oneCount = 0;
+            int otherCount = 0;
+            for (int j = 0; j < p.getColumnDimension(); j++) {
+                final Fraction e = p.get(i, j);
+                if (e.equals(Fraction.ZERO)) {
+                    ++zeroCount;
+                } else if (e.equals(Fraction.ONE)) {
+                    ++oneCount;
+                } else {
+                    ++otherCount;
+                }
+            }
+            Assert.assertEquals(p.getRowDimension() - 1, zeroCount);
+            Assert.assertEquals(1, oneCount);
+            Assert.assertEquals(0, otherCount);
+        }
+
+        for (int j = 0; j < p.getRowDimension(); j++) {
+            int zeroCount = 0;
+            int oneCount = 0;
+            int otherCount = 0;
+            for (int i = 0; i < p.getColumnDimension(); i++) {
+                final Fraction e = p.get(i, j);
+                if (e.equals(Fraction.ZERO)) {
+                    ++zeroCount;
+                } else if (e.equals(Fraction.ONE)) {
+                    ++oneCount;
+                } else {
+                    ++otherCount;
+                }
+            }
+            Assert.assertEquals(p.getRowDimension() - 1, zeroCount);
+            Assert.assertEquals(1, oneCount);
+            Assert.assertEquals(0, otherCount);
+        }
+    }
+
+    @Test
+    public void testIsSingular1() {
+        FieldLUDecomposition<Fraction> lu = FieldLUDecomposition.of(create(testData));
+        Assert.assertFalse(lu.isSingular());
+        lu.getSolver();
+    }
+    @Test(expected=SingularMatrixException.class)
+    public void testIsSingular2() {
+        FieldLUDecomposition<Fraction> lu = FieldLUDecomposition.of(create(singular));
+        Assert.assertTrue(lu.isSingular());
+        lu.getSolver();
+    }
+    @Test(expected=SingularMatrixException.class)
+    public void testIsSingular3() {
+        FieldLUDecomposition<Fraction> lu = FieldLUDecomposition.of(create(bigSingular));
+        Assert.assertTrue(lu.isSingular());
+        lu.getSolver();
+    }
+
+    @Test
+    public void testMatricesValues1() {
+        FieldLUDecomposition<Fraction> lu = FieldLUDecomposition.of(create(testData));
+        FieldDenseMatrix<Fraction> lRef = create(new Fraction[][] {
+                { Fraction.of(1), Fraction.of(0), Fraction.of(0) },
+                { Fraction.of(2), Fraction.of(1), Fraction.of(0) },
+                { Fraction.of(1), Fraction.of(-2), Fraction.of(1) }
+            });
+        FieldDenseMatrix<Fraction> uRef = create(new Fraction[][] {
+                { Fraction.of(1),  Fraction.of(2), Fraction.of(3) },
+                { Fraction.of(0), Fraction.of(1), Fraction.of(-3) },
+                { Fraction.of(0),  Fraction.of(0), Fraction.of(-1) }
+            });
+        FieldDenseMatrix<Fraction> pRef = create(new Fraction[][] {
+                { Fraction.of(1), Fraction.of(0), Fraction.of(0) },
+                { Fraction.of(0), Fraction.of(1), Fraction.of(0) },
+                { Fraction.of(0), Fraction.of(0), Fraction.of(1) }
+            });
+        int[] pivotRef = { 0, 1, 2 };
+
+        // check values against known references
+        FieldDenseMatrix<Fraction> l = lu.getL();
+        Assert.assertEquals(lRef, l);
+        FieldDenseMatrix<Fraction> u = lu.getU();
+        Assert.assertEquals(uRef, u);
+        FieldDenseMatrix<Fraction> p = lu.getP();
+        Assert.assertEquals(pRef, p);
+        int[] pivot = lu.getPivot();
+        for (int i = 0; i < pivotRef.length; ++i) {
+            Assert.assertEquals(pivotRef[i], pivot[i]);
+        }
+    }
+
+    @Test
+    public void testMatricesValues2() {
+        FieldLUDecomposition<Fraction> lu = FieldLUDecomposition.of(create(luData));
+        FieldDenseMatrix<Fraction> lRef = create(new Fraction[][] {
+                { Fraction.of(1), Fraction.of(0), Fraction.of(0) },
+                { Fraction.of(3), Fraction.of(1), Fraction.of(0) },
+                { Fraction.of(1), Fraction.of(0), Fraction.of(1) }
+            });
+        FieldDenseMatrix<Fraction> uRef = create(new Fraction[][] {
+                { Fraction.of(2), Fraction.of(3), Fraction.of(3)    },
+                { Fraction.of(0), Fraction.of(-3), Fraction.of(-1)  },
+                { Fraction.of(0), Fraction.of(0), Fraction.of(4) }
+            });
+        FieldDenseMatrix<Fraction> pRef = create(new Fraction[][] {
+                { Fraction.of(1), Fraction.of(0), Fraction.of(0) },
+                { Fraction.of(0), Fraction.of(0), Fraction.of(1) },
+                { Fraction.of(0), Fraction.of(1), Fraction.of(0) }
+            });
+        int[] pivotRef = { 0, 2, 1 };
+
+        // check values against known references
+        FieldDenseMatrix<Fraction> l = lu.getL();
+        Assert.assertEquals(lRef, l);
+        FieldDenseMatrix<Fraction> u = lu.getU();
+        Assert.assertEquals(uRef, u);
+        FieldDenseMatrix<Fraction> p = lu.getP();
+        Assert.assertEquals(pRef, p);
+        int[] pivot = lu.getPivot();
+        for (int i = 0; i < pivotRef.length; ++i) {
+            Assert.assertEquals(pivotRef[i], pivot[i]);
+        }
+    }
+}


[commons-math] 04/08: MATH-1499: Matrix whose entries are elements of a field.

Posted by er...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

erans pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-math.git

commit 128523112bdbad85b6b5c925004c0e975be5d553
Author: Gilles Sadowski <gi...@harfang.homelinux.org>
AuthorDate: Sun Oct 27 14:59:19 2019 +0100

    MATH-1499: Matrix whose entries are elements of a field.
---
 .../math4/field/linalg/FieldDenseMatrix.java       | 343 +++++++++++++++++++++
 .../commons/math4/field/linalg/package-info.java   |  21 ++
 .../apache/commons/math4/field/package-info.java   |  22 ++
 .../field/linalg/FP64FieldDenseMatrixTest.java     | 285 +++++++++++++++++
 4 files changed, 671 insertions(+)

diff --git a/src/main/java/org/apache/commons/math4/field/linalg/FieldDenseMatrix.java b/src/main/java/org/apache/commons/math4/field/linalg/FieldDenseMatrix.java
new file mode 100644
index 0000000..8fd0dc1
--- /dev/null
+++ b/src/main/java/org/apache/commons/math4/field/linalg/FieldDenseMatrix.java
@@ -0,0 +1,343 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math4.field.linalg;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.ArrayList;
+import org.apache.commons.numbers.field.Field;
+import org.apache.commons.math4.linear.AnyMatrix;
+
+/**
+ * Square matrix whose elements define a {@link Field}.
+ *
+ * @param <T> Type of the field elements.
+ *
+ * @since 4.0
+ */
+public class FieldDenseMatrix<T>
+    implements AnyMatrix {
+    /** Field. */
+    private final Field<T> field;
+    /** Number of rows. */
+    private final int rows;
+    /** Number of columns. */
+    private final int columns;
+    /** Data storage (in row-major order). */
+    private final T[] data;
+
+    /**
+     * @param f Field.
+     * @param r Number of rows.
+     * @param c Number of columns.
+     * @throws IllegalArgumentException if {@code r <= 0} or {@code c <= 0}.
+     */
+    protected FieldDenseMatrix(Field<T> f,
+                               int r,
+                               int c) {
+        if (r <= 0 ||
+            c <= 0) {
+            throw new IllegalArgumentException("Negative size");
+        }
+
+        field = f;
+        rows = r;
+        columns = c;
+        data = (T[]) new Object[r * c];
+    }
+
+    /**
+     * Factory method.
+     *
+     * @param f Field.
+     * @param r Number of rows.
+     * @param c Number of columns.
+     * @throws IllegalArgumentException if {@code r <= 0} or {@code c <= 0}.
+     */
+    public static <T> FieldDenseMatrix<T> create(Field<T> f,
+                                                 int r,
+                                                 int c) {
+        return new FieldDenseMatrix<>(f, r, c);
+    }
+
+    /**
+     * Factory method.
+     *
+     * @param f Field.
+     * @param r Number of rows.
+     * @param c Number of columns.
+     * @throws IllegalArgumentException if {@code r <= 0} or {@code c <= 0}.
+     * @return a matrix with elements zet to {@link Field#zero() zero}.
+     */
+    public static <T> FieldDenseMatrix<T> zero(Field<T> f,
+                                               int r,
+                                               int c) {
+        return create(f, r, c).fill(f.zero());
+    }
+
+    /**
+     * Factory method.
+     *
+     * @param f Field.
+     * @param n Dimension of the matrix.
+     * @return the identity matrix.
+     * @throws IllegalArgumentException if {@code n <= 0}.
+     */
+    public static <T> FieldDenseMatrix<T> identity(Field<T> f,
+                                                   int n) {
+        final FieldDenseMatrix<T> r = zero(f, n, n);
+
+        for (int i = 0; i < n; i++) {
+            r.set(i, i, f.one());
+        }
+
+        return r;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        } else {
+            if (other instanceof FieldDenseMatrix) {
+                final FieldDenseMatrix<?> m = (FieldDenseMatrix<?>) other;
+                return field.equals(m.field) &&
+                    rows == m.rows &&
+                    columns == m.columns &&
+                    Arrays.equals(data, m.data);
+            } else {
+                return false;
+            }
+        }
+    }
+
+    /**
+     * Copies this matrix.
+     *
+     * @return a new instance.
+     */
+    public FieldDenseMatrix<T> copy() {
+        final FieldDenseMatrix<T> r = create(field, rows, columns);
+        System.arraycopy(data, 0, r.data, 0, data.length);
+        return r;
+    }
+
+    /**
+     * Transposes this matrix.
+     *
+     * @return a new instance.
+     */
+    public FieldDenseMatrix<T> transpose() {
+        final FieldDenseMatrix<T> r = create(field, columns, rows);
+
+        for (int i = 0; i < rows; i++) {
+            for (int j = 0; j < columns; j++) {
+                r.set(j, i, get(i, j));
+            }
+        }
+
+        return r;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int getRowDimension() {
+        return rows;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int getColumnDimension() {
+        return columns;
+    }
+
+    /**
+     * @return the field associated with the matrix entries.
+     */
+    public Field<T> getField() {
+        return field;
+    }
+
+    /**
+     * Sets all elements to the given value.
+     *
+     * @param value Value of the elements of the matrix.
+     * @return {@code this}.
+     */
+    public FieldDenseMatrix<T> fill(T value) {
+        Arrays.fill(data, value);
+        return this;
+    }
+
+    /**
+     * Gets an element.
+     *
+     * @param i Row.
+     * @param j Column.
+     * @return the element at (i, j).
+     */
+    public T get(int i,
+                 int j) {
+        return data[i * columns + j];
+    }
+
+    /**
+     * Sets an element.
+     *
+     * @param i Row.
+     * @param j Column.
+     * @param value Value.
+     */
+    public void set(int i,
+                    int j,
+                    T value) {
+        data[i * columns + j] = value;
+    }
+
+    /**
+     * Addition.
+     *
+     * @param other Matrix to add.
+     * @return a new instance with the result of the addition.
+     * @throws IllegalArgumentException if the dimensions do not match.
+     */
+    public FieldDenseMatrix<T> add(FieldDenseMatrix<T> other) {
+        checkAdd(other);
+        final FieldDenseMatrix<T> r = create(field, rows, columns);
+
+        for (int i = 0; i < data.length; i++) {
+            r.data[i] = field.add(data[i], other.data[i]);
+        }
+
+        return r;
+    }
+
+    /**
+     * Subtraction.
+     *
+     * @param other Matrix to subtract.
+     * @return a new instance with the result of the subtraction.
+     * @throws IllegalArgumentException if the dimensions do not match.
+     */
+    public FieldDenseMatrix<T> subtract(FieldDenseMatrix<T> other) {
+        checkAdd(other);
+        final FieldDenseMatrix<T> r = create(field, rows, columns);
+
+        for (int i = 0; i < data.length; i++) {
+            r.data[i] = field.subtract(data[i], other.data[i]);
+        }
+
+        return r;
+    }
+
+    /**
+     * Negate.
+     *
+     * @return a new instance with the opposite matrix.
+     */
+    public FieldDenseMatrix<T> negate() {
+        final FieldDenseMatrix<T> r = create(field, rows, columns);
+
+        for (int i = 0; i < data.length; i++) {
+            r.data[i] = field.negate(data[i]);
+        }
+
+        return r;
+    }
+
+    /**
+     * Multiplication.
+     *
+     * @param other Matrix to multiply with.
+     * @return a new instance with the result of the multiplication.
+     * @throws IllegalArgumentException if the dimensions do not match.
+     */
+    public FieldDenseMatrix<T> multiply(FieldDenseMatrix<T> other) {
+        checkMultiply(other);
+        final FieldDenseMatrix<T> r = zero(field, rows, other.columns);
+
+        for (int i = 0; i < rows; i++) {
+            final int o1 = i * columns;
+            final int o2 = i * r.columns;
+            for (int j = 0; j < other.columns; j++) {
+                final int o3 = o2 + j;
+                for (int k = 0; k < columns; k++) {
+                    r.data[o3] = field.add(r.data[o3],
+                                           field.multiply(data[o1 + k],
+                                                          other.data[k * other.columns + j]));
+                }
+            }
+        }
+
+        return r;
+    }
+
+    /**
+     * Multiplies the matrix with itself {@code p} times.
+     *
+     * @param p Exponent.
+     * @return a new instance.
+     * @throws IllegalArgumentException if {@code p < 0}.
+     */
+    public FieldDenseMatrix<T> pow(int p) {
+        checkMultiply(this);
+
+        if (p < 0) {
+            throw new IllegalArgumentException("Negative exponent: " + p);
+        }
+
+        if (p == 0) {
+            return identity(field, rows);
+        }
+
+        if (p == 1) {
+            return copy();
+        }
+
+        final int power = p - 1;
+
+        // Only log_2(p) operations are necessary by doing as follows:
+        //    5^214 = 5^128 * 5^64 * 5^16 * 5^4 * 5^2
+        // The same approach is used for A^p.
+
+        final char[] binary = Integer.toBinaryString(power).toCharArray();
+        final ArrayList<Integer> nonZeroPositions = new ArrayList<>();
+
+        for (int i = 0; i < binary.length; i++) {
+            if (binary[i] == '1') {
+                final int pos = binary.length - i - 1;
+                nonZeroPositions.add(pos);
+            }
+        }
+
+        final List<FieldDenseMatrix<T>> results = new ArrayList<>(binary.length);
+        results.add(this);
+        for (int i = 1; i < binary.length; i++) {
+            final FieldDenseMatrix<T> s = results.get(i - 1);
+            final FieldDenseMatrix<T> r = s.multiply(s);
+            results.add(r);
+        }
+
+        FieldDenseMatrix<T> r = this;
+        for (Integer i : nonZeroPositions) {
+            r = r.multiply(results.get(i));
+        }
+
+        return r;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math4/field/linalg/package-info.java b/src/main/java/org/apache/commons/math4/field/linalg/package-info.java
new file mode 100644
index 0000000..3ee0946
--- /dev/null
+++ b/src/main/java/org/apache/commons/math4/field/linalg/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Linear algebra defined in term of matrices whose entries are elements
+ * of a {@link org.apache.commons.numbers.field.Field field}.
+ */
+package org.apache.commons.math4.field.linalg;
diff --git a/src/main/java/org/apache/commons/math4/field/package-info.java b/src/main/java/org/apache/commons/math4/field/package-info.java
new file mode 100644
index 0000000..f800a67
--- /dev/null
+++ b/src/main/java/org/apache/commons/math4/field/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Utilities based on the {@link org.apache.commons.numbers.field.Field Field}
+ * functionality defined in <a href="http://commons.apache.org/numbers">
+ * Commons Numbers</a>.
+ */
+package org.apache.commons.math4.field;
diff --git a/src/test/java/org/apache/commons/math4/field/linalg/FP64FieldDenseMatrixTest.java b/src/test/java/org/apache/commons/math4/field/linalg/FP64FieldDenseMatrixTest.java
new file mode 100644
index 0000000..55a1ea2
--- /dev/null
+++ b/src/test/java/org/apache/commons/math4/field/linalg/FP64FieldDenseMatrixTest.java
@@ -0,0 +1,285 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math4.field.linalg;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.apache.commons.numbers.field.FP64;
+import org.apache.commons.numbers.field.FP64Field;
+import org.apache.commons.math3.linear.RealMatrix;
+import org.apache.commons.math3.linear.Array2DRowRealMatrix;
+import org.apache.commons.math3.util.Pair;
+
+/**
+ * Tests for {@link FieldDenseMatrix} (using {@link FP64} as field elements).
+ */
+public class FP64FieldDenseMatrixTest {
+    @Test
+    public void testGetRowDimension() {
+        final int r = 6;
+        final int c = 9;
+        final FieldDenseMatrix<FP64> a = FieldDenseMatrix.create(FP64Field.get(), r, c);
+        Assert.assertEquals(r, a.getRowDimension());
+    }
+
+    @Test
+    public void testGetColumnDimension() {
+        final int r = 6;
+        final int c = 9;
+        final FieldDenseMatrix<FP64> a = FieldDenseMatrix.create(FP64Field.get(), r, c);
+        Assert.assertEquals(c, a.getColumnDimension());
+    }
+
+    @Test
+    public void testSetGet() {
+        final int r = 17;
+        final int c = 20;
+        final FieldDenseMatrix<FP64> a = FieldDenseMatrix.create(FP64Field.get(), r, c);
+
+        int count = 0;
+        for (int i = 0; i < r; i++) {
+            for (int j = 0; j < c; j++) {
+                a.set(i, j, FP64.of(count++));
+            }
+        }
+        Assert.assertEquals(r * c, count);
+
+        count = 0;
+        for (int i = 0; i < r; i++) {
+            for (int j = 0; j < c; j++) {
+                Assert.assertEquals((double) count++,
+                                    a.get(i, j).doubleValue(),
+                                    0d);
+            }
+        }
+    }
+
+    @Test
+    public void testAdd() {
+        final int r = 5;
+        final int c = 3;
+        final double scale = 1e3;
+        final Pair<FieldDenseMatrix<FP64>, RealMatrix> p1 = createRandom(r, c, scale);
+        final Pair<FieldDenseMatrix<FP64>, RealMatrix> p2 = createRandom(r, c, scale);
+
+        assertEquals(p1.getFirst().add(p2.getFirst()),
+                     p1.getSecond().add(p2.getSecond()),
+                     0d);
+    }
+
+    @Test
+    public void testSubtract() {
+        final int r = 2;
+        final int c = 6;
+        final double scale = 1e3;
+        final Pair<FieldDenseMatrix<FP64>, RealMatrix> p1 = createRandom(r, c, scale);
+        final Pair<FieldDenseMatrix<FP64>, RealMatrix> p2 = createRandom(r, c, scale);
+
+        assertEquals(p1.getFirst().subtract(p2.getFirst()),
+                     p1.getSecond().subtract(p2.getSecond()),
+                     0d);
+    }
+
+    @Test
+    public void testMultiply() {
+        final int r = 7;
+        final int c1 = 4;
+        final int c2 = 5;
+        final double scale = 1e2;
+        final Pair<FieldDenseMatrix<FP64>, RealMatrix> p1 = createRandom(r, c1, scale);
+        final Pair<FieldDenseMatrix<FP64>, RealMatrix> p2 = createRandom(c1, c2, scale);
+
+        assertEquals(p1.getFirst().multiply(p2.getFirst()),
+                     p1.getSecond().multiply(p2.getSecond()),
+                     0d);
+    }
+
+    @Test
+    public void testNegate() {
+        final int dim = 13;
+        final double scale = 1;
+        final Pair<FieldDenseMatrix<FP64>, RealMatrix> p = createRandom(dim, dim, scale);
+
+        assertEquals(p.getFirst().negate(),
+                     p.getSecond().scalarMultiply(-1),
+                     0d);
+    }
+
+    @Test
+    public void testPowZero() {
+        final int dim = 5;
+        final double scale = 1e100;
+        final Pair<FieldDenseMatrix<FP64>, RealMatrix> p = createRandom(dim, dim, scale);
+
+        final int exp = 0;
+        assertEquals(p.getFirst().pow(exp),
+                     p.getSecond().power(exp),
+                     0d);
+    }
+
+    @Test
+    public void testPowOne() {
+        final int dim = 5;
+        final double scale = 1e100;
+        final Pair<FieldDenseMatrix<FP64>, RealMatrix> p = createRandom(dim, dim, scale);
+
+        final int exp = 1;
+        assertEquals(p.getFirst().pow(exp),
+                     p.getSecond().power(exp),
+                     0d);
+    }
+
+    @Test
+    public void testPow() {
+        final int dim = 5;
+        final double scale = 1e2;
+        final Pair<FieldDenseMatrix<FP64>, RealMatrix> p = createRandom(dim, dim, scale);
+
+        final int exp = 4;
+        assertEquals(p.getFirst().pow(exp),
+                     p.getSecond().power(exp),
+                     0d);
+    }
+
+    @Test
+    public void testGetField() {
+        final FieldDenseMatrix<FP64> a = FieldDenseMatrix.create(FP64Field.get(), 7, 5);
+        Assert.assertEquals(FP64Field.get(), a.getField());
+    }
+
+    @Test
+    public void testEquals() {
+        // Reference equality.
+        final FieldDenseMatrix<FP64> a = FieldDenseMatrix.create(FP64Field.get(), 7, 2);
+        Assert.assertEquals(a, a);
+
+        // Dimension mismatch
+        final FieldDenseMatrix<FP64> b = FieldDenseMatrix.create(FP64Field.get(), 7, 3);
+        Assert.assertNotEquals(a, b);
+        final FieldDenseMatrix<FP64> c = FieldDenseMatrix.create(FP64Field.get(), 6, 2);
+        Assert.assertNotEquals(a, c);
+
+        // Contents.        
+        final FieldDenseMatrix<FP64> d = FieldDenseMatrix.create(FP64Field.get(), 7, 2);
+        Assert.assertEquals(a, d); // Unitialized contents.
+        a.fill(FP64.of(1.23456789));
+        d.fill(FP64.of(1.23456789));
+        Assert.assertEquals(a, d); // Initialized contents.
+        d.set(6, 1, d.get(6, 1).add(FP64.of(1e-15)));
+        Assert.assertNotEquals(a, d);
+    }
+
+    @Test
+    public void testCopy() {
+        final FieldDenseMatrix<FP64> a = FieldDenseMatrix.create(FP64Field.get(), 7, 3)
+            .fill(FP64Field.get().one());
+        final FieldDenseMatrix<FP64> b = a.copy();
+        Assert.assertEquals(a, b);
+
+        b.set(0, 0, FP64Field.get().zero());
+        Assert.assertNotEquals(a, b);
+    }
+
+    @Test
+    public void testTranspose() {
+        final int r = 4;
+        final int c = 5;
+        final FieldDenseMatrix<FP64> a = FieldDenseMatrix.create(FP64Field.get(), r, c);
+        for (int i = 0; i < r; i++) {
+            for (int j = 0; j < c; j++) {
+                final double j2 = j * j;
+                a.set(i, j,
+                      FP64.of(1.2 * i + 3.4 * j2));
+            }
+        }
+
+        final FieldDenseMatrix<FP64> b = a.transpose();
+        for (int i = 0; i < r; i++) {
+            for (int j = 0; j < c; j++) {
+                Assert.assertEquals(a.get(i, j), b.get(j, i));
+            }
+        }
+
+        Assert.assertEquals(a, b.transpose());
+    }
+
+    @Test
+    public void testIdentity() {
+        final int dim = 3;
+        final FieldDenseMatrix<FP64> a = FieldDenseMatrix.identity(FP64Field.get(), dim);
+        for (int i = 0; i < dim; i++) {
+            for (int j = 0; j < dim; j++) {
+                if (i == j) {
+                    Assert.assertEquals(FP64Field.get().one(),                                        a.get(i, j));
+                } else {
+                    Assert.assertEquals(FP64Field.get().zero(),
+                                        a.get(i, j));
+                }
+            }
+        }
+    }
+
+    /**
+     * Compares with result obtained from "Commons Math".
+     *
+     * @param a "o.a.c.m.field.linalg" result.
+     * @param b "o.a.c.m.linear" result.
+     * @param tol Tolerance.
+     */
+    private void assertEquals(FieldDenseMatrix<FP64> a,
+                              RealMatrix b,
+                              double tol) {
+        if (a.getRowDimension() != b.getRowDimension() ||
+            a.getColumnDimension() != b.getColumnDimension()) {
+            Assert.fail("Dimension mismatch"); 
+        }
+
+        for (int i = 0; i < a.getRowDimension(); i++) {
+            for (int j = 0; j < a.getColumnDimension(); j++) {
+                Assert.assertEquals("(" + i + ", " + j + ")",
+                                    a.get(i, j).doubleValue(),
+                                    b.getEntry(i, j),
+                                    tol);
+            }
+        }
+    }
+
+    /**
+     * Creates test matrices with random entries.
+     *
+     * @param r Rows.
+     * @param c Columns.
+     * @param scale Range of the entries.
+     * @return a pair of matrices whose entries are in the interval
+     * {@code [-scale, scale]}.
+     */
+    private Pair<FieldDenseMatrix<FP64>, RealMatrix> createRandom(int r,
+                                                                  int c,
+                                                                  double scale) {
+        final FieldDenseMatrix<FP64> a = FieldDenseMatrix.create(FP64Field.get(), r, c);
+        final RealMatrix b = new Array2DRowRealMatrix(r, c);
+        for (int i = 0; i < r; i++) {
+            for (int j = 0; j < c; j++) {
+                final double v = scale * (2 * Math.random() - 1);
+                a.set(i, j, FP64.of(v));
+                b.setEntry(i, j, v);
+            }
+        }
+
+        return new Pair<>(a, b);
+    }
+}


[commons-math] 03/08: Use methods defined in "AnyMatrix".

Posted by er...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

erans pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-math.git

commit 2e219c32e84331ec9883b661c61c446e1636165c
Author: Gilles Sadowski <gi...@harfang.homelinux.org>
AuthorDate: Sun Oct 27 14:47:52 2019 +0100

    Use methods defined in "AnyMatrix".
---
 .../commons/math4/linear/AbstractFieldMatrix.java  | 52 ++--------------------
 .../commons/math4/linear/AbstractRealMatrix.java   |  6 +--
 .../math4/linear/Array2DRowFieldMatrix.java        |  6 +--
 .../commons/math4/linear/Array2DRowRealMatrix.java |  6 +--
 .../commons/math4/linear/BlockFieldMatrix.java     | 12 ++---
 .../commons/math4/linear/BlockRealMatrix.java      | 12 ++---
 6 files changed, 24 insertions(+), 70 deletions(-)

diff --git a/src/main/java/org/apache/commons/math4/linear/AbstractFieldMatrix.java b/src/main/java/org/apache/commons/math4/linear/AbstractFieldMatrix.java
index 55f264b..1b337b5 100644
--- a/src/main/java/org/apache/commons/math4/linear/AbstractFieldMatrix.java
+++ b/src/main/java/org/apache/commons/math4/linear/AbstractFieldMatrix.java
@@ -144,7 +144,7 @@ public abstract class AbstractFieldMatrix<T extends FieldElement<T>>
     public FieldMatrix<T> add(FieldMatrix<T> m)
         throws MatrixDimensionMismatchException {
         // safety check
-        checkAdditionCompatible(m);
+        checkAdd(m);
 
         final int rowCount    = getRowDimension();
         final int columnCount = getColumnDimension();
@@ -163,7 +163,7 @@ public abstract class AbstractFieldMatrix<T extends FieldElement<T>>
     public FieldMatrix<T> subtract(final FieldMatrix<T> m)
         throws MatrixDimensionMismatchException {
         // safety check
-        checkSubtractionCompatible(m);
+        checkAdd(m);
 
         final int rowCount    = getRowDimension();
         final int columnCount = getColumnDimension();
@@ -213,7 +213,7 @@ public abstract class AbstractFieldMatrix<T extends FieldElement<T>>
     public FieldMatrix<T> multiply(final FieldMatrix<T> m)
         throws DimensionMismatchException {
         // safety check
-        checkMultiplicationCompatible(m);
+        checkMultiply(m);
 
         final int nRows = getRowDimension();
         final int nCols = m.getColumnDimension();
@@ -1111,50 +1111,4 @@ public abstract class AbstractFieldMatrix<T extends FieldElement<T>>
             checkColumnIndex(column);
         }
     }
-
-    /**
-     * Check if a matrix is addition compatible with the instance.
-     *
-     * @param m Matrix to check.
-     * @throws MatrixDimensionMismatchException if the matrix is not
-     * addition-compatible with instance.
-     */
-    protected void checkAdditionCompatible(final FieldMatrix<T> m)
-        throws MatrixDimensionMismatchException {
-        if ((getRowDimension() != m.getRowDimension()) ||
-            (getColumnDimension() != m.getColumnDimension())) {
-            throw new MatrixDimensionMismatchException(m.getRowDimension(), m.getColumnDimension(),
-                                                       getRowDimension(), getColumnDimension());
-        }
-    }
-
-    /**
-     * Check if a matrix is subtraction compatible with the instance.
-     *
-     * @param m Matrix to check.
-     * @throws MatrixDimensionMismatchException if the matrix is not
-     * subtraction-compatible with instance.
-     */
-    protected void checkSubtractionCompatible(final FieldMatrix<T> m)
-        throws MatrixDimensionMismatchException {
-        if ((getRowDimension() != m.getRowDimension()) ||
-            (getColumnDimension() != m.getColumnDimension())) {
-            throw new MatrixDimensionMismatchException(m.getRowDimension(), m.getColumnDimension(),
-                                                       getRowDimension(), getColumnDimension());
-        }
-    }
-
-    /**
-     * Check if a matrix is multiplication compatible with the instance.
-     *
-     * @param m Matrix to check.
-     * @throws DimensionMismatchException if the matrix is not
-     * multiplication-compatible with instance.
-     */
-    protected void checkMultiplicationCompatible(final FieldMatrix<T> m)
-        throws DimensionMismatchException {
-        if (getColumnDimension() != m.getRowDimension()) {
-            throw new DimensionMismatchException(m.getRowDimension(), getColumnDimension());
-        }
-    }
 }
diff --git a/src/main/java/org/apache/commons/math4/linear/AbstractRealMatrix.java b/src/main/java/org/apache/commons/math4/linear/AbstractRealMatrix.java
index f6539f0..c5d8d7c 100644
--- a/src/main/java/org/apache/commons/math4/linear/AbstractRealMatrix.java
+++ b/src/main/java/org/apache/commons/math4/linear/AbstractRealMatrix.java
@@ -76,7 +76,7 @@ public abstract class AbstractRealMatrix
     @Override
     public RealMatrix add(RealMatrix m)
         throws MatrixDimensionMismatchException {
-        MatrixUtils.checkAdditionCompatible(this, m);
+        checkAdd(m);
 
         final int rowCount    = getRowDimension();
         final int columnCount = getColumnDimension();
@@ -94,7 +94,7 @@ public abstract class AbstractRealMatrix
     @Override
     public RealMatrix subtract(final RealMatrix m)
         throws MatrixDimensionMismatchException {
-        MatrixUtils.checkSubtractionCompatible(this, m);
+        checkAdd(m);
 
         final int rowCount    = getRowDimension();
         final int columnCount = getColumnDimension();
@@ -142,7 +142,7 @@ public abstract class AbstractRealMatrix
     @Override
     public RealMatrix multiply(final RealMatrix m)
         throws DimensionMismatchException {
-        MatrixUtils.checkMultiplicationCompatible(this, m);
+        checkMultiply(m);
 
         final int nRows = getRowDimension();
         final int nCols = m.getColumnDimension();
diff --git a/src/main/java/org/apache/commons/math4/linear/Array2DRowFieldMatrix.java b/src/main/java/org/apache/commons/math4/linear/Array2DRowFieldMatrix.java
index f49f888..6afaa8a 100644
--- a/src/main/java/org/apache/commons/math4/linear/Array2DRowFieldMatrix.java
+++ b/src/main/java/org/apache/commons/math4/linear/Array2DRowFieldMatrix.java
@@ -228,7 +228,7 @@ public class Array2DRowFieldMatrix<T extends FieldElement<T>>
     public Array2DRowFieldMatrix<T> add(final Array2DRowFieldMatrix<T> m)
         throws MatrixDimensionMismatchException {
         // safety check
-        checkAdditionCompatible(m);
+        checkAdd(m);
 
         final int rowCount    = getRowDimension();
         final int columnCount = getColumnDimension();
@@ -256,7 +256,7 @@ public class Array2DRowFieldMatrix<T extends FieldElement<T>>
     public Array2DRowFieldMatrix<T> subtract(final Array2DRowFieldMatrix<T> m)
         throws MatrixDimensionMismatchException {
         // safety check
-        checkSubtractionCompatible(m);
+        checkAdd(m);
 
         final int rowCount    = getRowDimension();
         final int columnCount = getColumnDimension();
@@ -285,7 +285,7 @@ public class Array2DRowFieldMatrix<T extends FieldElement<T>>
     public Array2DRowFieldMatrix<T> multiply(final Array2DRowFieldMatrix<T> m)
         throws DimensionMismatchException {
         // safety check
-        checkMultiplicationCompatible(m);
+        checkMultiply(m);
 
         final int nRows = this.getRowDimension();
         final int nCols = m.getColumnDimension();
diff --git a/src/main/java/org/apache/commons/math4/linear/Array2DRowRealMatrix.java b/src/main/java/org/apache/commons/math4/linear/Array2DRowRealMatrix.java
index b9b41e0..85e4929 100644
--- a/src/main/java/org/apache/commons/math4/linear/Array2DRowRealMatrix.java
+++ b/src/main/java/org/apache/commons/math4/linear/Array2DRowRealMatrix.java
@@ -160,7 +160,7 @@ public class Array2DRowRealMatrix extends AbstractRealMatrix implements Serializ
     public Array2DRowRealMatrix add(final Array2DRowRealMatrix m)
         throws MatrixDimensionMismatchException {
         // Safety check.
-        MatrixUtils.checkAdditionCompatible(this, m);
+        checkAdd(m);
 
         final int rowCount    = getRowDimension();
         final int columnCount = getColumnDimension();
@@ -187,7 +187,7 @@ public class Array2DRowRealMatrix extends AbstractRealMatrix implements Serializ
      */
     public Array2DRowRealMatrix subtract(final Array2DRowRealMatrix m)
         throws MatrixDimensionMismatchException {
-        MatrixUtils.checkSubtractionCompatible(this, m);
+        checkAdd(m);
 
         final int rowCount    = getRowDimension();
         final int columnCount = getColumnDimension();
@@ -214,7 +214,7 @@ public class Array2DRowRealMatrix extends AbstractRealMatrix implements Serializ
      */
     public Array2DRowRealMatrix multiply(final Array2DRowRealMatrix m)
         throws DimensionMismatchException {
-        MatrixUtils.checkMultiplicationCompatible(this, m);
+        checkMultiply(m);
 
         final int nRows = this.getRowDimension();
         final int nCols = m.getColumnDimension();
diff --git a/src/main/java/org/apache/commons/math4/linear/BlockFieldMatrix.java b/src/main/java/org/apache/commons/math4/linear/BlockFieldMatrix.java
index 03417a3..dda300a 100644
--- a/src/main/java/org/apache/commons/math4/linear/BlockFieldMatrix.java
+++ b/src/main/java/org/apache/commons/math4/linear/BlockFieldMatrix.java
@@ -321,7 +321,7 @@ public class BlockFieldMatrix<T extends FieldElement<T>> extends AbstractFieldMa
         } catch (ClassCastException cce) {
 
             // safety check
-            checkAdditionCompatible(m);
+            checkAdd(m);
 
             final BlockFieldMatrix<T> out = new BlockFieldMatrix<>(getField(), rows, columns);
 
@@ -367,7 +367,7 @@ public class BlockFieldMatrix<T extends FieldElement<T>> extends AbstractFieldMa
         throws MatrixDimensionMismatchException {
 
         // safety check
-        checkAdditionCompatible(m);
+        checkAdd(m);
 
         final BlockFieldMatrix<T> out = new BlockFieldMatrix<>(getField(), rows, columns);
 
@@ -393,7 +393,7 @@ public class BlockFieldMatrix<T extends FieldElement<T>> extends AbstractFieldMa
         } catch (ClassCastException cce) {
 
             // safety check
-            checkSubtractionCompatible(m);
+            checkAdd(m);
 
             final BlockFieldMatrix<T> out = new BlockFieldMatrix<>(getField(), rows, columns);
 
@@ -437,7 +437,7 @@ public class BlockFieldMatrix<T extends FieldElement<T>> extends AbstractFieldMa
      */
     public BlockFieldMatrix<T> subtract(final BlockFieldMatrix<T> m) throws MatrixDimensionMismatchException {
         // safety check
-        checkSubtractionCompatible(m);
+        checkAdd(m);
 
         final BlockFieldMatrix<T> out = new BlockFieldMatrix<>(getField(), rows, columns);
 
@@ -498,7 +498,7 @@ public class BlockFieldMatrix<T extends FieldElement<T>> extends AbstractFieldMa
         } catch (ClassCastException cce) {
 
             // safety check
-            checkMultiplicationCompatible(m);
+            checkMultiply(m);
 
             final BlockFieldMatrix<T> out = new BlockFieldMatrix<>(getField(), rows, m.getColumnDimension());
             final T zero = getField().getZero();
@@ -561,7 +561,7 @@ public class BlockFieldMatrix<T extends FieldElement<T>> extends AbstractFieldMa
         throws DimensionMismatchException {
 
         // safety check
-        checkMultiplicationCompatible(m);
+        checkMultiply(m);
 
         final BlockFieldMatrix<T> out = new BlockFieldMatrix<>(getField(), rows, m.columns);
         final T zero = getField().getZero();
diff --git a/src/main/java/org/apache/commons/math4/linear/BlockRealMatrix.java b/src/main/java/org/apache/commons/math4/linear/BlockRealMatrix.java
index 20192ad..1dff0eb 100644
--- a/src/main/java/org/apache/commons/math4/linear/BlockRealMatrix.java
+++ b/src/main/java/org/apache/commons/math4/linear/BlockRealMatrix.java
@@ -304,7 +304,7 @@ public class BlockRealMatrix extends AbstractRealMatrix implements Serializable
             return add((BlockRealMatrix) m);
         } catch (ClassCastException cce) {
             // safety check
-            MatrixUtils.checkAdditionCompatible(this, m);
+            checkAdd(m);
 
             final BlockRealMatrix out = new BlockRealMatrix(rows, columns);
 
@@ -347,7 +347,7 @@ public class BlockRealMatrix extends AbstractRealMatrix implements Serializable
     public BlockRealMatrix add(final BlockRealMatrix m)
         throws MatrixDimensionMismatchException {
         // safety check
-        MatrixUtils.checkAdditionCompatible(this, m);
+        checkAdd(m);
 
         final BlockRealMatrix out = new BlockRealMatrix(rows, columns);
 
@@ -372,7 +372,7 @@ public class BlockRealMatrix extends AbstractRealMatrix implements Serializable
             return subtract((BlockRealMatrix) m);
         } catch (ClassCastException cce) {
             // safety check
-            MatrixUtils.checkSubtractionCompatible(this, m);
+            checkAdd(m);
 
             final BlockRealMatrix out = new BlockRealMatrix(rows, columns);
 
@@ -415,7 +415,7 @@ public class BlockRealMatrix extends AbstractRealMatrix implements Serializable
     public BlockRealMatrix subtract(final BlockRealMatrix m)
         throws MatrixDimensionMismatchException {
         // safety check
-        MatrixUtils.checkSubtractionCompatible(this, m);
+        checkAdd(m);
 
         final BlockRealMatrix out = new BlockRealMatrix(rows, columns);
 
@@ -475,7 +475,7 @@ public class BlockRealMatrix extends AbstractRealMatrix implements Serializable
             return multiply((BlockRealMatrix) m);
         } catch (ClassCastException cce) {
             // safety check
-            MatrixUtils.checkMultiplicationCompatible(this, m);
+            checkMultiply(m);
 
             final BlockRealMatrix out = new BlockRealMatrix(rows, m.getColumnDimension());
 
@@ -532,7 +532,7 @@ public class BlockRealMatrix extends AbstractRealMatrix implements Serializable
     public BlockRealMatrix multiply(BlockRealMatrix m)
         throws DimensionMismatchException {
         // safety check
-        MatrixUtils.checkMultiplicationCompatible(this, m);
+        checkMultiply(m);
 
         final BlockRealMatrix out = new BlockRealMatrix(rows, m.columns);
 


[commons-math] 02/08: Add "default" methods.

Posted by er...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

erans pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-math.git

commit 7acf4d9ccc05fe9ed544b03c3d2308343e9d5514
Author: Gilles Sadowski <gi...@harfang.homelinux.org>
AuthorDate: Sun Oct 27 14:32:58 2019 +0100

    Add "default" methods.
---
 .../org/apache/commons/math4/linear/AnyMatrix.java | 48 ++++++++++++++++++++++
 .../apache/commons/math4/linear/MatrixUtils.java   | 27 +++---------
 2 files changed, 54 insertions(+), 21 deletions(-)

diff --git a/src/main/java/org/apache/commons/math4/linear/AnyMatrix.java b/src/main/java/org/apache/commons/math4/linear/AnyMatrix.java
index 0e1bb56..062ed91 100644
--- a/src/main/java/org/apache/commons/math4/linear/AnyMatrix.java
+++ b/src/main/java/org/apache/commons/math4/linear/AnyMatrix.java
@@ -17,6 +17,7 @@
 
 package org.apache.commons.math4.linear;
 
+import org.apache.commons.math4.exception.DimensionMismatchException;
 
 /**
  * Interface defining very basic matrix operations.
@@ -46,4 +47,51 @@ public interface AnyMatrix {
      * @return the number of columns.
      */
     int getColumnDimension();
+
+    /**
+     * Checks that this matrix and the {@code other} matrix can be added.
+     *
+     * @param other Matrix to be added.
+     * @return {@code false} if the dimensions do not match.
+     */
+    default boolean canAdd(AnyMatrix other) {
+        return getRowDimension() == other.getRowDimension() &&
+            getColumnDimension() == other.getColumnDimension();
+    }
+
+    /**
+     * Checks that this matrix and the {@code other} matrix can be added.
+     *
+     * @param other Matrix to check.
+     * @throws IllegalArgumentException if the dimensions do not match.
+     */
+    default void checkAdd(AnyMatrix other) {
+        if (!canAdd(other)) {
+            throw new MatrixDimensionMismatchException(getRowDimension(), getColumnDimension(),
+                                                       other.getRowDimension(), other.getColumnDimension());
+        }
+    }
+
+    /**
+     * Checks that this matrix can be multiplied by the {@code other} matrix.
+     *
+     * @param other Matrix to be added.
+     * @return {@code false} if the dimensions do not match.
+     */
+    default boolean canMultiply(AnyMatrix other) {
+        return getColumnDimension() == other.getRowDimension();
+    }
+
+    /**
+     * Checks that this matrix can be multiplied by the {@code other} matrix.
+     *
+     * @param other Matrix to check.
+     * @throws IllegalArgumentException if the dimensions do not match.
+     */
+    default void checkMultiply(AnyMatrix other) {
+        if (!canMultiply(other)) {
+            throw new DimensionMismatchException(getColumnDimension(),
+                                                 other.getRowDimension());
+        }
+    }
 }
diff --git a/src/main/java/org/apache/commons/math4/linear/MatrixUtils.java b/src/main/java/org/apache/commons/math4/linear/MatrixUtils.java
index 04daf94..47d3017 100644
--- a/src/main/java/org/apache/commons/math4/linear/MatrixUtils.java
+++ b/src/main/java/org/apache/commons/math4/linear/MatrixUtils.java
@@ -582,13 +582,8 @@ public class MatrixUtils {
      * @throws MatrixDimensionMismatchException if the matrices are not addition
      * compatible.
      */
-    public static void checkAdditionCompatible(final AnyMatrix left, final AnyMatrix right)
-        throws MatrixDimensionMismatchException {
-        if ((left.getRowDimension()    != right.getRowDimension()) ||
-            (left.getColumnDimension() != right.getColumnDimension())) {
-            throw new MatrixDimensionMismatchException(left.getRowDimension(), left.getColumnDimension(),
-                                                       right.getRowDimension(), right.getColumnDimension());
-        }
+    public static void checkAdditionCompatible(final AnyMatrix left, final AnyMatrix right) {
+        left.checkAdd(right);
     }
 
     /**
@@ -599,13 +594,8 @@ public class MatrixUtils {
      * @throws MatrixDimensionMismatchException if the matrices are not addition
      * compatible.
      */
-    public static void checkSubtractionCompatible(final AnyMatrix left, final AnyMatrix right)
-        throws MatrixDimensionMismatchException {
-        if ((left.getRowDimension()    != right.getRowDimension()) ||
-            (left.getColumnDimension() != right.getColumnDimension())) {
-            throw new MatrixDimensionMismatchException(left.getRowDimension(), left.getColumnDimension(),
-                                                       right.getRowDimension(), right.getColumnDimension());
-        }
+    public static void checkSubtractionCompatible(final AnyMatrix left, final AnyMatrix right) {
+        left.checkAdd(right);
     }
 
     /**
@@ -616,13 +606,8 @@ public class MatrixUtils {
      * @throws DimensionMismatchException if matrices are not multiplication
      * compatible.
      */
-    public static void checkMultiplicationCompatible(final AnyMatrix left, final AnyMatrix right)
-        throws DimensionMismatchException {
-
-        if (left.getColumnDimension() != right.getRowDimension()) {
-            throw new DimensionMismatchException(left.getColumnDimension(),
-                                                 right.getRowDimension());
-        }
+    public static void checkMultiplicationCompatible(final AnyMatrix left, final AnyMatrix right) {
+        left.checkMultiply(right);
     }
 
     /**


[commons-math] 08/08: MATH-1500 (unit tests).

Posted by er...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

erans pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-math.git

commit 471d4d60dc21fbccb8c6b4616a00238c245f78f6
Author: Gilles Sadowski <gi...@harfang.homelinux.org>
AuthorDate: Mon Oct 28 01:51:42 2019 +0100

    MATH-1500 (unit tests).
---
 .../field/linalg/FieldLUDecompositionTest.java     | 195 +++++++++++++--------
 1 file changed, 121 insertions(+), 74 deletions(-)

diff --git a/src/test/java/org/apache/commons/math4/field/linalg/FieldLUDecompositionTest.java b/src/test/java/org/apache/commons/math4/field/linalg/FieldLUDecompositionTest.java
index b756643..8f08580 100644
--- a/src/test/java/org/apache/commons/math4/field/linalg/FieldLUDecompositionTest.java
+++ b/src/test/java/org/apache/commons/math4/field/linalg/FieldLUDecompositionTest.java
@@ -17,60 +17,47 @@
 
 package org.apache.commons.math4.field.linalg;
 
-import org.apache.commons.numbers.fraction.Fraction;
-import org.apache.commons.numbers.field.FractionField;
 import org.junit.Test;
 import org.junit.Assert;
-import org.apache.commons.math4.linear.NonSquareMatrixException;
+import org.apache.commons.numbers.fraction.Fraction;
+import org.apache.commons.numbers.field.FractionField;
 import org.apache.commons.math4.linear.SingularMatrixException;
+import org.apache.commons.math4.exception.DimensionMismatchException;
 
 public class FieldLUDecompositionTest {
-    private final Fraction[][] testData = {
-            { Fraction.of(1), Fraction.of(2), Fraction.of(3)},
-            { Fraction.of(2), Fraction.of(5), Fraction.of(3)},
-            { Fraction.of(1), Fraction.of(0), Fraction.of(8)}
+    private final int[][] testData = {
+        { 1, 2, 3 },
+        { 2, 5, 3 },
+        { 1, 0, 8 }
+    };
+    private final int[][] testDataMinus = {
+        { -1, -2, -3 },
+        { -2, -5, -3 },
+        { -1, 0, -8 }
     };
-    private final Fraction[][] testDataMinus = {
-            { Fraction.of(-1), Fraction.of(-2), Fraction.of(-3)},
-            { Fraction.of(-2), Fraction.of(-5), Fraction.of(-3)},
-            { Fraction.of(-1), Fraction.of(0), Fraction.of(-8)}
+    private final int[][] luData = {
+        { 2, 3, 3 },
+        { 2, 3, 7 },
+        { 6, 6, 8 }
     };
-    private final Fraction[][] luData = {
-            { Fraction.of(2), Fraction.of(3), Fraction.of(3) },
-            { Fraction.of(2), Fraction.of(3), Fraction.of(7) },
-            { Fraction.of(6), Fraction.of(6), Fraction.of(8) }
+    private final int[][] luData2 = {
+        { 2, 3, 3 },
+        { 0, 5, 7 },
+        { 6, 9, 8 }
     };
 
     // singular matrices
-    private final Fraction[][] singular = {
-            { Fraction.of(2), Fraction.of(3) },
-            { Fraction.of(2), Fraction.of(3) }
+    private int[][] singular = {
+        { 2, 3 },
+        { 2, 3 }
     };
-    private final Fraction[][] bigSingular = {
-            { Fraction.of(1), Fraction.of(2), Fraction.of(3), Fraction.of(4) },
-            { Fraction.of(2), Fraction.of(5), Fraction.of(3), Fraction.of(4) },
-            { Fraction.of(7), Fraction.of(3), Fraction.of(256), Fraction.of(1930) },
-            { Fraction.of(3), Fraction.of(7), Fraction.of(6), Fraction.of(8) }
+    private final int[][] bigSingular = {
+        { 1, 2,   3,    4 },
+        { 2, 5,   3,    4 },
+        { 7, 3, 256, 1930 },
+        { 3, 7,   6,    8 }
     }; // 4th row = 1st + 2nd
 
-    /**
-     * @param data Matrix.
-     * @return a {@link FieldDenseMatrix} instance.
-     */
-    private FieldDenseMatrix<Fraction> create(Fraction[][] data) {
-        final FieldDenseMatrix<Fraction> m = FieldDenseMatrix.create(FractionField.get(),
-                                                                     data.length,
-                                                                     data[0].length);
-        for (int i = 0; i < data.length; i++) {
-            for (int j = 0; j < data.length; j++) {
-                m.set(i, j, data[i][j]);
-            }
-        }
-
-        return m;
-    }
-
-    /** test dimensions */
     @Test
     public void testDimensions() {
         FieldDenseMatrix<Fraction> matrix = create(testData);
@@ -80,7 +67,6 @@ public class FieldLUDecompositionTest {
         Assert.assertEquals(testData.length, LU.getP().getRowDimension());
     }
 
-    /** test PA = LU */
     @Test
     public void testPAEqualLU() {
         FieldDenseMatrix<Fraction> matrix = create(testData);
@@ -105,7 +91,7 @@ public class FieldLUDecompositionTest {
         Assert.assertEquals(p.multiply(matrix), l.multiply(u));
     }
 
-    /** test that L is lower triangular with unit diagonal */
+    /* L is lower triangular with unit diagonal */
     @Test
     public void testLLowerTriangular() {
         FieldDenseMatrix<Fraction> matrix = create(testData);
@@ -118,7 +104,7 @@ public class FieldLUDecompositionTest {
         }
     }
 
-    /** test that U is upper triangular */
+    /* U is upper triangular */
     @Test
     public void testUUpperTriangular() {
         FieldDenseMatrix<Fraction> matrix = create(testData);
@@ -130,7 +116,7 @@ public class FieldLUDecompositionTest {
         }
     }
 
-    /** test that P is a permutation matrix */
+    /* P is a permutation matrix */
     @Test
     public void testPPermutation() {
         FieldDenseMatrix<Fraction> matrix = create(testData);
@@ -202,20 +188,20 @@ public class FieldLUDecompositionTest {
     @Test
     public void testMatricesValues1() {
         FieldLUDecomposition<Fraction> lu = FieldLUDecomposition.of(create(testData));
-        FieldDenseMatrix<Fraction> lRef = create(new Fraction[][] {
-                { Fraction.of(1), Fraction.of(0), Fraction.of(0) },
-                { Fraction.of(2), Fraction.of(1), Fraction.of(0) },
-                { Fraction.of(1), Fraction.of(-2), Fraction.of(1) }
+        FieldDenseMatrix<Fraction> lRef = create(new int[][] {
+                { 1, 0, 0 },
+                { 2, 1, 0 },
+                { 1, -2, 1 }
             });
-        FieldDenseMatrix<Fraction> uRef = create(new Fraction[][] {
-                { Fraction.of(1),  Fraction.of(2), Fraction.of(3) },
-                { Fraction.of(0), Fraction.of(1), Fraction.of(-3) },
-                { Fraction.of(0),  Fraction.of(0), Fraction.of(-1) }
+        FieldDenseMatrix<Fraction> uRef = create(new int[][] {
+                { 1,  2, 3 },
+                { 0, 1, -3 },
+                { 0,  0, -1 }
             });
-        FieldDenseMatrix<Fraction> pRef = create(new Fraction[][] {
-                { Fraction.of(1), Fraction.of(0), Fraction.of(0) },
-                { Fraction.of(0), Fraction.of(1), Fraction.of(0) },
-                { Fraction.of(0), Fraction.of(0), Fraction.of(1) }
+        FieldDenseMatrix<Fraction> pRef = create(new int[][] {
+                { 1, 0, 0 },
+                { 0, 1, 0 },
+                { 0, 0, 1 }
             });
         int[] pivotRef = { 0, 1, 2 };
 
@@ -234,34 +220,95 @@ public class FieldLUDecompositionTest {
 
     @Test
     public void testMatricesValues2() {
-        FieldLUDecomposition<Fraction> lu = FieldLUDecomposition.of(create(luData));
-        FieldDenseMatrix<Fraction> lRef = create(new Fraction[][] {
-                { Fraction.of(1), Fraction.of(0), Fraction.of(0) },
-                { Fraction.of(3), Fraction.of(1), Fraction.of(0) },
-                { Fraction.of(1), Fraction.of(0), Fraction.of(1) }
+        final FieldLUDecomposition<Fraction> lu = FieldLUDecomposition.of(create(luData));
+        final FieldDenseMatrix<Fraction> lRef = create(new int[][] {
+                { 1, 0, 0 },
+                { 3, 1, 0 },
+                { 1, 0, 1 }
             });
-        FieldDenseMatrix<Fraction> uRef = create(new Fraction[][] {
-                { Fraction.of(2), Fraction.of(3), Fraction.of(3)    },
-                { Fraction.of(0), Fraction.of(-3), Fraction.of(-1)  },
-                { Fraction.of(0), Fraction.of(0), Fraction.of(4) }
+        final FieldDenseMatrix<Fraction> uRef = create(new int[][] {
+                { 2, 3, 3 },
+                { 0, -3, -1 },
+                { 0, 0, 4 }
             });
-        FieldDenseMatrix<Fraction> pRef = create(new Fraction[][] {
-                { Fraction.of(1), Fraction.of(0), Fraction.of(0) },
-                { Fraction.of(0), Fraction.of(0), Fraction.of(1) },
-                { Fraction.of(0), Fraction.of(1), Fraction.of(0) }
+        final FieldDenseMatrix<Fraction> pRef = create(new int[][] {
+                { 1, 0, 0 },
+                { 0, 0, 1 },
+                { 0, 1, 0 }
             });
         int[] pivotRef = { 0, 2, 1 };
 
         // check values against known references
-        FieldDenseMatrix<Fraction> l = lu.getL();
+        final FieldDenseMatrix<Fraction> l = lu.getL();
         Assert.assertEquals(lRef, l);
-        FieldDenseMatrix<Fraction> u = lu.getU();
+        final FieldDenseMatrix<Fraction> u = lu.getU();
         Assert.assertEquals(uRef, u);
-        FieldDenseMatrix<Fraction> p = lu.getP();
+        final FieldDenseMatrix<Fraction> p = lu.getP();
         Assert.assertEquals(pRef, p);
         int[] pivot = lu.getPivot();
-        for (int i = 0; i < pivotRef.length; ++i) {
+        for (int i = 0; i < pivotRef.length; i++) {
             Assert.assertEquals(pivotRef[i], pivot[i]);
         }
     }
+
+    @Test(expected=DimensionMismatchException.class)
+    public void testSolveDimensionErrors() {
+        FieldLUDecomposition
+            .of(create(testData))
+            .getSolver()
+            .solve(create(new int[2][2]));
+    }
+
+    @Test
+    public void testSolve() {
+        final FieldDecompositionSolver<Fraction> solver = FieldLUDecomposition
+            .of(create(testData))
+            .getSolver();
+        final FieldDenseMatrix<Fraction> b = create(new int[][] {
+                { 1, 0 },
+                { 2, -5 },
+                { 3, 1 }
+            });
+        final FieldDenseMatrix<Fraction> xRef = create(new int[][] {
+                { 19, -71 },
+                { -6, 22 },
+                { -2, 9 }
+            });
+
+        final FieldDenseMatrix<Fraction> x = solver.solve(b);
+        for (int i = 0; i < x.getRowDimension(); i++){
+            for (int j = 0; j < x.getColumnDimension(); j++){
+                Assert.assertEquals("(" + i + ", " + j + ")",
+                                    xRef.get(i, j), x.get(i, j));
+            }
+        }
+    }
+
+    @Test
+    public void testDeterminant() {
+        Assert.assertEquals(-1, determinant(testData), 1e-15);
+        Assert.assertEquals(24, determinant(luData), 1e-14);
+        Assert.assertEquals(-10, determinant(luData2), 1e-14);
+        Assert.assertEquals(0, determinant(singular), 1e-15);
+        Assert.assertEquals(0, determinant(bigSingular), 1e-15);
+    }
+
+    private static double determinant(int[][] data) {
+        return FieldLUDecomposition.of(create(data)).getDeterminant().doubleValue();
+    }
+
+    private static FieldDenseMatrix<Fraction> create(final int[][] data) {
+        final int numRows = data.length;
+        final int numCols = data[0].length;
+        final FieldDenseMatrix<Fraction> m = FieldDenseMatrix
+            .create(FractionField.get(), numRows, numCols);
+
+        for (int i = 0; i < numRows; i++) {
+            for (int j = 0; j < numCols; j++) {
+                m.set(i, j, Fraction.of(data[i][j], 1));
+            }
+        }
+
+        return m;
+    }
 }


[commons-math] 05/08: Code upgraded following MATH-1499.

Posted by er...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

erans pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-math.git

commit 407f1e780e63df0af81a80f499dfbfe5d2841612
Author: Gilles Sadowski <gi...@harfang.homelinux.org>
AuthorDate: Sun Oct 27 15:02:21 2019 +0100

    Code upgraded following MATH-1499.
---
 .../commons/math4/stat/inference/KolmogorovSmirnovTest.java  | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/main/java/org/apache/commons/math4/stat/inference/KolmogorovSmirnovTest.java b/src/main/java/org/apache/commons/math4/stat/inference/KolmogorovSmirnovTest.java
index accc3d6..026a94e 100644
--- a/src/main/java/org/apache/commons/math4/stat/inference/KolmogorovSmirnovTest.java
+++ b/src/main/java/org/apache/commons/math4/stat/inference/KolmogorovSmirnovTest.java
@@ -27,7 +27,6 @@ import org.apache.commons.statistics.distribution.ContinuousDistribution;
 import org.apache.commons.numbers.combinatorics.BinomialCoefficientDouble;
 import org.apache.commons.numbers.fraction.BigFraction;
 import org.apache.commons.numbers.field.BigFractionField;
-import org.apache.commons.numbers.field.FieldSquareMatrix;
 import org.apache.commons.math4.distribution.EnumeratedRealDistribution;
 import org.apache.commons.math4.distribution.AbstractRealDistribution;
 import org.apache.commons.math4.exception.InsufficientDataException;
@@ -44,6 +43,7 @@ import org.apache.commons.math4.linear.RealMatrix;
 import org.apache.commons.math4.util.FastMath;
 import org.apache.commons.math4.util.MathArrays;
 import org.apache.commons.math4.util.MathUtils;
+import org.apache.commons.math4.field.linalg.FieldDenseMatrix;
 
 /**
  * Implementation of the <a href="http://en.wikipedia.org/wiki/Kolmogorov-Smirnov_test">
@@ -490,14 +490,14 @@ public class KolmogorovSmirnovTest {
     private double exactK(double d, int n) {
         final int k = (int) Math.ceil(n * d);
 
-        final FieldSquareMatrix<BigFraction> H;
+        final FieldDenseMatrix<BigFraction> H;
         try {
             H = createExactH(d, n);
         } catch (ArithmeticException e) {
             throw new MathArithmeticException(LocalizedFormats.FRACTION);
         }
 
-        final FieldSquareMatrix<BigFraction> Hpower = H.pow(n);
+        final FieldDenseMatrix<BigFraction> Hpower = H.pow(n);
 
         BigFraction pFrac = Hpower.get(k - 1, k - 1);
 
@@ -684,8 +684,8 @@ public class KolmogorovSmirnovTest {
      * @throws ArithmeticException if algorithm fails to convert {@code h} to a
      * {@link BigFraction}.
      */
-    private FieldSquareMatrix<BigFraction> createExactH(double d,
-                                                        int n) {
+    private FieldDenseMatrix<BigFraction> createExactH(double d,
+                                                       int n) {
         final int k = (int) Math.ceil(n * d);
         final int m = 2 * k - 1;
         final double hDouble = k - n * d;
@@ -702,7 +702,7 @@ public class KolmogorovSmirnovTest {
                 h = BigFraction.from(hDouble, 1e-5, 10000);
             }
         }
-        final FieldSquareMatrix<BigFraction> Hdata = FieldSquareMatrix.create(BigFractionField.get(), m);
+        final FieldDenseMatrix<BigFraction> Hdata = FieldDenseMatrix.create(BigFractionField.get(), m, m);
 
         /*
          * Start by filling everything with either 0 or 1.


[commons-math] 07/08: Code upgraded following MATH-1500.

Posted by er...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

erans pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-math.git

commit 9988a5b3c4779eadfad9ea0c4925f5b327317814
Author: Gilles Sadowski <gi...@harfang.homelinux.org>
AuthorDate: Sun Oct 27 15:11:56 2019 +0100

    Code upgraded following MATH-1500.
---
 .../ode/nonstiff/AdamsNordsieckTransformer.java    | 72 ++++++++++++----------
 1 file changed, 40 insertions(+), 32 deletions(-)

diff --git a/src/main/java/org/apache/commons/math4/ode/nonstiff/AdamsNordsieckTransformer.java b/src/main/java/org/apache/commons/math4/ode/nonstiff/AdamsNordsieckTransformer.java
index 7cf5a4e..60f5ee7 100644
--- a/src/main/java/org/apache/commons/math4/ode/nonstiff/AdamsNordsieckTransformer.java
+++ b/src/main/java/org/apache/commons/math4/ode/nonstiff/AdamsNordsieckTransformer.java
@@ -21,16 +21,17 @@ import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
 
-import org.apache.commons.math4.fraction.BigFraction;
+import org.apache.commons.numbers.fraction.BigFraction;
+import org.apache.commons.numbers.field.BigFractionField;
 import org.apache.commons.math4.linear.Array2DRowFieldMatrix;
 import org.apache.commons.math4.linear.Array2DRowRealMatrix;
 import org.apache.commons.math4.linear.ArrayFieldVector;
-import org.apache.commons.math4.linear.FieldDecompositionSolver;
-import org.apache.commons.math4.linear.FieldLUDecomposition;
-import org.apache.commons.math4.linear.FieldMatrix;
 import org.apache.commons.math4.linear.MatrixUtils;
 import org.apache.commons.math4.linear.QRDecomposition;
 import org.apache.commons.math4.linear.RealMatrix;
+import org.apache.commons.math4.field.linalg.FieldDenseMatrix;
+import org.apache.commons.math4.field.linalg.FieldDecompositionSolver;
+import org.apache.commons.math4.field.linalg.FieldLUDecomposition;
 
 /** Transformer to Nordsieck vectors for Adams integrators.
  * <p>This class is used by {@link AdamsBashforthIntegrator Adams-Bashforth} and
@@ -148,38 +149,45 @@ public class AdamsNordsieckTransformer {
      * (excluding the one being computed)
      */
     private AdamsNordsieckTransformer(final int n) {
-
-        final int rows = n - 1;
+        final int dim = n - 1;
 
         // compute exact coefficients
-        FieldMatrix<BigFraction> bigP = buildP(rows);
-        FieldDecompositionSolver<BigFraction> pSolver =
-            new FieldLUDecomposition<>(bigP).getSolver();
+        final FieldDenseMatrix<BigFraction> bigP = buildP(dim);
+        final FieldDecompositionSolver<BigFraction> pSolver = FieldLUDecomposition.of(bigP).getSolver();
 
-        BigFraction[] u = new BigFraction[rows];
-        Arrays.fill(u, BigFraction.ONE);
-        BigFraction[] bigC1 = pSolver.solve(new ArrayFieldVector<>(u, false)).toArray();
+        final FieldDenseMatrix<BigFraction> u = FieldDenseMatrix.create(BigFractionField.get(), dim, 1)
+            .fill(BigFraction.ONE);
+        final FieldDenseMatrix<BigFraction> bigC1 = pSolver.solve(u);
 
         // update coefficients are computed by combining transform from
         // Nordsieck to multistep, then shifting rows to represent step advance
         // then applying inverse transform
-        BigFraction[][] shiftedP = bigP.getData();
-        for (int i = shiftedP.length - 1; i > 0; --i) {
+        final FieldDenseMatrix<BigFraction> shiftedP = bigP.copy();
+        for (int i = dim - 1; i > 0; --i) {
             // shift rows
-            shiftedP[i] = shiftedP[i - 1];
+            for (int j = 0; j < dim; j++) {
+                shiftedP.set(i, j, shiftedP.get(i - 1, j));
+            }
         }
-        shiftedP[0] = new BigFraction[rows];
-        Arrays.fill(shiftedP[0], BigFraction.ZERO);
-        FieldMatrix<BigFraction> bigMSupdate =
-            pSolver.solve(new Array2DRowFieldMatrix<>(shiftedP, false));
+        for (int j = 0; j < dim; j++) {
+            shiftedP.set(0, j, BigFraction.ZERO);
+        }
+
+        final FieldDenseMatrix<BigFraction> bigMSupdate = pSolver.solve(shiftedP);
 
         // convert coefficients to double
-        update         = MatrixUtils.bigFractionMatrixToRealMatrix(bigMSupdate);
-        c1             = new double[rows];
-        for (int i = 0; i < rows; ++i) {
-            c1[i] = bigC1[i].doubleValue();
+        final double[][] updateData = new double[dim][dim];
+        for (int i = 0; i < dim; i++) {
+            for (int j = 0; j < dim; j++) {
+                updateData[i][j] = bigMSupdate.get(i, j).doubleValue();
+            }
         }
 
+        update = new Array2DRowRealMatrix(updateData, false);
+        c1 = new double[dim];
+        for (int i = 0; i < dim; ++i) {
+            c1[i] = bigC1.get(i, 0).doubleValue();
+        }
     }
 
     /** Get the Nordsieck transformer for a given number of steps.
@@ -223,23 +231,23 @@ public class AdamsNordsieckTransformer {
      * @param rows number of rows of the matrix
      * @return P matrix
      */
-    private FieldMatrix<BigFraction> buildP(final int rows) {
+    private FieldDenseMatrix<BigFraction> buildP(final int rows) {
+        final FieldDenseMatrix<BigFraction> pData = FieldDenseMatrix.create(BigFractionField.get(),
+                                                                            rows, rows)
+            .fill(BigFraction.ZERO);
 
-        final BigFraction[][] pData = new BigFraction[rows][rows];
-
-        for (int i = 1; i <= pData.length; ++i) {
+        for (int i = 1; i <= rows; ++i) {
             // build the P matrix elements from Taylor series formulas
-            final BigFraction[] pI = pData[i - 1];
             final int factor = -i;
             int aj = factor;
-            for (int j = 1; j <= pI.length; ++j) {
-                pI[j - 1] = new BigFraction(aj * (j + 1));
+            for (int j = 1; j <= rows; ++j) {
+                pData.set(i - 1, j - 1,
+                          BigFraction.of(aj * (j + 1)));
                 aj *= factor;
             }
         }
 
-        return new Array2DRowFieldMatrix<>(pData, false);
-
+        return pData;
     }
 
     /** Initialize the high order scaled derivatives at step start.


[commons-math] 01/08: Remove redundant declarations/definitions.

Posted by er...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

erans pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-math.git

commit 78e4c98096c94043ca01735200c2410b755e938a
Author: Gilles Sadowski <gi...@harfang.homelinux.org>
AuthorDate: Sun Oct 27 13:58:47 2019 +0100

    Remove redundant declarations/definitions.
    
    Target for next release is Java 8+.
---
 .../commons/math4/linear/AbstractFieldMatrix.java  | 14 --------------
 .../commons/math4/linear/AbstractRealMatrix.java   | 22 ----------------------
 .../org/apache/commons/math4/linear/AnyMatrix.java | 20 +++++++++++---------
 3 files changed, 11 insertions(+), 45 deletions(-)

diff --git a/src/main/java/org/apache/commons/math4/linear/AbstractFieldMatrix.java b/src/main/java/org/apache/commons/math4/linear/AbstractFieldMatrix.java
index c2f3b18..55f264b 100644
--- a/src/main/java/org/apache/commons/math4/linear/AbstractFieldMatrix.java
+++ b/src/main/java/org/apache/commons/math4/linear/AbstractFieldMatrix.java
@@ -672,20 +672,6 @@ public abstract class AbstractFieldMatrix<T extends FieldElement<T>>
 
     /** {@inheritDoc} */
     @Override
-    public boolean isSquare() {
-        return getColumnDimension() == getRowDimension();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public abstract int getRowDimension();
-
-    /** {@inheritDoc} */
-    @Override
-    public abstract int getColumnDimension();
-
-    /** {@inheritDoc} */
-    @Override
     public T getTrace() throws NonSquareMatrixException {
         final int nRows = getRowDimension();
         final int nCols = getColumnDimension();
diff --git a/src/main/java/org/apache/commons/math4/linear/AbstractRealMatrix.java b/src/main/java/org/apache/commons/math4/linear/AbstractRealMatrix.java
index 76ef1cb..f6539f0 100644
--- a/src/main/java/org/apache/commons/math4/linear/AbstractRealMatrix.java
+++ b/src/main/java/org/apache/commons/math4/linear/AbstractRealMatrix.java
@@ -660,28 +660,6 @@ public abstract class AbstractRealMatrix
 
     /** {@inheritDoc} */
     @Override
-    public boolean isSquare() {
-        return getColumnDimension() == getRowDimension();
-    }
-
-    /**
-     * Returns the number of rows of this matrix.
-     *
-     * @return the number of rows.
-     */
-    @Override
-    public abstract int getRowDimension();
-
-    /**
-     * Returns the number of columns of this matrix.
-     *
-     * @return the number of columns.
-     */
-    @Override
-    public abstract int getColumnDimension();
-
-    /** {@inheritDoc} */
-    @Override
     public double getTrace() throws NonSquareMatrixException {
         final int nRows = getRowDimension();
         final int nCols = getColumnDimension();
diff --git a/src/main/java/org/apache/commons/math4/linear/AnyMatrix.java b/src/main/java/org/apache/commons/math4/linear/AnyMatrix.java
index 85a5fe7..0e1bb56 100644
--- a/src/main/java/org/apache/commons/math4/linear/AnyMatrix.java
+++ b/src/main/java/org/apache/commons/math4/linear/AnyMatrix.java
@@ -20,28 +20,30 @@ package org.apache.commons.math4.linear;
 
 /**
  * Interface defining very basic matrix operations.
+ *
  * @since 2.0
  */
 public interface AnyMatrix {
-
     /**
-     * Is this a square matrix?
-     * @return true if the matrix is square (rowDimension = columnDimension)
+     * Indicates whether this is a square matrix.
+     *
+     * @return {@code true} if the number of rows is the same as the number of columns.
      */
-    boolean isSquare();
+    default boolean isSquare() {
+        return getRowDimension() == getColumnDimension();
+    }
 
     /**
-     * Returns the number of rows in the matrix.
+     * Gets the number of rows.
      *
-     * @return rowDimension
+     * @return the number of rows.
      */
     int getRowDimension();
 
     /**
-     * Returns the number of columns in the matrix.
+     * Gets the number of columns.
      *
-     * @return columnDimension
+     * @return the number of columns.
      */
     int getColumnDimension();
-
 }