/* * Copyright 2011-2013, by Vladimir Kostyukov and Contributors. * * This file is part of la4j project (http://la4j.org) * * Licensed 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. * * Contributor(s): Daniel Renshaw * Jakob Moellers * Yuriy Drozd * Maxim Samoylov * */ package org.la4j.vector; import org.junit.Assert; import org.junit.Test; import org.la4j.V; import org.la4j.Vector; import org.la4j.Vectors; import org.la4j.Matrix; import org.la4j.vector.functor.VectorAccumulator; import org.la4j.vector.functor.VectorPredicate; import static org.la4j.V.*; import static org.la4j.M.*; import java.util.Arrays; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; public abstract class VectorTest<T extends Vector> { protected VectorFactory<T> factory; public VectorTest(VectorFactory<T> factory) { this.factory = factory; } public T v(double... values) { return V.v(values).to(factory); } public T vz(int length) { return V.vz(length).to(factory); } @Test public void testAccess_10() { Vector a = v(0.0, 0.0, 2.0, 0.0, 3.0, 0.0, 0.0, 0.0, 0.1, 2.0); Assert.assertEquals(10, a.length()); Assert.assertEquals(0.0, a.get(0), Vectors.EPS); Assert.assertEquals(2.0, a.get(2), Vectors.EPS); Assert.assertEquals(2.0, a.get(9), Vectors.EPS); a.set(3, 42.0); a.set(8, 14.0); a.set(0, 3.3); Assert.assertEquals(42.0, a.get(3), Vectors.EPS); Assert.assertEquals(14.0, a.get(8), Vectors.EPS); Assert.assertEquals(3.3, a.get(0), Vectors.EPS); } @Test public void testSetAll_5() { Vector a = v(0.0, 0.0, 0.0, 0.0, 1.0, 4.0); a.setAll(11.1); for (double d: a) { Assert.assertEquals(11.1, d, Vectors.EPS); } } @Test public void testCopyOfLength_3_to_5_to_2() { Vector a = v(0.0, 0.0, 1.0); Vector b = v(0.0, 0.0, 1.0, 0.0, 0.0); Vector c = v(0.0, 0.0); a = a.copyOfLength(5); Assert.assertEquals(b, a); a = a.copyOfLength(2); Assert.assertEquals(c, a); } @Test public void testCopyOf_5_to_0_to_4() { Vector a = v(0.0, 1.0, 2.0, 3.0, 0.0); Vector b = v(); Vector c = v(0.0, 0.0, 0.0, 0.0); a = a.copyOfLength(0); Assert.assertEquals(b, a); a = a.copyOfLength(4); Assert.assertEquals(c, a); } @Test public void testSlice_5_to_2_and_3() { Vector a = v(1.0, 2.0, 3.0, 4.0, 5.0); Vector b = v(2.0, 3.0); Vector c = v(3.0, 4.0, 5.0); Assert.assertEquals(b, a.slice(1, 3)); Assert.assertEquals(c, a.slice(2, 5)); } @Test public void testSliceLeftRight_5_to_1_and_4() { Vector a = v(0.0, 2.0, 0.0, 4.0, 0.0); Vector b = v(0.0); Vector c = v(2.0, 0.0, 4.0, 0.0); Assert.assertEquals(b, a.sliceLeft(1)); Assert.assertEquals(c, a.sliceRight(1)); } @Test public void testSelect_4() { Vector a = v(0.0, 3.0, 7.0, 0.0); Vector b = v(3.0, 0.0, 0.0, 7.0); Vector c = v(7.0, 7.0, 0.0, 0.0); Assert.assertEquals(b, a.select(new int[]{1, 0, 3, 2})); Assert.assertEquals(c, a.select(new int[]{2, 2, 0, 3})); } @Test public void testSelect_5() { Vector a = v(1.0, 6.0, 0.0, 0.0, 8.0); Vector b = v(1.0, 1.0, 1.0); Vector c = v(0.0, 0.0, 8.0, 8.0, 1.0, 0.0); Assert.assertEquals(b, a.select(new int[]{0, 0, 0})); Assert.assertEquals(c, a.select(new int[]{2, 3, 4, 4, 0, 3})); } @Test public void testSelect_3() { Vector a = v(1.0, 0.0, 0.0); Vector b = v(0.0, 0.0, 0.0, 0.0); Vector c = v(1.0); Assert.assertEquals(b, a.select(new int[]{1, 2, 2, 1})); Assert.assertEquals(c, a.select(new int[]{0})); } @Test public void testSwapElements_5() { Vector a = v(1.0, 0.0, 0.0, 0.0, 3.0); Vector b = v(3.0, 0.0, 0.0, 0.0, 1.0); a.swapElements(0, 4); Assert.assertEquals(b, a); } @Test public void testSwapElements_4() { Vector a = v(0.0, 1.0, 0.0, 0.0); Vector b = v(0.0, 0.0, 1.0, 0.0); a.swapElements(1, 2); Assert.assertEquals(b, a); } @Test public void testSwapElements_4_2() { Vector a = v(0.0, 1.0, 0.0, 2.0); Vector b = v(0.0, 0.0, 1.0, 2.0); a.swapElements(1, 2); Assert.assertEquals(a, b); } @Test public void testSwapElements_6() { Vector a = v(0.0, 0.0, 0.0, 0.0, 0.0, -5.0); Vector b = v(0.0, 0.0, 0.0, -5.0, 0.0, 0.0); a.swapElements(3, 5); Assert.assertEquals(a, b); } @Test public void testSwapElements_2() { Vector a = v(1.0, 2.0); Vector b = v(2.0, 1.0); a.swapElements(0, 1); Assert.assertEquals(b, a); } @Test public void testEuclideanNorm_3() { Vector a = v(1.0, 2.0, 3.0); Assert.assertEquals(3.74165, a.fold(Vectors.mkEuclideanNormAccumulator()), 1e-5); Assert.assertEquals(3.74165, a.euclideanNorm(), 1e-5); } @Test public void testEuclideanNorm_5() { Vector a = v(1.0, 0.0, 3.0, 0.0, -5.0); Assert.assertEquals(5.91607, a.fold(Vectors.mkEuclideanNormAccumulator()), 1e-5); Assert.assertEquals(5.91607, a.euclideanNorm(), 1e-5); } @Test public void testManhattanNorm_3() { Vector a = v(1.0, 2.0, 3.0); Assert.assertEquals(6.0, a.fold(Vectors.mkManhattanNormAccumulator()), 1e-5); Assert.assertEquals(6.0, a.manhattanNorm(), 1e-5); } @Test public void testManhattanNorm_5() { Vector a = v(1.0, 0.0, 3.0, 0.0, -5.0); Assert.assertEquals(9.0, a.fold(Vectors.mkManhattanNormAccumulator()), 1e-5); Assert.assertEquals(9.0, a.manhattanNorm(), 1e-5); } @Test public void testInfinityNorm_3() { Vector a = v(1.0, 2.0, 3.0); Assert.assertEquals(3.0, a.fold(Vectors.mkInfinityNormAccumulator()), 1e-5); Assert.assertEquals(3.0, a.infinityNorm(), 1e-5); } @Test public void testInfinityNorm_5() { Vector a = v(1.0, 0.0, 3.0, 0.0, -5.0); Assert.assertEquals(5.0, a.fold(Vectors.mkInfinityNormAccumulator()), 1e-5); Assert.assertEquals(5.0, a.infinityNorm(), 1e-5); } @Test public void testAdd_3() { for (Vector b: vs(0.0, 5.0, 0.0)) { Vector a = v(0.0, 0.0, 3.0); Vector c = v(7.0, 7.0, 10.0); Vector d = v(0.0, 5.0, 3.0); Assert.assertEquals(c, a.add(7.0)); Assert.assertEquals(d, a.add(b)); Assert.assertEquals(d, b.add(a)); } } @Test public void testAdd_4() { for (Vector b: vs(0.0, 1.0, 0.0, 6.0)) { Vector a = v(1.0, 0.0, 0.0, 3.0); Vector c = v(1.0, 1.0, 0.0, 9.0); Assert.assertEquals(c, a.add(b)); Assert.assertEquals(c, b.add(a)); } } @Test public void testSubtract_3() { for (Vector b: vs(4.0, 0.0, 0.0)) { Vector a = v(0.0, 0.0, 3.0); Vector c = v(-7.0, -7.0, -4.0); Vector d = v(-4.0, 0.0, 3.0); Assert.assertEquals(c, a.subtract(7.0)); Assert.assertEquals(d, a.subtract(b)); } } @Test public void testMultiply_3() { for (Vector b: vs(0.0, 5.0, 0.0)) { Vector a = v(0.0, 0.0, 1.0); Vector c = v(0.0, 0.0, 10.0); Vector d = v(0.0, 0.0, 0.0); Assert.assertEquals(c, a.multiply(10.0)); Assert.assertEquals(d, a.hadamardProduct(b)); } } @Test public void testHadamardProduct_3() { for (Vector b: vs(3.0, 0.0, 0.0)) { Vector a = v(1.0, 0.0, 2.0); Vector c = v(3.0, 0.0, 0.0); Assert.assertEquals(c, a.hadamardProduct(b)); } } @Test public void testMultiply_2_2x4() { for (Matrix b: ms(a(0.0, 5.0, 0.0, 6.0), a(1.0, 0.0, 8.0, 0.0))) { Vector a = v(1.0, 2.0); Vector c = v(2.0, 5.0, 16.0, 6.0); Assert.assertEquals(c, a.multiply(b)); } } @Test public void testMultiply_3_3x1() { for (Matrix b: ms(a(0.0), a(3.0), a(0.0))) { Vector a = v(0.0, 2.0, 0.0); Vector c = v(6.0); Assert.assertEquals(c, a.multiply(b)); } } @Test public void testProduct_3() { Vector a = v(2.0, 4.0, 6.0); Assert.assertEquals(a.product(), 48.0, Vectors.EPS); } @Test public void testSum_3() { Vector a = v(2.0, 4.0, 6.0); Assert.assertEquals(a.sum(), 12.0, Vectors.EPS); } @Test public void testDivide_3() { Vector a = v(0.0, 0.0, 3.0); Vector b = v(0.0, 0.0, 0.3); Assert.assertEquals(b, a.divide(10)); } @Test public void testCopy_5() { Vector a = v(0.0, 0.0, 0.0, 0.0, 1.0); Assert.assertEquals(a, a.copy()); } @Test public void testBlank_5() { Vector a = v(0.0, 0.0, 0.0, 0.0, 1.0); Vector b = v(0.0, 0.0, 0.0, 0.0, 0.0); Assert.assertEquals(b, a.blank()); } @Test public void testInnerProduct_1() { for (Vector b: vs(10.0)) { Vector a = v(18.0); Assert.assertEquals(180.0, a.innerProduct(b), Vectors.EPS); } } @Test public void testInnerProduct_3() { for (Vector b: vs(10.0, 0.0, 10.0)) { Vector a = v(1.0, 2.0, 3.0); Assert.assertEquals(40.0, a.innerProduct(b), Vectors.EPS); } } @Test public void testInnerProduct_4() { for (Vector b: vs(11.0, 13.0, 17.0, 19.0)) { Vector a = v(2.0, 3.0, 5.0, 7.0); Assert.assertEquals(279.0, a.innerProduct(b), Vectors.EPS); } } @Test public void testOuterProduct_3_4() { for (Vector b: vs(7.0, 11.0, 13.0, 17.0)) { Vector a = v(2.0, 3.0, 5.0); Matrix c = m(a(14.0, 22.0, 26.0, 34.0), a(21.0, 33.0, 39.0, 51.0), a(35.0, 55.0, 65.0, 85.0)); Assert.assertEquals(c, a.outerProduct(b)); } } @Test public void testOuterProduct_1_2() { for (Vector b: vs(24.0, 1.0)) { Vector a = v(2.0); Matrix c = m(a(48.0, 2.0)); Assert.assertEquals(c, a.outerProduct(b)); } } @Test public void testOuterProduct_4_2() { for (Vector b: vs(4.0, -10.0)) { Vector a = v(2.0, 0.0, -1.0, 41.0); Matrix c = m(a(8.0, -20.0), a(0.0, 0.0), a(-4.0, 10.0), a(164.0, -410.0)); Assert.assertEquals(c, a.outerProduct(b)); } } /** * Tests whether two vectors contain the same elements * * @param vector1 Vector1 * @param vector2 Vector2 * @return True if both vectors contain the same elements */ public boolean testWhetherVectorsContainSameElements(Vector vector1, Vector vector2) { if (vector1.length() == vector2.length()) { boolean[] checkList = new boolean[vector1.length()]; for (int i = 0; i < vector1.length(); i++) { for (int j = 0; j < vector2.length(); j++) { if (vector1.get(i) == vector2.get(j)) { if (!checkList[j]) { checkList[j] = true; break; } } } } boolean result = true; for (int i = 0; i < checkList.length; i++) { if (!checkList[i]) { result = false; } } return result; } else { return false; } } @Test public void testTestWhetherVectorsContainSameElements() { Vector a = v(1.0, 1.0, 3.0, 4.0); Vector b = v(4.0, 1.0, 1.0, 3.0); Vector c = v(4.0, 2.0, 1.0, 3.0); Assert.assertTrue(testWhetherVectorsContainSameElements(a, b)); Assert.assertFalse(testWhetherVectorsContainSameElements(a, c)); } @Test public void testShuffle() { Vector a = v(1.0, 1.0, 3.0, 4.0); Vector b = a.shuffle(); Assert.assertTrue(testWhetherVectorsContainSameElements(a, b)); } @Test public void testMax() { Vector a = v(1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -5.0, 0.0, 0.0, 5.0); Assert.assertEquals(5.0, a.max(), Vectors.EPS); } @Test public void testMaxCompressed() { Vector a = v(0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -5.0, 0.0, 0.0); Assert.assertEquals(0.0, a.max(), Vectors.EPS); } @Test public void testMin() { Vector a = v(1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -5.0, 0.0, 0.0, 5.0); Assert.assertEquals(-5.0, a.min(), Vectors.EPS); } @Test public void testMinCompressed() { Vector a = v(1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 5.0); Assert.assertEquals(0.0, a.min(), Vectors.EPS); } @Test public void testFold_6() { Vector a = v(0.0, 0.0, 5.0, 0.0, 2.0, 1.0); VectorAccumulator sum = Vectors.asSumAccumulator(0.0); VectorAccumulator product = Vectors.asProductAccumulator(1.0); Assert.assertEquals(8.0, a.fold(sum), Vectors.EPS); // check whether the accumulator were flushed Assert.assertEquals(8.0, a.fold(sum), Vectors.EPS); Assert.assertEquals(0.0, a.fold(product), Vectors.EPS); // check whether the accumulator were flushed Assert.assertEquals(0.0, a.fold(product), Vectors.EPS); } @Test public void testIssue162_0() { VectorPredicate pi = new VectorPredicate() { @Override public boolean test(int i, double value) { return value == 3.14; } }; Vector a = v(); Vector b = a.copyOfLength(31); Assert.assertEquals(0, a.length()); Assert.assertEquals(31, b.length()); b.setAll(3.14); Assert.assertTrue(b.is(pi)); Vector c = b.copyOfLength(42); c.setAll(3.14); Assert.assertTrue(c.is(pi)); Vector d = c.copyOfLength(54); d.setAll(3.14); Assert.assertTrue(d.is(pi)); } @Test public void testResize_32_to_110_to_1076_to_31() { VectorPredicate fortyTwo = new VectorPredicate() { @Override public boolean test(int i, double value) { return value == 42.0; } }; Vector a = v(); Vector b = a.copyOfLength(32); Assert.assertEquals(32, b.length()); b.setAll(42.0); Assert.assertTrue(b.is(fortyTwo)); Vector c = b.copyOfLength(110); c.setAll(42.0); Assert.assertTrue(c.is(fortyTwo)); Vector d = c.copyOfLength(1076); d.setAll(42.0); Assert.assertTrue(d.is(fortyTwo)); Vector e = d.copyOfLength(31); e.setAll(42.0); Assert.assertTrue(e.is(fortyTwo)); } @Test public void testNormalize_Default() { Vector a = v(3.0, 0.0, -4.0); Vector b = a.divide(a.norm()); Assert.assertEquals(3, b.length()); Assert.assertEquals(0.6, b.get(0), Vectors.EPS); Assert.assertEquals(0.0, b.get(1), Vectors.EPS); Assert.assertEquals(-0.8, b.get(2), Vectors.EPS); // Verify b is a unit vector // The default normalize() uses Euclidean as the accumulator Assert.assertEquals(1.0, b.norm(), Vectors.EPS); } @Test public void testNormalize_EuclideanNormAccumulator() { Vector a = v(3.0, 0.0, -4.0); Vector b = a.divide(a.euclideanNorm()); Assert.assertEquals(3, b.length()); Assert.assertEquals(0.6, b.get(0), Vectors.EPS); Assert.assertEquals(0.0, b.get(1), Vectors.EPS); Assert.assertEquals(-0.8, b.get(2), Vectors.EPS); // Verify b is a unit vector Assert.assertEquals(1.0, b.euclideanNorm(), Vectors.EPS); } @Test public void testNormalize_ManhattanNormAccumulator() { Vector a = v(3.0, 0.0, -4.0); Vector b = a.divide(a.manhattanNorm()); Assert.assertEquals(3, b.length()); Assert.assertEquals(0.42857, b.get(0), 0.00001); Assert.assertEquals(0.0, b.get(1), Vectors.EPS); Assert.assertEquals(-0.57142, b.get(2), 0.00001); // Verify b is a unit vector Assert.assertEquals(1.0, b.manhattanNorm(), Vectors.EPS); } @Test public void testNormalize_InfinityNormAccumulator() { Vector a = v(3.0, 0.0, -4.0); Vector b = a.divide(a.infinityNorm()); Assert.assertEquals(3, b.length()); Assert.assertEquals(0.75, b.get(0), Vectors.EPS); Assert.assertEquals(0.0, b.get(1), Vectors.EPS); Assert.assertEquals(-1.0, b.get(2), Vectors.EPS); // Verify b is a unit vector Assert.assertEquals(1.0, b.infinityNorm(), Vectors.EPS); } @Test public void testEqualsWithPrecision() throws Exception { Vector a = v(1000.0, 1.0); Assert.assertTrue(a.equals(a, Vectors.EPS)); Vector b = v().copyOfLength(1000); b.setAll(42.0); Assert.assertFalse(a.equals(b, Vectors.EPS)); Assert.assertFalse(b.equals(a, Vectors.EPS)); Vector e = v(); Assert.assertTrue(e.equals(e, Vectors.EPS)); Vector f = v(Double.MIN_VALUE, Double.MIN_VALUE); Vector g = vz(2); Assert.assertTrue(f.equals(g, Vectors.EPS)); Assert.assertTrue(g.equals(f, Vectors.EPS)); Vector i = v(Double.MIN_NORMAL, Double.MIN_NORMAL); Assert.assertTrue(i.equals(g, Vectors.EPS)); Assert.assertTrue(i.equals(f, Vectors.EPS)); Assert.assertTrue(g.equals(i, Vectors.EPS)); Assert.assertTrue(f.equals(i, Vectors.EPS)); } @Test public void testEquals() throws Exception { Vector a = v().copyOfLength(1000); a.setAll(1.0); Assert.assertTrue(a.equals(a)); Assert.assertTrue(a.copy().equals(a)); Vector d = v().copyOfLength(1000); Assert.assertFalse(d.equals(a)); Assert.assertTrue(d.equals(d.copy())); Vector e = v(); Assert.assertTrue(e.equals(e.copy())); Vector f = v(Double.MIN_VALUE); Vector g = v(0.0); Assert.assertTrue(f.equals(g)); Assert.assertTrue(g.equals(f)); Vector i = v(Double.MIN_NORMAL); Assert.assertTrue(i.equals(g)); Assert.assertTrue(i.equals(f)); Assert.assertTrue(g.equals(i)); Assert.assertTrue(f.equals(i)); } @Test public void testFromCollection_empty() { List<Number> values = new LinkedList<>(); Assert.assertEquals(Vector.fromCollection(values), Vector.zero(0)); } @Test public void testFromCollection_normal_x3() { List<Double> values = Arrays.asList(1.0, 2.0, 3.0); Vector v = Vector.fromCollection(values); Assert.assertEquals(v, Vector.fromArray(new double[] {1.0, 2.0, 3.0})); } @Test public void testFromCollection_byte() { List<Byte> values = Arrays.asList((byte) 1, (byte) 3, (byte) 5, (byte) 6); Vector v = Vector.fromCollection(values); Assert.assertEquals(v, Vector.fromArray(new double[] {1.0, 3.0, 5.0, 6.0})); } @Test(expected = NullPointerException.class) public void testFromCollection_NPE() { Vector v = Vector.fromCollection(null); } @Test public void testFromMap_empty() { Map<Integer, Double> map = new HashMap<>(); Assert.assertEquals(Vector.fromMap(map, 0), Vector.zero(0)); } @Test public void testFromMap_normal() { Map<Integer, Double> map = new HashMap<>(); map.put(0, 1.0); map.put(3, 2.0); map.put(5, 1.0); Vector v = Vector.fromArray(new double[]{1, 0, 0, 2, 0, 1, 0}); Assert.assertEquals(v, Vector.fromMap(map, 7)); } @Test public void testFromMap_emptyMap() { Map<Integer, Double> map = new HashMap<>(); Assert.assertEquals(Vector.fromMap(map, 5), Vector.zero(5)); } @Test(expected = IllegalArgumentException.class) public void testFromMap_invalidMap() { Map<Integer, Double> map = new HashMap<>(); map.put(0, 1.0); map.put(3, 2.0); map.put(-2, 1.0); Vector v = Vector.fromMap(map, 5); } @Test(expected = NullPointerException.class) public void testFromMap_NPE() { Vector v = Vector.fromMap(null, 4); } @Test public void testCosineSimilarity() { Vector a = v(5, 1, 0, 0, 0, 1, 10, 15); Vector b = v(1, 8, 0, 9, 6, 4, 2, 5); Vector c = v(9, 0, 2, 1, 1, 0, 8, 12); Vector d = v(900, 0, 200, 100, 100, 0, 800, 1200); // a & c are more similar to each other than b Assert.assertTrue(a.cosineSimilarity(b) < a.cosineSimilarity(c)); Assert.assertTrue(c.cosineSimilarity(b) < c.cosineSimilarity(a)); Assert.assertEquals(1.0, c.cosineSimilarity(d), 0.00005); Assert.assertEquals(1.0, d.cosineSimilarity(c), 0.00005); } }