You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2017/04/18 09:00:25 UTC
[13/50] [abbrv] ignite git commit: IGNITE-5000 Rename Ignite Math
module to Ignite ML module
http://git-wip-us.apache.org/repos/asf/ignite/blob/732dfea9/modules/ml/src/test/java/org/apache/ignite/math/decompositions/CholeskyDecompositionTest.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/test/java/org/apache/ignite/math/decompositions/CholeskyDecompositionTest.java b/modules/ml/src/test/java/org/apache/ignite/math/decompositions/CholeskyDecompositionTest.java
new file mode 100644
index 0000000..fa311e0
--- /dev/null
+++ b/modules/ml/src/test/java/org/apache/ignite/math/decompositions/CholeskyDecompositionTest.java
@@ -0,0 +1,158 @@
+/*
+ * 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.ignite.math.decompositions;
+
+import org.apache.ignite.math.Matrix;
+import org.apache.ignite.math.Vector;
+import org.apache.ignite.math.exceptions.CardinalityException;
+import org.apache.ignite.math.exceptions.NonPositiveDefiniteMatrixException;
+import org.apache.ignite.math.exceptions.NonSymmetricMatrixException;
+import org.apache.ignite.math.impls.matrix.DenseLocalOnHeapMatrix;
+import org.apache.ignite.math.impls.matrix.PivotedMatrixView;
+import org.apache.ignite.math.impls.vector.DenseLocalOnHeapVector;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+/** */
+public class CholeskyDecompositionTest {
+ /** */
+ @Test
+ public void basicTest() {
+ basicTest(new DenseLocalOnHeapMatrix(new double[][] {
+ {2.0d, -1.0d, 0.0d},
+ {-1.0d, 2.0d, -1.0d},
+ {0.0d, -1.0d, 2.0d}
+ }));
+ }
+
+ /**
+ * Test for {@link DecompositionSupport} features.
+ */
+ @Test
+ public void decompositionSupportTest() {
+ basicTest(new PivotedMatrixView(new DenseLocalOnHeapMatrix(new double[][] {
+ {2.0d, -1.0d, 0.0d},
+ {-1.0d, 2.0d, -1.0d},
+ {0.0d, -1.0d, 2.0d}
+ })));
+ }
+
+ /** */
+ @Test(expected = AssertionError.class)
+ public void nullMatrixTest() {
+ new CholeskyDecomposition(null);
+ }
+
+ /** */
+ @Test(expected = CardinalityException.class)
+ public void wrongMatrixSizeTest() {
+ new CholeskyDecomposition(new DenseLocalOnHeapMatrix(2, 3));
+ }
+
+ /** */
+ @Test(expected = NonSymmetricMatrixException.class)
+ public void nonSymmetricMatrixTest() {
+ new CholeskyDecomposition(new DenseLocalOnHeapMatrix(new double[][] {
+ {2.0d, -1.0d, 10.0d},
+ {-1.0d, 2.0d, -1.0d},
+ {-10.0d, -1.0d, 2.0d}
+ }));
+ }
+
+ /** */
+ @Test(expected = NonPositiveDefiniteMatrixException.class)
+ public void nonAbsPositiveMatrixTest() {
+ new CholeskyDecomposition(new DenseLocalOnHeapMatrix(new double[][] {
+ {2.0d, -1.0d, 0.0d},
+ {-1.0d, 0.0d, -1.0d},
+ {0.0d, -1.0d, 2.0d}
+ }));
+ }
+
+ /** */
+ @Test(expected = CardinalityException.class)
+ public void solveWrongVectorSizeTest() {
+ new CholeskyDecomposition(new DenseLocalOnHeapMatrix(new double[][] {
+ {2.0d, -1.0d, 0.0d},
+ {-1.0d, 2.0d, -1.0d},
+ {0.0d, -1.0d, 2.0d}
+ })).solve(new DenseLocalOnHeapVector(2));
+ }
+
+ /** */
+ @Test(expected = CardinalityException.class)
+ public void solveWrongMatrixSizeTest() {
+ new CholeskyDecomposition(new DenseLocalOnHeapMatrix(new double[][] {
+ {2.0d, -1.0d, 0.0d},
+ {-1.0d, 2.0d, -1.0d},
+ {0.0d, -1.0d, 2.0d}
+ })).solve(new DenseLocalOnHeapMatrix(2, 3));
+ }
+
+ /** */
+ private void basicTest(Matrix m) {
+ // This decomposition is useful when dealing with systems of linear equations of the form
+ // m x = b where m is a Hermitian matrix.
+ // For such systems Cholesky decomposition provides
+ // more effective method of solving compared to LU decomposition.
+ // Suppose we want to solve system
+ // m x = b for various bs. Then after we computed Cholesky decomposition, we can feed various bs
+ // as a matrix of the form
+ // (b1, b2, ..., bm)
+ // to the method Cholesky::solve which returns solutions in the form
+ // (sol1, sol2, ..., solm)
+ CholeskyDecomposition dec = new CholeskyDecomposition(m);
+ assertEquals("Unexpected value for decomposition determinant.",
+ 4d, dec.getDeterminant(), 0d);
+
+ Matrix l = dec.getL();
+ Matrix lt = dec.getLT();
+
+ assertNotNull("Matrix l is expected to be not null.", l);
+ assertNotNull("Matrix lt is expected to be not null.", lt);
+
+ for (int row = 0; row < l.rowSize(); row++)
+ for (int col = 0; col < l.columnSize(); col++)
+ assertEquals("Unexpected value transposed matrix at (" + row + "," + col + ").",
+ l.get(row, col), lt.get(col, row), 0d);
+
+ Matrix bs = new DenseLocalOnHeapMatrix(new double[][] {
+ {4.0, -6.0, 7.0},
+ {1.0, 1.0, 1.0}
+ }).transpose();
+ Matrix sol = dec.solve(bs);
+
+ assertNotNull("Solution matrix is expected to be not null.", sol);
+ assertEquals("Solution rows are not as expected.", bs.rowSize(), sol.rowSize());
+ assertEquals("Solution columns are not as expected.", bs.columnSize(), sol.columnSize());
+
+ for (int i = 0; i < sol.columnSize(); i++)
+ assertNotNull("Solution matrix column is expected to be not null at index " + i, sol.viewColumn(i));
+
+ Vector b = new DenseLocalOnHeapVector(new double[] {4.0, -6.0, 7.0});
+ Vector solVec = dec.solve(b);
+
+ for (int idx = 0; idx < b.size(); idx++)
+ assertEquals("Unexpected value solution vector at " + idx,
+ b.get(idx), solVec.get(idx), 0d);
+
+ dec.destroy();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/732dfea9/modules/ml/src/test/java/org/apache/ignite/math/decompositions/EigenDecompositionTest.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/test/java/org/apache/ignite/math/decompositions/EigenDecompositionTest.java b/modules/ml/src/test/java/org/apache/ignite/math/decompositions/EigenDecompositionTest.java
new file mode 100644
index 0000000..e4e7b15
--- /dev/null
+++ b/modules/ml/src/test/java/org/apache/ignite/math/decompositions/EigenDecompositionTest.java
@@ -0,0 +1,193 @@
+/*
+ * 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.ignite.math.decompositions;
+
+import org.apache.ignite.math.Matrix;
+import org.apache.ignite.math.Vector;
+import org.apache.ignite.math.impls.matrix.DenseLocalOnHeapMatrix;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests for {@link EigenDecomposition}
+ */
+public class EigenDecompositionTest {
+ /** */
+ private static final double EPSILON = 1e-11;
+
+ /** */
+ @Test
+ public void testMatrixWithRealEigenvalues() {
+ test(new double[][] {
+ {1.0d, 0.0d, 0.0d, 0.0d},
+ {0.0d, 1.0d, 0.0d, 0.0d},
+ {0.0d, 0.0d, 2.0d, 0.0d},
+ {1.0d, 1.0d, 0.0d, 2.0d}},
+ new double[] {1, 2, 2, 1});
+ }
+
+ /** */
+ @Test
+ public void testSymmetricMatrix() {
+ EigenDecomposition decomposition = new EigenDecomposition(new DenseLocalOnHeapMatrix(new double[][] {
+ {1.0d, 0.0d, 0.0d, 1.0d},
+ {0.0d, 1.0d, 0.0d, 1.0d},
+ {0.0d, 0.0d, 2.0d, 0.0d},
+ {1.0d, 1.0d, 0.0d, 2.0d}}));
+
+ Matrix d = decomposition.getD();
+ Matrix v = decomposition.getV();
+
+ assertNotNull("Matrix d is expected to be not null.", d);
+ assertNotNull("Matrix v is expected to be not null.", v);
+
+ assertEquals("Unexpected rows in d matrix.", 4, d.rowSize());
+ assertEquals("Unexpected cols in d matrix.", 4, d.columnSize());
+
+ assertEquals("Unexpected rows in v matrix.", 4, v.rowSize());
+ assertEquals("Unexpected cols in v matrix.", 4, v.columnSize());
+
+ assertIsDiagonalNonZero(d);
+
+ decomposition.destroy();
+ }
+
+ /** */
+ @Test
+ public void testNonSquareMatrix() {
+ EigenDecomposition decomposition = new EigenDecomposition(new DenseLocalOnHeapMatrix(new double[][] {
+ {1.0d, 0.0d, 0.0d},
+ {0.0d, 1.0d, 0.0d},
+ {0.0d, 0.0d, 2.0d},
+ {1.0d, 1.0d, 0.0d}}));
+ // todo find out why decomposition of 3X4 matrix throws row index exception
+
+ Matrix d = decomposition.getD();
+ Matrix v = decomposition.getV();
+
+ assertNotNull("Matrix d is expected to be not null.", d);
+ assertNotNull("Matrix v is expected to be not null.", v);
+
+ assertEquals("Unexpected rows in d matrix.", 4, d.rowSize());
+ assertEquals("Unexpected cols in d matrix.", 4, d.columnSize());
+
+ assertEquals("Unexpected rows in v matrix.", 4, v.rowSize());
+ assertEquals("Unexpected cols in v matrix.", 3, v.columnSize());
+
+ assertIsDiagonal(d, true);
+
+ decomposition.destroy();
+ }
+
+ /** */
+ private void test(double[][] mRaw, double[] expRealEigenValues) {
+ DenseLocalOnHeapMatrix m = new DenseLocalOnHeapMatrix(mRaw);
+ EigenDecomposition decomposition = new EigenDecomposition(m);
+
+ Matrix d = decomposition.getD();
+ Matrix v = decomposition.getV();
+
+ assertIsDiagonalNonZero(d);
+
+ // check that d's diagonal consists of eigenvalues of m.
+ assertDiagonalConsistsOfEigenvalues(m, d, v);
+
+ // m = v d v^{-1} is equivalent to
+ // m v = v d
+ assertMatricesAreEqual(m.times(v), v.times(d));
+
+ assertEigenvalues(decomposition, expRealEigenValues);
+
+ decomposition.destroy();
+ }
+
+ /** */
+ private void assertEigenvalues(EigenDecomposition decomposition, double[] expRealEigenValues) {
+ Vector real = decomposition.getRealEigenValues();
+ Vector imag = decomposition.getImagEigenvalues();
+
+ assertEquals("Real values size differs from expected.", expRealEigenValues.length, real.size());
+ assertEquals("Imag values size differs from expected.", expRealEigenValues.length, imag.size());
+
+ for (int idx = 0; idx < expRealEigenValues.length; idx++) {
+ assertEquals("Real eigen value differs from expected at " + idx,
+ expRealEigenValues[idx], real.get(idx), 0d);
+
+ assertEquals("Imag eigen value differs from expected at " + idx,
+ 0d, imag.get(idx), 0d);
+ }
+
+ }
+
+ /** */
+ private void assertDiagonalConsistsOfEigenvalues(DenseLocalOnHeapMatrix m, Matrix d, Matrix v) {
+ int n = m.columnSize();
+ for (int i = 0; i < n; i++) {
+ Vector eigenVector = v.viewColumn(i);
+ double eigenVal = d.getX(i, i);
+ assertVectorsAreEqual(m.times(eigenVector), eigenVector.times(eigenVal));
+ }
+
+ }
+
+ /** */
+ private void assertMatricesAreEqual(Matrix exp, Matrix actual) {
+ assertTrue("The row sizes of matrices are not equal", exp.rowSize() == actual.rowSize());
+ assertTrue("The col sizes of matrices are not equal", exp.columnSize() == actual.columnSize());
+
+ // Since matrix is square, we need only one dimension
+ int n = exp.columnSize();
+
+ for (int i = 0; i < n; i++)
+ for (int j = 0; j < n; j++)
+ assertEquals("Values should be equal", exp.getX(i, j), actual.getX(i, j), EPSILON);
+ }
+
+ /** */
+ private void assertVectorsAreEqual(Vector exp, Vector actual) {
+ assertTrue("Vectors sizes are not equal", exp.size() == actual.size());
+
+ // Since matrix is square, we need only one dimension
+ int n = exp.size();
+
+ for (int i = 0; i < n; i++)
+ assertEquals("Values should be equal", exp.getX(i), actual.getX(i), EPSILON);
+ }
+
+ /** */
+ private void assertIsDiagonalNonZero(Matrix m) {
+ assertIsDiagonal(m, false);
+ }
+
+ /** */
+ private void assertIsDiagonal(Matrix m, boolean zeroesAllowed) {
+ // Since matrix is square, we need only one dimension
+ int n = m.columnSize();
+
+ assertEquals("Diagonal matrix is not square", n, m.rowSize());
+
+ for (int i = 0; i < n; i++)
+ for (int j = 0; j < n; j++)
+ assertTrue("Matrix is not diagonal, violation at (" + i + "," + j + ")",
+ ((i == j) && (zeroesAllowed || m.getX(i, j) != 0))
+ || ((i != j) && m.getX(i, j) == 0));
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/732dfea9/modules/ml/src/test/java/org/apache/ignite/math/decompositions/LUDecompositionTest.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/test/java/org/apache/ignite/math/decompositions/LUDecompositionTest.java b/modules/ml/src/test/java/org/apache/ignite/math/decompositions/LUDecompositionTest.java
new file mode 100644
index 0000000..0feb48f
--- /dev/null
+++ b/modules/ml/src/test/java/org/apache/ignite/math/decompositions/LUDecompositionTest.java
@@ -0,0 +1,250 @@
+/*
+ * 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.ignite.math.decompositions;
+
+import org.apache.ignite.math.Matrix;
+import org.apache.ignite.math.Vector;
+import org.apache.ignite.math.exceptions.CardinalityException;
+import org.apache.ignite.math.exceptions.SingularMatrixException;
+import org.apache.ignite.math.impls.matrix.DenseLocalOnHeapMatrix;
+import org.apache.ignite.math.impls.matrix.PivotedMatrixView;
+import org.apache.ignite.math.impls.vector.DenseLocalOnHeapVector;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Tests for {@link LUDecomposition}.
+ */
+public class LUDecompositionTest {
+ /** */
+ private Matrix testL;
+ /** */
+ private Matrix testU;
+ /** */
+ private Matrix testP;
+ /** */
+ private Matrix testMatrix;
+ /** */
+ private int[] rawPivot;
+
+ /** */
+ @Before
+ public void setUp() {
+ double[][] rawMatrix = new double[][] {
+ {2.0d, 1.0d, 1.0d, 0.0d},
+ {4.0d, 3.0d, 3.0d, 1.0d},
+ {8.0d, 7.0d, 9.0d, 5.0d},
+ {6.0d, 7.0d, 9.0d, 8.0d}};
+ double[][] rawL = {
+ {1.0d, 0.0d, 0.0d, 0.0d},
+ {3.0d / 4.0d, 1.0d, 0.0d, 0.0d},
+ {1.0d / 2.0d, -2.0d / 7.0d, 1.0d, 0.0d},
+ {1.0d / 4.0d, -3.0d / 7.0d, 1.0d / 3.0d, 1.0d}};
+ double[][] rawU = {
+ {8.0d, 7.0d, 9.0d, 5.0d},
+ {0.0d, 7.0d / 4.0d, 9.0d / 4.0d, 17.0d / 4.0d},
+ {0.0d, 0.0d, -6.0d / 7.0d, -2.0d / 7.0d},
+ {0.0d, 0.0d, 0.0d, 2.0d / 3.0d}};
+ double[][] rawP = new double[][] {
+ {0, 0, 1.0d, 0},
+ {0, 0, 0, 1.0d},
+ {0, 1.0d, 0, 0},
+ {1.0d, 0, 0, 0}};
+
+ rawPivot = new int[] {3, 4, 2, 1};
+
+ testMatrix = new DenseLocalOnHeapMatrix(rawMatrix);
+ testL = new DenseLocalOnHeapMatrix(rawL);
+ testU = new DenseLocalOnHeapMatrix(rawU);
+ testP = new DenseLocalOnHeapMatrix(rawP);
+ }
+
+ /** */
+ @Test
+ public void getL() throws Exception {
+ Matrix luDecompositionL = new LUDecomposition(testMatrix).getL();
+
+ assertEquals("Unexpected row size.", testL.rowSize(), luDecompositionL.rowSize());
+ assertEquals("Unexpected column size.", testL.columnSize(), luDecompositionL.columnSize());
+
+ for (int i = 0; i < testL.rowSize(); i++)
+ for (int j = 0; j < testL.columnSize(); j++)
+ assertEquals("Unexpected value at (" + i + "," + j + ").",
+ testL.getX(i, j), luDecompositionL.getX(i, j), 0.0000001d);
+
+ luDecompositionL.destroy();
+ }
+
+ /** */
+ @Test
+ public void getU() throws Exception {
+ Matrix luDecompositionU = new LUDecomposition(testMatrix).getU();
+
+ assertEquals("Unexpected row size.", testU.rowSize(), luDecompositionU.rowSize());
+ assertEquals("Unexpected column size.", testU.columnSize(), luDecompositionU.columnSize());
+
+ for (int i = 0; i < testU.rowSize(); i++)
+ for (int j = 0; j < testU.columnSize(); j++)
+ assertEquals("Unexpected value at (" + i + "," + j + ").",
+ testU.getX(i, j), luDecompositionU.getX(i, j), 0.0000001d);
+
+ luDecompositionU.destroy();
+ }
+
+ /** */
+ @Test
+ public void getP() throws Exception {
+ Matrix luDecompositionP = new LUDecomposition(testMatrix).getP();
+
+ assertEquals("Unexpected row size.", testP.rowSize(), luDecompositionP.rowSize());
+ assertEquals("Unexpected column size.", testP.columnSize(), luDecompositionP.columnSize());
+
+ for (int i = 0; i < testP.rowSize(); i++)
+ for (int j = 0; j < testP.columnSize(); j++)
+ assertEquals("Unexpected value at (" + i + "," + j + ").",
+ testP.getX(i, j), luDecompositionP.getX(i, j), 0.0000001d);
+
+ luDecompositionP.destroy();
+ }
+
+ /** */
+ @Test
+ public void getPivot() throws Exception {
+ Vector pivot = new LUDecomposition(testMatrix).getPivot();
+
+ assertEquals("Unexpected pivot size.", rawPivot.length, pivot.size());
+
+ for (int i = 0; i < testU.rowSize(); i++)
+ assertEquals("Unexpected value at " + i, rawPivot[i], (int)pivot.get(i) + 1);
+ }
+
+ /**
+ * Test for {@link DecompositionSupport} features.
+ */
+ @Test
+ public void decompositionSupportTest() {
+ LUDecomposition dec = new LUDecomposition(new PivotedMatrixView(testMatrix));
+ Matrix luDecompositionL = dec.getL();
+
+ assertEquals("Unexpected L row size.", testL.rowSize(), luDecompositionL.rowSize());
+ assertEquals("Unexpected L column size.", testL.columnSize(), luDecompositionL.columnSize());
+
+ for (int i = 0; i < testL.rowSize(); i++)
+ for (int j = 0; j < testL.columnSize(); j++)
+ assertEquals("Unexpected L value at (" + i + "," + j + ").",
+ testL.getX(i, j), luDecompositionL.getX(i, j), 0.0000001d);
+
+ Matrix luDecompositionU = dec.getU();
+
+ assertEquals("Unexpected U row size.", testU.rowSize(), luDecompositionU.rowSize());
+ assertEquals("Unexpected U column size.", testU.columnSize(), luDecompositionU.columnSize());
+
+ for (int i = 0; i < testU.rowSize(); i++)
+ for (int j = 0; j < testU.columnSize(); j++)
+ assertEquals("Unexpected U value at (" + i + "," + j + ").",
+ testU.getX(i, j), luDecompositionU.getX(i, j), 0.0000001d);
+
+ Matrix luDecompositionP = dec.getP();
+
+ assertEquals("Unexpected P row size.", testP.rowSize(), luDecompositionP.rowSize());
+ assertEquals("Unexpected P column size.", testP.columnSize(), luDecompositionP.columnSize());
+
+ for (int i = 0; i < testP.rowSize(); i++)
+ for (int j = 0; j < testP.columnSize(); j++)
+ assertEquals("Unexpected P value at (" + i + "," + j + ").",
+ testP.getX(i, j), luDecompositionP.getX(i, j), 0.0000001d);
+
+ dec.destroy();
+ }
+
+ /** */
+ @Test
+ public void singularDeterminant() throws Exception {
+ assertEquals("Unexpected determinant for singular matrix decomposition.",
+ 0d, new LUDecomposition(new DenseLocalOnHeapMatrix(2, 2)).determinant(), 0d);
+ }
+
+ /** */
+ @Test(expected = CardinalityException.class)
+ public void solveVecWrongSize() throws Exception {
+ new LUDecomposition(testMatrix).solve(new DenseLocalOnHeapVector(testMatrix.rowSize() + 1));
+ }
+
+ /** */
+ @Test(expected = SingularMatrixException.class)
+ public void solveVecSingularMatrix() throws Exception {
+ new LUDecomposition(new DenseLocalOnHeapMatrix(testMatrix.rowSize(), testMatrix.rowSize()))
+ .solve(new DenseLocalOnHeapVector(testMatrix.rowSize()));
+ }
+
+ /** */
+ @Test
+ public void solveVec() throws Exception {
+ Vector sol = new LUDecomposition(new PivotedMatrixView(testMatrix))
+ .solve(new DenseLocalOnHeapVector(testMatrix.rowSize()));
+
+ assertEquals("Wrong solution vector size.", testMatrix.rowSize(), sol.size());
+
+ for (int i = 0; i < sol.size(); i++)
+ assertEquals("Unexpected value at index " + i, 0d, sol.getX(i), 0.0000001d);
+ }
+
+ /** */
+ @Test(expected = CardinalityException.class)
+ public void solveMtxWrongSize() throws Exception {
+ new LUDecomposition(testMatrix).solve(
+ new DenseLocalOnHeapMatrix(testMatrix.rowSize() + 1, testMatrix.rowSize()));
+ }
+
+ /** */
+ @Test(expected = SingularMatrixException.class)
+ public void solveMtxSingularMatrix() throws Exception {
+ new LUDecomposition(new DenseLocalOnHeapMatrix(testMatrix.rowSize(), testMatrix.rowSize()))
+ .solve(new DenseLocalOnHeapMatrix(testMatrix.rowSize(), testMatrix.rowSize()));
+ }
+
+ /** */
+ @Test
+ public void solveMtx() throws Exception {
+ Matrix sol = new LUDecomposition(new PivotedMatrixView(testMatrix))
+ .solve(new DenseLocalOnHeapMatrix(testMatrix.rowSize(), testMatrix.rowSize()));
+
+ assertEquals("Wrong solution matrix row size.", testMatrix.rowSize(), sol.rowSize());
+
+ assertEquals("Wrong solution matrix column size.", testMatrix.rowSize(), sol.columnSize());
+
+ for (int row = 0; row < sol.rowSize(); row++)
+ for (int col = 0; col < sol.columnSize(); col++)
+ assertEquals("Unexpected P value at (" + row + "," + col + ").",
+ 0d, sol.getX(row, col), 0.0000001d);
+ }
+
+ /** */
+ @Test(expected = AssertionError.class)
+ public void nullMatrixTest() {
+ new LUDecomposition(null);
+ }
+
+ /** */
+ @Test(expected = CardinalityException.class)
+ public void nonSquareMatrixTest() {
+ new LUDecomposition(new DenseLocalOnHeapMatrix(2, 3));
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/732dfea9/modules/ml/src/test/java/org/apache/ignite/math/decompositions/QRDecompositionTest.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/test/java/org/apache/ignite/math/decompositions/QRDecompositionTest.java b/modules/ml/src/test/java/org/apache/ignite/math/decompositions/QRDecompositionTest.java
new file mode 100644
index 0000000..3bb92d1
--- /dev/null
+++ b/modules/ml/src/test/java/org/apache/ignite/math/decompositions/QRDecompositionTest.java
@@ -0,0 +1,139 @@
+/*
+ * 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.ignite.math.decompositions;
+
+import org.apache.ignite.math.Matrix;
+import org.apache.ignite.math.impls.matrix.DenseLocalOnHeapMatrix;
+import org.apache.ignite.math.impls.matrix.PivotedMatrixView;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/** */
+public class QRDecompositionTest {
+ /** */
+ @Test
+ public void basicTest() {
+ basicTest(new DenseLocalOnHeapMatrix(new double[][] {
+ {2.0d, -1.0d, 0.0d},
+ {-1.0d, 2.0d, -1.0d},
+ {0.0d, -1.0d, 2.0d}
+ }));
+ }
+
+ /**
+ * Test for {@link DecompositionSupport} features.
+ */
+ @Test
+ public void decompositionSupportTest() {
+ basicTest(new PivotedMatrixView(new DenseLocalOnHeapMatrix(new double[][] {
+ {2.0d, -1.0d, 0.0d},
+ {-1.0d, 2.0d, -1.0d},
+ {0.0d, -1.0d, 2.0d}
+ })));
+ }
+
+ /** */
+ @Test(expected = AssertionError.class)
+ public void nullMatrixTest() {
+ new QRDecomposition(null);
+ }
+
+ /** */
+ @Test(expected = IllegalArgumentException.class)
+ public void solveWrongMatrixSizeTest() {
+ new QRDecomposition(new DenseLocalOnHeapMatrix(new double[][] {
+ {2.0d, -1.0d, 0.0d},
+ {-1.0d, 2.0d, -1.0d},
+ {0.0d, -1.0d, 2.0d}
+ })).solve(new DenseLocalOnHeapMatrix(2, 3));
+ }
+
+ /** */
+ private void basicTest(Matrix m) {
+ QRDecomposition dec = new QRDecomposition(m);
+ assertTrue("Unexpected value for full rank in decomposition " + dec, dec.hasFullRank());
+
+ Matrix q = dec.getQ();
+ Matrix r = dec.getR();
+
+ assertNotNull("Matrix q is expected to be not null.", q);
+ assertNotNull("Matrix r is expected to be not null.", r);
+
+ Matrix qSafeCp = safeCopy(q);
+
+ Matrix expIdentity = qSafeCp.times(qSafeCp.transpose());
+
+ final double delta = 0.0001;
+
+ for (int row = 0; row < expIdentity.rowSize(); row++)
+ for (int col = 0; col < expIdentity.columnSize(); col++)
+ assertEquals("Unexpected identity matrix value at (" + row + "," + col + ").",
+ row == col ? 1d : 0d, expIdentity.get(col, row), delta);
+
+ for (int row = 0; row < r.rowSize(); row++)
+ for (int col = 0; col < row - 1; col++)
+ assertEquals("Unexpected upper triangular matrix value at (" + row + "," + col + ").",
+ 0d, r.get(row, col), delta);
+
+ Matrix recomposed = qSafeCp.times(r);
+
+ for (int row = 0; row < m.rowSize(); row++)
+ for (int col = 0; col < m.columnSize(); col++)
+ assertEquals("Unexpected recomposed matrix value at (" + row + "," + col + ").",
+ m.get(row, col), recomposed.get(row, col), delta);
+
+ Matrix sol = dec.solve(new DenseLocalOnHeapMatrix(3, 10));
+ assertEquals("Unexpected rows in solution matrix.", 3, sol.rowSize());
+ assertEquals("Unexpected cols in solution matrix.", 10, sol.columnSize());
+
+ for (int row = 0; row < sol.rowSize(); row++)
+ for (int col = 0; col < sol.columnSize(); col++)
+ assertEquals("Unexpected solution matrix value at (" + row + "," + col + ").",
+ 0d, sol.get(row, col), delta);
+
+ dec.destroy();
+
+ QRDecomposition dec1 = new QRDecomposition(new DenseLocalOnHeapMatrix(new double[][] {
+ {2.0d, -1.0d},
+ {-1.0d, 2.0d},
+ {0.0d, -1.0d}
+ }));
+
+ assertTrue("Unexpected value for full rank in decomposition " + dec1, dec1.hasFullRank());
+
+ dec1.destroy();
+
+ QRDecomposition dec2 = new QRDecomposition(new DenseLocalOnHeapMatrix(new double[][] {
+ {2.0d, -1.0d, 0.0d, 0.0d},
+ {-1.0d, 2.0d, -1.0d, 0.0d},
+ {0.0d, -1.0d, 2.0d, 0.0d}
+ }));
+
+ assertTrue("Unexpected value for full rank in decomposition " + dec2, dec2.hasFullRank());
+
+ dec2.destroy();
+ }
+
+ /** */
+ private Matrix safeCopy(Matrix orig) {
+ return new DenseLocalOnHeapMatrix(orig.rowSize(), orig.columnSize()).assign(orig);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/732dfea9/modules/ml/src/test/java/org/apache/ignite/math/decompositions/SingularValueDecompositionTest.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/test/java/org/apache/ignite/math/decompositions/SingularValueDecompositionTest.java b/modules/ml/src/test/java/org/apache/ignite/math/decompositions/SingularValueDecompositionTest.java
new file mode 100644
index 0000000..d0b89f8
--- /dev/null
+++ b/modules/ml/src/test/java/org/apache/ignite/math/decompositions/SingularValueDecompositionTest.java
@@ -0,0 +1,120 @@
+/*
+ * 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.ignite.math.decompositions;
+
+import org.apache.ignite.math.Matrix;
+import org.apache.ignite.math.impls.matrix.DenseLocalOnHeapMatrix;
+import org.apache.ignite.math.impls.matrix.PivotedMatrixView;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/** */
+public class SingularValueDecompositionTest {
+ /** */
+ @Test
+ public void basicTest() {
+ basicTest(new DenseLocalOnHeapMatrix(new double[][] {
+ {2.0d, -1.0d, 0.0d},
+ {-1.0d, 2.0d, -1.0d},
+ {0.0d, -1.0d, 2.0d}
+ }));
+ }
+
+ /**
+ * Test for {@link DecompositionSupport} features.
+ */
+ @Test
+ public void decompositionSupportTest() {
+ basicTest(new PivotedMatrixView(new DenseLocalOnHeapMatrix(new double[][] {
+ {2.0d, -1.0d, 0.0d},
+ {-1.0d, 2.0d, -1.0d},
+ {0.0d, -1.0d, 2.0d}
+ })));
+ }
+
+ /** */
+ @Test
+ public void rowsLessThanColumnsTest() {
+ DenseLocalOnHeapMatrix m = new DenseLocalOnHeapMatrix(new double[][] {
+ {2.0d, -1.0d, 0.0d},
+ {-1.0d, 2.0d, -1.0d}
+ });
+
+ SingularValueDecomposition dec = new SingularValueDecomposition(m);
+ assertEquals("Unexpected value for singular values size.",
+ 2, dec.getSingularValues().length);
+
+ Matrix s = dec.getS();
+ Matrix u = dec.getU();
+ Matrix v = dec.getV();
+ Matrix covariance = dec.getCovariance(0.5);
+
+ assertNotNull("Matrix s is expected to be not null.", s);
+ assertNotNull("Matrix u is expected to be not null.", u);
+ assertNotNull("Matrix v is expected to be not null.", v);
+ assertNotNull("Covariance matrix is expected to be not null.", covariance);
+
+ dec.destroy();
+ }
+
+ /** */
+ @Test(expected = AssertionError.class)
+ public void nullMatrixTest() {
+ new SingularValueDecomposition(null);
+ }
+
+ /** */
+ private void basicTest(Matrix m) {
+ SingularValueDecomposition dec = new SingularValueDecomposition(m);
+ assertEquals("Unexpected value for singular values size.",
+ 3, dec.getSingularValues().length);
+
+ Matrix s = dec.getS();
+ Matrix u = dec.getU();
+ Matrix v = dec.getV();
+ Matrix covariance = dec.getCovariance(0.5);
+
+ assertNotNull("Matrix s is expected to be not null.", s);
+ assertNotNull("Matrix u is expected to be not null.", u);
+ assertNotNull("Matrix v is expected to be not null.", v);
+ assertNotNull("Covariance matrix is expected to be not null.", covariance);
+
+ assertTrue("Decomposition cond is expected to be positive.", dec.cond() > 0);
+ assertTrue("Decomposition norm2 is expected to be positive.", dec.norm2() > 0);
+ assertEquals("Decomposition rank differs from expected.", 3, dec.rank());
+ assertEquals("Decomposition singular values size differs from expected.",
+ 3, dec.getSingularValues().length);
+
+ Matrix recomposed = (u.times(s).times(v.transpose()));
+
+ for (int row = 0; row < m.rowSize(); row++)
+ for (int col = 0; col < m.columnSize(); col++)
+ assertEquals("Unexpected recomposed matrix value at (" + row + "," + col + ").",
+ m.get(row, col), recomposed.get(row, col), 0.001);
+
+ for (int row = 0; row < covariance.rowSize(); row++)
+ for (int col = row + 1; col < covariance.columnSize(); col++)
+ assertEquals("Unexpected covariance matrix value at (" + row + "," + col + ").",
+ covariance.get(row, col), covariance.get(col, row), 0.001);
+
+ dec.destroy();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/732dfea9/modules/ml/src/test/java/org/apache/ignite/math/impls/MathTestConstants.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/test/java/org/apache/ignite/math/impls/MathTestConstants.java b/modules/ml/src/test/java/org/apache/ignite/math/impls/MathTestConstants.java
new file mode 100644
index 0000000..122c62e
--- /dev/null
+++ b/modules/ml/src/test/java/org/apache/ignite/math/impls/MathTestConstants.java
@@ -0,0 +1,88 @@
+/*
+ * 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.ignite.math.impls;
+
+/**
+ * Collect constants for org.apache.ignite.math tests
+ */
+public interface MathTestConstants {
+ /** */
+ public double SECOND_ARG = 1d;
+
+ /**
+ * We assume that we will check calculation precision in other tests.
+ */
+ public double EXP_DELTA = 0.1d;
+
+ /** */
+ public String UNEXPECTED_VAL = "Unexpected value.";
+
+ /** */
+ public String NULL_GUID = "Null GUID.";
+
+ /** */
+ public String UNEXPECTED_GUID_VAL = "Unexpected GUID value.";
+
+ /** */
+ public String EMPTY_GUID = "Empty GUID.";
+
+ /** */
+ public String VALUES_SHOULD_BE_NOT_EQUALS = "Values should be not equals.";
+
+ /** */
+ public String NULL_VAL = "Null value.";
+
+ /** */
+ public String NULL_VALUES = "Null values.";
+
+ /** */
+ public String NOT_NULL_VAL = "Not null value.";
+
+ /** */
+ public double TEST_VAL = 1d;
+
+ /** */
+ public String VAL_NOT_EQUALS = "Values not equals.";
+
+ /** */
+ public String NO_NEXT_ELEMENT = "No next element.";
+
+ /** */
+ public int STORAGE_SIZE = 100;
+
+ /** */
+ public String WRONG_ATTRIBUTE_VAL = "Wrong attribute value.";
+
+ /** */
+ public String NULL_DATA_ELEMENT = "Null data element.";
+
+ /** */
+ public String WRONG_DATA_ELEMENT = "Wrong data element.";
+
+ /** */
+ public double NIL_DELTA = 0d;
+
+ /** */
+ public String NULL_DATA_STORAGE = "Null data storage.";
+
+ /** */
+ public String WRONG_DATA_SIZE = "Wrong data size.";
+
+ /** */
+ public String UNEXPECTED_DATA_VAL = "Unexpected data value.";
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/732dfea9/modules/ml/src/test/java/org/apache/ignite/math/impls/matrix/CacheMatrixTest.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/test/java/org/apache/ignite/math/impls/matrix/CacheMatrixTest.java b/modules/ml/src/test/java/org/apache/ignite/math/impls/matrix/CacheMatrixTest.java
new file mode 100644
index 0000000..8a6d077
--- /dev/null
+++ b/modules/ml/src/test/java/org/apache/ignite/math/impls/matrix/CacheMatrixTest.java
@@ -0,0 +1,369 @@
+/*
+ * 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.ignite.math.impls.matrix;
+
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.internal.util.IgniteUtils;
+import org.apache.ignite.math.ExternalizeTest;
+import org.apache.ignite.math.IdentityValueMapper;
+import org.apache.ignite.math.Matrix;
+import org.apache.ignite.math.MatrixKeyMapper;
+import org.apache.ignite.math.exceptions.UnsupportedOperationException;
+import org.apache.ignite.math.impls.MathTestConstants;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.apache.ignite.testframework.junits.common.GridCommonTest;
+
+/**
+ * Tests for {@link CacheMatrix}.
+ */
+@GridCommonTest(group = "Distributed Models")
+public class CacheMatrixTest extends GridCommonAbstractTest {
+ /** Number of nodes in grid */
+ private static final int NODE_COUNT = 3;
+ /** Cache name. */
+ private static final String CACHE_NAME = "test-cache";
+ /** */
+ private static final String UNEXPECTED_ATTRIBUTE_VALUE = "Unexpected attribute value.";
+ /** Grid instance. */
+ private Ignite ignite;
+ /** Matrix rows */
+ private final int rows = MathTestConstants.STORAGE_SIZE;
+ /** Matrix cols */
+ private final int cols = MathTestConstants.STORAGE_SIZE;
+
+ /**
+ * Default constructor.
+ */
+ public CacheMatrixTest() {
+ super(false);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTestsStarted() throws Exception {
+ for (int i = 1; i <= NODE_COUNT; i++)
+ startGrid(i);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTestsStopped() throws Exception {
+ stopAllGrids();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override protected void beforeTest() throws Exception {
+ ignite = grid(NODE_COUNT);
+
+ ignite.configuration().setPeerClassLoadingEnabled(true);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTest() throws Exception {
+ ignite.destroyCache(CACHE_NAME);
+ }
+
+ /** */
+ public void testGetSet() throws Exception {
+ MatrixKeyMapper<Integer> keyMapper = getKeyMapper(rows, cols);
+ IgniteCache<Integer, Double> cache = getCache();
+ CacheMatrix<Integer, Double> cacheMatrix = new CacheMatrix<>(rows, cols, cache, keyMapper, new IdentityValueMapper());
+
+ for (int i = 0; i < rows; i++) {
+ for (int j = 0; j < cols; j++) {
+ double v = Math.random();
+ cacheMatrix.set(i, j, v);
+
+ assert Double.compare(v, cacheMatrix.get(i, j)) == 0;
+ assert Double.compare(v, cache.get(keyMapper.apply(i, j))) == 0;
+ }
+ }
+ }
+
+ /** */
+ public void testCopy() throws Exception {
+ MatrixKeyMapper<Integer> keyMapper = getKeyMapper(rows, cols);
+ IgniteCache<Integer, Double> cache = getCache();
+ CacheMatrix<Integer, Double> cacheMatrix = new CacheMatrix<>(rows, cols, cache, keyMapper, new IdentityValueMapper());
+
+ fillMatrix(cacheMatrix);
+
+ try {
+ cacheMatrix.copy();
+
+ fail("UnsupportedOperationException expected");
+ }
+ catch (UnsupportedOperationException e) {
+ // No-op.
+ }
+ }
+
+ /** */
+ public void testLike() throws Exception {
+ MatrixKeyMapper<Integer> keyMapper = getKeyMapper(rows, cols);
+ IgniteCache<Integer, Double> cache = getCache();
+ CacheMatrix<Integer, Double> cacheMatrix = new CacheMatrix<>(rows, cols, cache, keyMapper, new IdentityValueMapper());
+
+ try {
+ cacheMatrix.like(rows, cols);
+
+ fail("UnsupportedOperationException expected");
+ }
+ catch (UnsupportedOperationException e) {
+ // No-op.
+ }
+ }
+
+ /** */
+ public void testLikeVector() throws Exception {
+ MatrixKeyMapper<Integer> keyMapper = getKeyMapper(rows, cols);
+ IgniteCache<Integer, Double> cache = getCache();
+ CacheMatrix<Integer, Double> cacheMatrix = new CacheMatrix<>(rows, cols, cache, keyMapper, new IdentityValueMapper());
+
+ try {
+ cacheMatrix.likeVector(cols);
+
+ fail("UnsupportedOperationException expected");
+ }
+ catch (UnsupportedOperationException e) {
+ // No-op.
+ }
+ }
+
+ /** */
+ public void testPlus() {
+ IgniteUtils.setCurrentIgniteName(ignite.configuration().getIgniteInstanceName());
+
+ double plusVal = 2;
+
+ MatrixKeyMapper<Integer> keyMapper = getKeyMapper(rows, cols);
+ IgniteCache<Integer, Double> cache = getCache();
+ CacheMatrix<Integer, Double> cacheMatrix = new CacheMatrix<>(rows, cols, cache, keyMapper, new IdentityValueMapper());
+
+ initMatrix(cacheMatrix);
+
+ cacheMatrix.plus(plusVal);
+
+ for (int i = 0; i < rows; i++)
+ for (int j = 0; j < cols; j++)
+ assertEquals(plusVal, cacheMatrix.get(i, j));
+ }
+
+ /** */
+ public void testDivide() {
+ IgniteUtils.setCurrentIgniteName(ignite.configuration().getIgniteInstanceName());
+
+ double initVal = 1;
+ double divVal = 2;
+
+ MatrixKeyMapper<Integer> keyMapper = getKeyMapper(rows, cols);
+ IgniteCache<Integer, Double> cache = getCache();
+ CacheMatrix<Integer, Double> cacheMatrix = new CacheMatrix<>(rows, cols, cache, keyMapper, new IdentityValueMapper());
+
+ initMatrix(cacheMatrix);
+ cacheMatrix.assign(initVal);
+ cacheMatrix.divide(divVal);
+
+ for (int i = 0; i < rows; i++)
+ for (int j = 0; j < cols; j++)
+ assertTrue(Double.compare(cacheMatrix.get(i, j), initVal / divVal) == 0);
+ }
+
+ /** */
+ public void testTimes() {
+ IgniteUtils.setCurrentIgniteName(ignite.configuration().getIgniteInstanceName());
+
+ double initVal = 1;
+ double timVal = 2;
+
+ MatrixKeyMapper<Integer> keyMapper = getKeyMapper(rows, cols);
+ IgniteCache<Integer, Double> cache = getCache();
+ CacheMatrix<Integer, Double> cacheMatrix = new CacheMatrix<>(rows, cols, cache, keyMapper, new IdentityValueMapper());
+
+ initMatrix(cacheMatrix);
+ cacheMatrix.assign(initVal);
+ cacheMatrix.times(timVal);
+
+ for (int i = 0; i < rows; i++)
+ for (int j = 0; j < cols; j++)
+ assertTrue(Double.compare(cacheMatrix.get(i, j), initVal * timVal) == 0);
+ }
+
+ /** */
+ public void testSum() {
+ IgniteUtils.setCurrentIgniteName(ignite.configuration().getIgniteInstanceName());
+
+ double initVal = 1;
+
+ MatrixKeyMapper<Integer> keyMapper = getKeyMapper(rows, cols);
+ IgniteCache<Integer, Double> cache = getCache();
+ CacheMatrix<Integer, Double> cacheMatrix = new CacheMatrix<>(rows, cols, cache, keyMapper, new IdentityValueMapper());
+
+ double sum = 0;
+
+ initMatrix(cacheMatrix);
+ sum = cacheMatrix.sum();
+
+ assertTrue(Double.compare(sum, 0d) == 0);
+
+ cacheMatrix.assign(1d);
+ sum = cacheMatrix.sum();
+
+ assertTrue(Double.compare(sum, rows * cols) == 0);
+ }
+
+ /** */
+ public void testAssignSingleValue() {
+ IgniteUtils.setCurrentIgniteName(ignite.configuration().getIgniteInstanceName());
+
+ double initVal = 1;
+
+ MatrixKeyMapper<Integer> keyMapper = getKeyMapper(rows, cols);
+ IgniteCache<Integer, Double> cache = getCache();
+ CacheMatrix<Integer, Double> cacheMatrix = new CacheMatrix<>(rows, cols, cache, keyMapper, new IdentityValueMapper());
+
+ initMatrix(cacheMatrix);
+
+ cacheMatrix.assign(initVal);
+
+ for (int i = 0; i < rows; i++)
+ for (int j = 0; j < cols; j++)
+ assertEquals(initVal, cacheMatrix.get(i, j));
+ }
+
+ /** */
+ public void testAssignArray() {
+ IgniteUtils.setCurrentIgniteName(ignite.configuration().getIgniteInstanceName());
+
+ double[][] initVal = new double[rows][cols];
+
+ MatrixKeyMapper<Integer> keyMapper = getKeyMapper(rows, cols);
+ IgniteCache<Integer, Double> cache = getCache();
+ CacheMatrix<Integer, Double> cacheMatrix = new CacheMatrix<>(rows, cols, cache, keyMapper, new IdentityValueMapper());
+
+ for (int i = 0; i < rows; i++)
+ for (int j = 0; j < cols; j++)
+ initVal[i][j] = Math.random();
+
+ cacheMatrix.assign(initVal);
+
+ for (int i = 0; i < rows; i++)
+ for (int j = 0; j < cols; j++)
+ assertEquals(initVal[i][j], cacheMatrix.get(i, j));
+ }
+
+ /** */
+ public void testAttributes() {
+ IgniteUtils.setCurrentIgniteName(ignite.configuration().getIgniteInstanceName());
+
+ MatrixKeyMapper<Integer> keyMapper = getKeyMapper(rows, cols);
+ IgniteCache<Integer, Double> cache = getCache();
+ CacheMatrix<Integer, Double> cacheMatrix = new CacheMatrix<>(rows, cols, cache, keyMapper, new IdentityValueMapper());
+
+ assertFalse(UNEXPECTED_ATTRIBUTE_VALUE, cacheMatrix.isSequentialAccess());
+ assertFalse(UNEXPECTED_ATTRIBUTE_VALUE, cacheMatrix.isDense());
+ assertFalse(UNEXPECTED_ATTRIBUTE_VALUE, cacheMatrix.isArrayBased());
+ assertTrue(UNEXPECTED_ATTRIBUTE_VALUE, cacheMatrix.isRandomAccess());
+ assertTrue(UNEXPECTED_ATTRIBUTE_VALUE, cacheMatrix.isDistributed());
+ }
+
+ /** */
+ public void testExternalization() {
+ IgniteUtils.setCurrentIgniteName(ignite.configuration().getIgniteInstanceName());
+
+ MatrixKeyMapper<Integer> keyMapper = getKeyMapper(rows, cols);
+ IgniteCache<Integer, Double> cache = getCache();
+ final CacheMatrix<Integer, Double> cacheMatrix = new CacheMatrix<>(rows, cols, cache, keyMapper, new IdentityValueMapper());
+
+ ExternalizeTest<CacheMatrix<Integer, Double>> externalizeTest = new ExternalizeTest<CacheMatrix<Integer, Double>>() {
+
+ @Override public void externalizeTest() {
+ super.externalizeTest(cacheMatrix);
+ }
+ };
+
+ externalizeTest.externalizeTest();
+ }
+
+ /** */
+ public void testMinMax() {
+ IgniteUtils.setCurrentIgniteName(ignite.configuration().getIgniteInstanceName());
+
+ MatrixKeyMapper<Integer> keyMapper = getKeyMapper(rows, cols);
+ IgniteCache<Integer, Double> cache = getCache();
+ final CacheMatrix<Integer, Double> cacheMatrix = new CacheMatrix<>(rows, cols, cache, keyMapper, new IdentityValueMapper());
+
+ for (int i = 0; i < rows; i++)
+ for (int j = 0; j < cols; j++)
+ cacheMatrix.set(i, j, i * rows + j);
+
+ assertEquals(0.0, cacheMatrix.minValue(), 0.0);
+ assertEquals(rows * cols - 1, cacheMatrix.maxValue(), 0.0);
+ }
+
+ /** */
+ public void testMap() {
+ IgniteUtils.setCurrentIgniteName(ignite.configuration().getIgniteInstanceName());
+
+ MatrixKeyMapper<Integer> keyMapper = getKeyMapper(rows, cols);
+ IgniteCache<Integer, Double> cache = getCache();
+ final CacheMatrix<Integer, Double> cacheMatrix = new CacheMatrix<>(rows, cols, cache, keyMapper, new IdentityValueMapper());
+
+ initMatrix(cacheMatrix);
+
+ cacheMatrix.map(value -> value + 10);
+
+ for (int i = 0; i < rows; i++)
+ for (int j = 0; j < cols; j++)
+ assertEquals(10.0, cacheMatrix.getX(i, j), 0.0);
+ }
+
+ /** */
+ private IgniteCache<Integer, Double> getCache() {
+ assert ignite != null;
+
+ CacheConfiguration cfg = new CacheConfiguration();
+ cfg.setName(CACHE_NAME);
+
+ IgniteCache<Integer, Double> cache = ignite.getOrCreateCache(CACHE_NAME);
+
+ assert cache != null;
+ return cache;
+ }
+
+ /** */
+ private MatrixKeyMapper<Integer> getKeyMapper(final int rows, final int cols) {
+ return new MatrixKeyMapperForTests(rows, cols);
+ }
+
+ /** Init the given matrix by random values. */
+ private void fillMatrix(Matrix m) {
+ for (int i = 0; i < m.rowSize(); i++)
+ for (int j = 0; j < m.columnSize(); j++)
+ m.set(i, j, Math.random());
+ }
+
+ /** Init the given matrix by zeros. */
+ private void initMatrix(Matrix m) {
+ for (int i = 0; i < m.rowSize(); i++)
+ for (int j = 0; j < m.columnSize(); j++)
+ m.set(i, j, 0d);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/732dfea9/modules/ml/src/test/java/org/apache/ignite/math/impls/matrix/DenseLocalOffHeapMatrixConstructorTest.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/test/java/org/apache/ignite/math/impls/matrix/DenseLocalOffHeapMatrixConstructorTest.java b/modules/ml/src/test/java/org/apache/ignite/math/impls/matrix/DenseLocalOffHeapMatrixConstructorTest.java
new file mode 100644
index 0000000..1f0537c
--- /dev/null
+++ b/modules/ml/src/test/java/org/apache/ignite/math/impls/matrix/DenseLocalOffHeapMatrixConstructorTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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.ignite.math.impls.matrix;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/** */
+public class DenseLocalOffHeapMatrixConstructorTest {
+ /** */
+ @Test
+ public void invalidArgsTest() {
+ DenseLocalOnHeapMatrixConstructorTest.verifyAssertionError(() -> new DenseLocalOffHeapMatrix(0, 1), "invalid row parameter");
+
+ DenseLocalOnHeapMatrixConstructorTest.verifyAssertionError(() -> new DenseLocalOffHeapMatrix(1, 0), "invalid col parameter");
+
+ //noinspection ConstantConditions
+ DenseLocalOnHeapMatrixConstructorTest.verifyAssertionError(() -> new DenseLocalOffHeapMatrix(null), "null matrix parameter");
+
+ DenseLocalOnHeapMatrixConstructorTest.verifyAssertionError(() -> new DenseLocalOffHeapMatrix(new double[][] {null, new double[1]}),
+ "null row in matrix");
+ }
+
+ /** */
+ @Test
+ public void basicTest() {
+ assertEquals("Expected number of rows, int parameters.", 1,
+ new DenseLocalOffHeapMatrix(1, 2).rowSize());
+
+ assertEquals("Expected number of rows, double[][] parameter.", 1,
+ new DenseLocalOffHeapMatrix(new double[][] {new double[2]}).rowSize());
+
+ assertEquals("Expected number of cols, int parameters.", 1,
+ new DenseLocalOffHeapMatrix(2, 1).columnSize());
+
+ assertEquals("Expected number of cols, double[][] parameter.", 1,
+ new DenseLocalOffHeapMatrix(new double[][] {new double[1], new double[1]}).columnSize());
+
+ double[][] data1 = new double[][] {{1, 2}, {3, 4}}, data2 = new double[][] {{1, 2}, {3, 5}};
+
+ assertTrue("Matrices with same values are expected to be equal",
+ new DenseLocalOffHeapMatrix(data1).equals(new DenseLocalOffHeapMatrix(data1)));
+
+ assertFalse("Matrices with same values are expected to be equal",
+ new DenseLocalOffHeapMatrix(data1).equals(new DenseLocalOffHeapMatrix(data2)));
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/732dfea9/modules/ml/src/test/java/org/apache/ignite/math/impls/matrix/DenseLocalOnHeapMatrixConstructorTest.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/test/java/org/apache/ignite/math/impls/matrix/DenseLocalOnHeapMatrixConstructorTest.java b/modules/ml/src/test/java/org/apache/ignite/math/impls/matrix/DenseLocalOnHeapMatrixConstructorTest.java
new file mode 100644
index 0000000..0a25e31
--- /dev/null
+++ b/modules/ml/src/test/java/org/apache/ignite/math/impls/matrix/DenseLocalOnHeapMatrixConstructorTest.java
@@ -0,0 +1,71 @@
+/*
+ * 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.ignite.math.impls.matrix;
+
+import java.util.function.Supplier;
+import org.apache.ignite.math.Matrix;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+/** */
+public class DenseLocalOnHeapMatrixConstructorTest {
+ /** */
+ @Test
+ public void invalidArgsTest() {
+ verifyAssertionError(() -> new DenseLocalOnHeapMatrix(0, 1), "invalid row parameter");
+
+ verifyAssertionError(() -> new DenseLocalOnHeapMatrix(1, 0), "invalid col parameter");
+
+ //noinspection ConstantConditions
+ verifyAssertionError(() -> new DenseLocalOnHeapMatrix(null), "null matrix parameter");
+
+ verifyAssertionError(() -> new DenseLocalOnHeapMatrix(new double[][] {null, new double[1]}),
+ "null row in matrix");
+ }
+
+ /** */
+ @Test
+ public void basicTest() {
+ assertEquals("Expected number of rows, int parameters.", 1,
+ new DenseLocalOnHeapMatrix(1, 2).rowSize());
+
+ assertEquals("Expected number of rows, double[][] parameter.", 1,
+ new DenseLocalOnHeapMatrix(new double[][] {new double[2]}).rowSize());
+
+ assertEquals("Expected number of cols, int parameters.", 1,
+ new DenseLocalOnHeapMatrix(2, 1).columnSize());
+
+ assertEquals("Expected number of cols, double[][] parameter.", 1,
+ new DenseLocalOnHeapMatrix(new double[][] {new double[1], new double[1]}).columnSize());
+ }
+
+ /** */
+ static void verifyAssertionError(Supplier<Matrix> ctor, String desc) {
+ try {
+ assertNotNull("Unexpected null matrix in " + desc, ctor.get());
+ }
+ catch (AssertionError ae) {
+ return;
+ }
+
+ fail("Expected error not caught in " + desc);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/732dfea9/modules/ml/src/test/java/org/apache/ignite/math/impls/matrix/DiagonalMatrixTest.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/test/java/org/apache/ignite/math/impls/matrix/DiagonalMatrixTest.java b/modules/ml/src/test/java/org/apache/ignite/math/impls/matrix/DiagonalMatrixTest.java
new file mode 100644
index 0000000..c0c2af7
--- /dev/null
+++ b/modules/ml/src/test/java/org/apache/ignite/math/impls/matrix/DiagonalMatrixTest.java
@@ -0,0 +1,209 @@
+/*
+ * 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.ignite.math.impls.matrix;
+
+import org.apache.ignite.math.ExternalizeTest;
+import org.apache.ignite.math.Matrix;
+import org.apache.ignite.math.Vector;
+import org.apache.ignite.math.exceptions.UnsupportedOperationException;
+import org.apache.ignite.math.impls.MathTestConstants;
+import org.apache.ignite.math.impls.vector.DenseLocalOnHeapVector;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * Tests for {@link DiagonalMatrix}.
+ */
+public class DiagonalMatrixTest extends ExternalizeTest<DiagonalMatrix> {
+ /** */
+ public static final String UNEXPECTED_VALUE = "Unexpected value";
+
+ /** */
+ private DiagonalMatrix testMatrix;
+
+ /** */
+ @Before
+ public void setup() {
+ DenseLocalOnHeapMatrix parent = new DenseLocalOnHeapMatrix(MathTestConstants.STORAGE_SIZE, MathTestConstants.STORAGE_SIZE);
+ fillMatrix(parent);
+ testMatrix = new DiagonalMatrix(parent);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void externalizeTest() {
+ externalizeTest(testMatrix);
+ }
+
+ /** */
+ @Test
+ public void testSetGetBasic() {
+ double testVal = 42;
+ for (int i = 0; i < MathTestConstants.STORAGE_SIZE; i++) {
+ testMatrix.set(i, i, testVal);
+
+ assertEquals(UNEXPECTED_VALUE + " at (" + i + "," + i + ")", testMatrix.get(i, i), testVal, 0d);
+ }
+
+ //noinspection EqualsWithItself
+ assertTrue("Matrix is expected to be equal to self.", testMatrix.equals(testMatrix));
+ //noinspection ObjectEqualsNull
+ assertFalse("Matrix is expected to be not equal to null.", testMatrix.equals(null));
+ }
+
+ /** */
+ @Test
+ public void testSetGet() {
+ verifyDiagonal(testMatrix);
+
+ final int size = MathTestConstants.STORAGE_SIZE;
+
+ for (Matrix m : new Matrix[] {
+ new DenseLocalOnHeapMatrix(size + 1, size),
+ new DenseLocalOnHeapMatrix(size, size + 1)}) {
+ fillMatrix(m);
+
+ verifyDiagonal(new DiagonalMatrix(m));
+ }
+
+ final double[] data = new double[size];
+
+ for (int i = 0; i < size; i++)
+ data[i] = 1 + i;
+
+ final Matrix m = new DiagonalMatrix(new DenseLocalOnHeapVector(data));
+
+ assertEquals("Rows in matrix constructed from vector", size, m.rowSize());
+ assertEquals("Cols in matrix constructed from vector", size, m.columnSize());
+
+ for (int i = 0; i < size; i++)
+ assertEquals(UNEXPECTED_VALUE + " at vector index " + i, data[i], m.get(i, i), 0d);
+
+ verifyDiagonal(m);
+
+ final Matrix m1 = new DiagonalMatrix(data);
+
+ assertEquals("Rows in matrix constructed from array", size, m1.rowSize());
+ assertEquals("Cols in matrix constructed from array", size, m1.columnSize());
+
+ for (int i = 0; i < size; i++)
+ assertEquals(UNEXPECTED_VALUE + " at array index " + i, data[i], m1.get(i, i), 0d);
+
+ verifyDiagonal(m1);
+ }
+
+ /** */
+ @Test
+ public void testConstant() {
+ final int size = MathTestConstants.STORAGE_SIZE;
+
+ for (double val : new double[] {-1.0, 0.0, 1.0}) {
+ Matrix m = new DiagonalMatrix(size, val);
+
+ assertEquals("Rows in matrix", size, m.rowSize());
+ assertEquals("Cols in matrix", size, m.columnSize());
+
+ for (int i = 0; i < size; i++)
+ assertEquals(UNEXPECTED_VALUE + " at index " + i, val, m.get(i, i), 0d);
+
+ verifyDiagonal(m, true);
+ }
+ }
+
+ /** */
+ @Test
+ public void testAttributes() {
+ assertTrue(UNEXPECTED_VALUE, testMatrix.rowSize() == MathTestConstants.STORAGE_SIZE);
+ assertTrue(UNEXPECTED_VALUE, testMatrix.columnSize() == MathTestConstants.STORAGE_SIZE);
+
+ assertFalse(UNEXPECTED_VALUE, testMatrix.isArrayBased());
+ assertTrue(UNEXPECTED_VALUE, testMatrix.isDense());
+ assertFalse(UNEXPECTED_VALUE, testMatrix.isDistributed());
+
+ assertEquals(UNEXPECTED_VALUE, testMatrix.isRandomAccess(), !testMatrix.isSequentialAccess());
+ assertTrue(UNEXPECTED_VALUE, testMatrix.isRandomAccess());
+ }
+
+ /** */
+ @Test
+ public void testNullParams() {
+ DenseLocalOnHeapMatrixConstructorTest.verifyAssertionError(() -> new DiagonalMatrix((Matrix)null), "Null Matrix parameter");
+
+ DenseLocalOnHeapMatrixConstructorTest.verifyAssertionError(() -> new DiagonalMatrix((Vector)null), "Null Vector parameter");
+
+ DenseLocalOnHeapMatrixConstructorTest.verifyAssertionError(() -> new DiagonalMatrix((double[])null), "Null double[] parameter");
+ }
+
+ /** */
+ private void verifyDiagonal(Matrix m, boolean readonly) {
+ final int rows = m.rowSize(), cols = m.columnSize();
+
+ final String sizeDetails = "rows" + "X" + "cols " + rows + "X" + cols;
+
+ for (int i = 0; i < rows; i++)
+ for (int j = 0; j < cols; j++) {
+ final String details = " at (" + i + "," + j + "), " + sizeDetails;
+
+ final boolean diagonal = i == j;
+
+ final double old = m.get(i, j);
+
+ if (!diagonal)
+ assertEquals(UNEXPECTED_VALUE + details, 0, old, 0d);
+
+ final double exp = diagonal && !readonly ? old + 1 : old;
+
+ boolean expECaught = false;
+
+ try {
+ m.set(i, j, exp);
+ }
+ catch (UnsupportedOperationException uoe) {
+ if (diagonal && !readonly)
+ throw uoe;
+
+ expECaught = true;
+ }
+
+ if ((!diagonal || readonly) && !expECaught)
+ fail("Expected exception was not caught " + details);
+
+ assertEquals(UNEXPECTED_VALUE + details, exp, m.get(i, j), 0d);
+ }
+ }
+
+ /** */
+ private void verifyDiagonal(Matrix m) {
+ verifyDiagonal(m, false);
+ }
+
+ /** */
+ private void fillMatrix(Matrix m) {
+ final int rows = m.rowSize(), cols = m.columnSize();
+
+ boolean negative = false;
+
+ for (int i = 0; i < rows; i++)
+ for (int j = 0; j < cols; j++)
+ m.set(i, j, (negative = !negative) ? -(i * cols + j + 1) : i * cols + j + 1);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/732dfea9/modules/ml/src/test/java/org/apache/ignite/math/impls/matrix/FunctionMatrixConstructorTest.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/test/java/org/apache/ignite/math/impls/matrix/FunctionMatrixConstructorTest.java b/modules/ml/src/test/java/org/apache/ignite/math/impls/matrix/FunctionMatrixConstructorTest.java
new file mode 100644
index 0000000..a5ac84a
--- /dev/null
+++ b/modules/ml/src/test/java/org/apache/ignite/math/impls/matrix/FunctionMatrixConstructorTest.java
@@ -0,0 +1,113 @@
+/*
+ * 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.ignite.math.impls.matrix;
+
+import org.apache.ignite.math.Matrix;
+import org.apache.ignite.math.exceptions.UnsupportedOperationException;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/** */
+public class FunctionMatrixConstructorTest {
+ /** */
+ @Test
+ public void invalidArgsTest() {
+ DenseLocalOnHeapMatrixConstructorTest.verifyAssertionError(() -> new FunctionMatrix(0, 1, (i, j) -> 0.0),
+ "Invalid row parameter.");
+
+ DenseLocalOnHeapMatrixConstructorTest.verifyAssertionError(() -> new FunctionMatrix(1, 0, (i, j) -> 0.0),
+ "Invalid col parameter.");
+
+ DenseLocalOnHeapMatrixConstructorTest.verifyAssertionError(() -> new FunctionMatrix(1, 1, null),
+ "Invalid func parameter.");
+
+ DenseLocalOnHeapMatrixConstructorTest.verifyAssertionError(() -> new FunctionMatrix(0, 1, (i, j) -> 0.0, null),
+ "Invalid row parameter, with setter func.");
+
+ DenseLocalOnHeapMatrixConstructorTest.verifyAssertionError(() -> new FunctionMatrix(1, 0, (i, j) -> 0.0, null),
+ "Invalid col parameter, with setter func.");
+
+ DenseLocalOnHeapMatrixConstructorTest.verifyAssertionError(() -> new FunctionMatrix(1, 1, null, null),
+ "Invalid func parameter, with setter func.");
+ }
+
+ /** */
+ @Test
+ public void basicTest() {
+ for (int rows : new int[] {1, 2, 3})
+ for (int cols : new int[] {1, 2, 3})
+ basicTest(rows, cols);
+
+ Matrix m = new FunctionMatrix(1, 1, (i, j) -> 1d);
+ //noinspection EqualsWithItself
+ assertTrue("Matrix is expected to be equal to self.", m.equals(m));
+ //noinspection ObjectEqualsNull
+ assertFalse("Matrix is expected to be not equal to null.", m.equals(null));
+ }
+
+ /** */
+ private void basicTest(int rows, int cols) {
+ double[][] data = new double[rows][cols];
+
+ for (int row = 0; row < rows; row++)
+ for (int col = 0; col < cols; col++)
+ data[row][col] = row * cols + row;
+
+ Matrix mReadOnly = new FunctionMatrix(rows, cols, (i, j) -> data[i][j]);
+
+ assertEquals("Rows in matrix.", rows, mReadOnly.rowSize());
+ assertEquals("Cols in matrix.", cols, mReadOnly.columnSize());
+
+ for (int row = 0; row < rows; row++)
+ for (int col = 0; col < cols; col++) {
+ assertEquals("Unexpected value at " + row + "x" + col, data[row][col], mReadOnly.get(row, col), 0d);
+
+ boolean expECaught = false;
+
+ try {
+ mReadOnly.set(row, col, 0.0);
+ }
+ catch (UnsupportedOperationException uoe) {
+ expECaught = true;
+ }
+
+ assertTrue("Expected exception wasn't thrown at " + row + "x" + col, expECaught);
+ }
+
+ Matrix m = new FunctionMatrix(rows, cols, (i, j) -> data[i][j], (i, j, val) -> data[i][j] = val);
+
+ assertEquals("Rows in matrix, with setter function.", rows, m.rowSize());
+ assertEquals("Cols in matrix, with setter function.", cols, m.columnSize());
+
+ for (int row = 0; row < rows; row++)
+ for (int col = 0; col < cols; col++) {
+ assertEquals("Unexpected value at " + row + "x" + col, data[row][col], m.get(row, col), 0d);
+
+ m.set(row, col, -data[row][col]);
+ }
+
+ for (int row = 0; row < rows; row++)
+ for (int col = 0; col < cols; col++)
+ assertEquals("Unexpected value set at " + row + "x" + col, -(row * cols + row), m.get(row, col), 0d);
+
+ assertTrue("Incorrect copy for empty matrix.", m.copy().equals(m));
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/732dfea9/modules/ml/src/test/java/org/apache/ignite/math/impls/matrix/MatrixAttributeTest.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/test/java/org/apache/ignite/math/impls/matrix/MatrixAttributeTest.java b/modules/ml/src/test/java/org/apache/ignite/math/impls/matrix/MatrixAttributeTest.java
new file mode 100644
index 0000000..c9fb390
--- /dev/null
+++ b/modules/ml/src/test/java/org/apache/ignite/math/impls/matrix/MatrixAttributeTest.java
@@ -0,0 +1,156 @@
+/*
+ * 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.ignite.math.impls.matrix;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Function;
+import org.apache.ignite.math.Matrix;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Attribute tests for matrices.
+ *
+ * TODO: WIP
+ */
+public class MatrixAttributeTest {
+ /** */
+ private final List<MatrixAttributeTest.AttrCfg> attrCfgs = Arrays.asList(
+ new AttrCfg("isDense", Matrix::isDense,
+ DenseLocalOnHeapMatrix.class, DenseLocalOffHeapMatrix.class, RandomMatrix.class, DiagonalMatrix.class),
+ new AttrCfg("isArrayBased", Matrix::isArrayBased, DenseLocalOnHeapMatrix.class),
+ new AttrCfg("isDistributed", Matrix::isDistributed),
+ new AttrCfg("isRandomAccess", Matrix::isRandomAccess, DenseLocalOnHeapMatrix.class, DenseLocalOffHeapMatrix.class, RandomMatrix.class, DiagonalMatrix.class, SparseLocalOnHeapMatrix.class),
+ new AttrCfg("isSequentialAccess", Matrix::isSequentialAccess, DiagonalMatrix.class)
+ );
+
+ /** */
+ private final List<MatrixAttributeTest.Specification> specFixture = Arrays.asList(
+ new Specification(new DenseLocalOnHeapMatrix(1, 1)),
+ new Specification(new DenseLocalOffHeapMatrix(1, 1)),
+ new Specification(new RandomMatrix(1, 1)),
+ new Specification(new DiagonalMatrix(new double[] {1.0})),
+ new Specification(new FunctionMatrix(1, 1, (x, y) -> 1.0)),
+ new Specification(new SparseLocalOnHeapMatrix(1, 1))
+ );
+
+ /** */
+ @Test
+ public void isDenseTest() {
+ assertAttribute("isDense");
+ }
+
+ /** */
+ @Test
+ public void isArrayBasedTest() {
+ assertAttribute("isArrayBased");
+ }
+
+ /** */
+ @Test
+ public void isSequentialAccessTest() {
+ assertAttribute("isSequentialAccess");
+ }
+
+ /** */
+ @Test
+ public void isRandomAccessTest() {
+ assertAttribute("isRandomAccess");
+ }
+
+ /** */
+ @Test
+ public void isDistributedTest() {
+ assertAttribute("isDistributed");
+ }
+
+ /** */
+ private void assertAttribute(String name) {
+ final MatrixAttributeTest.AttrCfg attr = attrCfg(name);
+
+ for (MatrixAttributeTest.Specification spec : specFixture)
+ spec.verify(attr);
+ }
+
+ /** */
+ private MatrixAttributeTest.AttrCfg attrCfg(String name) {
+ for (MatrixAttributeTest.AttrCfg attr : attrCfgs)
+ if (attr.name.equals(name))
+ return attr;
+
+ throw new IllegalArgumentException("Undefined attribute " + name);
+ }
+
+ /** See http://en.wikipedia.org/wiki/Specification_pattern */
+ private static class Specification {
+ /** */
+ private final Matrix m;
+ /** */
+ private final Class<? extends Matrix> underlyingType;
+ /** */
+ private final List<String> attrsFromUnderlying;
+ /** */
+ final String desc;
+
+ /** */
+ Specification(Matrix m, Class<? extends Matrix> underlyingType, String... attrsFromUnderlying) {
+ this.m = m;
+ this.underlyingType = underlyingType;
+ this.attrsFromUnderlying = Arrays.asList(attrsFromUnderlying);
+ final Class<? extends Matrix> clazz = m.getClass();
+ desc = clazz.getSimpleName() + (clazz.equals(underlyingType)
+ ? "" : " (underlying type " + underlyingType.getSimpleName() + ")");
+ }
+
+ /** */
+ Specification(Matrix m) {
+ this(m, m.getClass());
+ }
+
+ /** */
+ void verify(MatrixAttributeTest.AttrCfg attr) {
+ final boolean obtained = attr.obtain.apply(m);
+
+ final Class<? extends Matrix> typeToCheck
+ = attrsFromUnderlying.contains(attr.name) ? underlyingType : m.getClass();
+
+ final boolean exp = attr.trueInTypes.contains(typeToCheck);
+
+ assertEquals("Unexpected " + attr.name + " value for " + desc, exp, obtained);
+ }
+ }
+
+ /** */
+ private static class AttrCfg {
+ /** */
+ final String name;
+ /** */
+ final Function<Matrix, Boolean> obtain;
+ /** */
+ final List<Class> trueInTypes;
+
+ /** */
+ AttrCfg(String name, Function<Matrix, Boolean> obtain, Class... trueInTypes) {
+ this.name = name;
+ this.obtain = obtain;
+ this.trueInTypes = Arrays.asList(trueInTypes);
+ }
+ }
+}