/* * 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.mahout.math; import org.apache.mahout.math.function.Functions; import org.junit.Test; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; public final class VectorTest extends MahoutTestCase { @Test public void testSparseVector() { Vector vec1 = new RandomAccessSparseVector(3); Vector vec2 = new RandomAccessSparseVector(3); doTestVectors(vec1, vec2); } @Test public void testSparseVectorFullIteration() { int[] index = {0, 1, 2, 3, 4, 5}; double[] values = {1, 2, 3, 4, 5, 6}; assertEquals(index.length, values.length); int n = index.length; Vector vector = new SequentialAccessSparseVector(n); for (int i = 0; i < n; i++) { vector.set(index[i], values[i]); } for (int i = 0; i < n; i++) { assertEquals(vector.get(i), values[i], EPSILON); } int elements = 0; for (Vector.Element e : vector) { elements++; } assertEquals(n, elements); assertFalse(new SequentialAccessSparseVector(0).iterator().hasNext()); } @Test public void testSparseVectorSparseIteration() { int[] index = {0, 1, 2, 3, 4, 5}; double[] values = {1, 2, 3, 4, 5, 6}; assertEquals(index.length, values.length); int n = index.length; Vector vector = new SequentialAccessSparseVector(n); for (int i = 0; i < n; i++) { vector.set(index[i], values[i]); } for (int i = 0; i < n; i++) { assertEquals(vector.get(i), values[i], EPSILON); } int elements = 0; Iterator<Vector.Element> it = vector.iterateNonZero(); while (it.hasNext()) { it.next(); elements++; } assertEquals(n, elements); Vector empty = new SequentialAccessSparseVector(0); assertFalse(empty.iterateNonZero().hasNext()); } @Test public void testEquivalent() { //names are not used for equivalent RandomAccessSparseVector randomAccessLeft = new RandomAccessSparseVector(3); Vector sequentialAccessLeft = new SequentialAccessSparseVector(3); Vector right = new DenseVector(3); randomAccessLeft.setQuick(0, 1); randomAccessLeft.setQuick(1, 2); randomAccessLeft.setQuick(2, 3); sequentialAccessLeft.setQuick(0,1); sequentialAccessLeft.setQuick(1,2); sequentialAccessLeft.setQuick(2,3); right.setQuick(0, 1); right.setQuick(1, 2); right.setQuick(2, 3); assertEquals(randomAccessLeft, right); assertEquals(sequentialAccessLeft, right); assertEquals(sequentialAccessLeft, randomAccessLeft); Vector leftBar = new DenseVector(3); leftBar.setQuick(0, 1); leftBar.setQuick(1, 2); leftBar.setQuick(2, 3); assertEquals(leftBar, right); assertEquals(randomAccessLeft, right); assertEquals(sequentialAccessLeft, right); Vector rightBar = new RandomAccessSparseVector(3); rightBar.setQuick(0, 1); rightBar.setQuick(1, 2); rightBar.setQuick(2, 3); assertEquals(randomAccessLeft, rightBar); right.setQuick(2, 4); assertFalse(randomAccessLeft.equals(right)); right = new DenseVector(4); right.setQuick(0, 1); right.setQuick(1, 2); right.setQuick(2, 3); right.setQuick(3, 3); assertFalse(randomAccessLeft.equals(right)); randomAccessLeft = new RandomAccessSparseVector(2); randomAccessLeft.setQuick(0, 1); randomAccessLeft.setQuick(1, 2); assertFalse(randomAccessLeft.equals(right)); Vector dense = new DenseVector(3); right = new DenseVector(3); right.setQuick(0, 1); right.setQuick(1, 2); right.setQuick(2, 3); dense.setQuick(0, 1); dense.setQuick(1, 2); dense.setQuick(2, 3); assertEquals(dense, right); RandomAccessSparseVector sparse = new RandomAccessSparseVector(3); randomAccessLeft = new RandomAccessSparseVector(3); sparse.setQuick(0, 1); sparse.setQuick(1, 2); sparse.setQuick(2, 3); randomAccessLeft.setQuick(0, 1); randomAccessLeft.setQuick(1, 2); randomAccessLeft.setQuick(2, 3); assertEquals(randomAccessLeft, sparse); Vector v1 = new VectorView(randomAccessLeft, 0, 2); Vector v2 = new VectorView(right, 0, 2); assertEquals(v1, v2); sparse = new RandomAccessSparseVector(2); sparse.setQuick(0, 1); sparse.setQuick(1, 2); assertEquals(v1, sparse); } private static void doTestVectors(Vector left, Vector right) { left.setQuick(0, 1); left.setQuick(1, 2); left.setQuick(2, 3); right.setQuick(0, 4); right.setQuick(1, 5); right.setQuick(2, 6); double result = left.dot(right); assertEquals(32.0, result, EPSILON); } @Test public void testGetDistanceSquared() { Vector v = new DenseVector(5); Vector w = new DenseVector(5); setUpV(v); setUpW(w); doTestGetDistanceSquared(v, w); v = new RandomAccessSparseVector(5); w = new RandomAccessSparseVector(5); setUpV(v); setUpW(w); doTestGetDistanceSquared(v, w); v = new SequentialAccessSparseVector(5); w = new SequentialAccessSparseVector(5); setUpV(v); setUpW(w); doTestGetDistanceSquared(v, w); } @Test public void testAddTo() throws Exception { Vector v = new DenseVector(4); Vector w = new DenseVector(4); v.setQuick(0, 1); v.setQuick(1, 2); v.setQuick(2, 0); v.setQuick(3, 4); w.setQuick(0, 1); w.setQuick(1, 1); w.setQuick(2, 1); w.setQuick(3, 1); w.assign(v, Functions.PLUS); Vector gold = new DenseVector(new double[]{2, 3, 1, 5}); assertEquals(w, gold); assertFalse(v.equals(gold)); } private static void setUpV(Vector v) { v.setQuick(1, 2); v.setQuick(2, -4); v.setQuick(3, -9); } private static void setUpW(Vector w) { w.setQuick(0, -5); w.setQuick(1, -1); w.setQuick(2, 9); w.setQuick(3, 0.1); w.setQuick(4, 2.1); } private static void doTestGetDistanceSquared(Vector v, Vector w) { double expected = v.minus(w).getLengthSquared(); assertEquals(expected, v.getDistanceSquared(w), 1.0e-6); } @Test public void testGetLengthSquared() { Vector v = new DenseVector(5); setUpV(v); doTestGetLengthSquared(v); v = new RandomAccessSparseVector(5); setUpV(v); doTestGetLengthSquared(v); v = new SequentialAccessSparseVector(5); setUpV(v); doTestGetLengthSquared(v); } public static double lengthSquaredSlowly(Vector v) { double d = 0.0; for (int i = 0; i < v.size(); i++) { double value = v.get(i); d += value * value; } return d; } private static void doTestGetLengthSquared(Vector v) { double expected = lengthSquaredSlowly(v); assertEquals("v.getLengthSquared() != sum_of_squared_elements(v)", expected, v.getLengthSquared(), 0.0); v.set(v.size()/2, v.get(v.size()/2) + 1.0); expected = lengthSquaredSlowly(v); assertEquals("mutation via set() fails to change lengthSquared", expected, v.getLengthSquared(), EPSILON); v.setQuick(v.size()/5, v.get(v.size()/5) + 1.0); expected = lengthSquaredSlowly(v); assertEquals("mutation via setQuick() fails to change lengthSquared", expected, v.getLengthSquared(), EPSILON); Iterator<Vector.Element> it = v.iterator(); while (it.hasNext()) { Vector.Element e = it.next(); if (e.index() == v.size() - 2) { e.set(e.get() - 5.0); } } expected = lengthSquaredSlowly(v); assertEquals("mutation via dense iterator.set fails to change lengthSquared", expected, v.getLengthSquared(), EPSILON); it = v.iterateNonZero(); int i = 0; while (it.hasNext()) { i++; Vector.Element e = it.next(); if (i == v.getNumNondefaultElements() - 1) { e.set(e.get() - 5.0); } } expected = lengthSquaredSlowly(v); assertEquals("mutation via sparse iterator.set fails to change lengthSquared", expected, v.getLengthSquared(), EPSILON); v.assign(3.0); expected = lengthSquaredSlowly(v); assertEquals("mutation via assign(double) fails to change lengthSquared", expected, v.getLengthSquared(), EPSILON); v.assign(Functions.SQUARE); expected = lengthSquaredSlowly(v); assertEquals("mutation via assign(square) fails to change lengthSquared", expected, v.getLengthSquared(), EPSILON); v.assign(new double[v.size()]); expected = lengthSquaredSlowly(v); assertEquals("mutation via assign(double[]) fails to change lengthSquared", expected, v.getLengthSquared(), EPSILON); v.getElement(v.size()/2).set(2.5); expected = lengthSquaredSlowly(v); assertEquals("mutation via v.getElement().set() fails to change lengthSquared", expected, v.getLengthSquared(), EPSILON); v.normalize(); expected = lengthSquaredSlowly(v); assertEquals("mutation via normalize() fails to change lengthSquared", expected, v.getLengthSquared(), EPSILON); v.set(0, 1.5); v.normalize(1.0); expected = lengthSquaredSlowly(v); assertEquals("mutation via normalize(double) fails to change lengthSquared", expected, v.getLengthSquared(), EPSILON); v.times(2.0); expected = lengthSquaredSlowly(v); assertEquals("mutation via times(double) fails to change lengthSquared", expected, v.getLengthSquared(), EPSILON); v.times(v); expected = lengthSquaredSlowly(v); assertEquals("mutation via times(vector) fails to change lengthSquared", expected, v.getLengthSquared(), EPSILON); v.assign(Functions.POW, 3.0); expected = lengthSquaredSlowly(v); assertEquals("mutation via assign(pow, 3.0) fails to change lengthSquared", expected, v.getLengthSquared(), EPSILON); v.assign(v, Functions.PLUS); expected = lengthSquaredSlowly(v); assertEquals("mutation via assign(v,plus) fails to change lengthSquared", expected, v.getLengthSquared(), EPSILON); } @Test public void testIterator() { Collection<Integer> expectedIndices = new HashSet<Integer>(); int i = 1; while (i <= 20) { expectedIndices.add(i * (i + 1) / 2); i++; } Vector denseVector = new DenseVector(i * i); for (int index : expectedIndices) { denseVector.set(index, (double) 2 * index); } doTestIterators(denseVector, expectedIndices); Vector randomAccessVector = new RandomAccessSparseVector(i * i); for (int index : expectedIndices) { randomAccessVector.set(index, (double) 2 * index); } doTestIterators(randomAccessVector, expectedIndices); Vector sequentialVector = new SequentialAccessSparseVector(i * i); for (int index : expectedIndices) { sequentialVector.set(index, (double) 2 * index); } doTestIterators(sequentialVector, expectedIndices); } private static void doTestIterators(Vector vector, Collection<Integer> expectedIndices) { expectedIndices = new HashSet<Integer>(expectedIndices); Iterator<Vector.Element> allIterator = vector.iterator(); int index = 0; while (allIterator.hasNext()) { Vector.Element element = allIterator.next(); assertEquals(index, element.index()); if (expectedIndices.contains(index)) { assertEquals((double) index * 2, element.get(), EPSILON); } else { assertEquals(0.0, element.get(), EPSILON); } index++; } Iterator<Vector.Element> nonZeroIterator = vector.iterateNonZero(); while (nonZeroIterator.hasNext()) { Vector.Element element = nonZeroIterator.next(); index = element.index(); assertTrue(expectedIndices.contains(index)); assertEquals((double) index * 2, element.get(), EPSILON); expectedIndices.remove(index); } assertTrue(expectedIndices.isEmpty()); } @Test public void testNormalize() { Vector vec1 = new RandomAccessSparseVector(3); vec1.setQuick(0, 1); vec1.setQuick(1, 2); vec1.setQuick(2, 3); Vector norm = vec1.normalize(); assertNotNull("norm1 is null and it shouldn't be", norm); Vector vec2 = new SequentialAccessSparseVector(3); vec2.setQuick(0, 1); vec2.setQuick(1, 2); vec2.setQuick(2, 3); Vector norm2 = vec2.normalize(); assertNotNull("norm1 is null and it shouldn't be", norm2); Vector expected = new RandomAccessSparseVector(3); expected.setQuick(0, 0.2672612419124244); expected.setQuick(1, 0.5345224838248488); expected.setQuick(2, 0.8017837257372732); assertEquals(expected, norm); norm = vec1.normalize(2); assertEquals(expected, norm); norm2 = vec2.normalize(2); assertEquals(expected, norm2); norm = vec1.normalize(1); norm2 = vec2.normalize(1); expected.setQuick(0, 1.0 / 6); expected.setQuick(1, 2.0 / 6); expected.setQuick(2, 3.0 / 6); assertEquals(expected, norm); assertEquals(expected, norm2); norm = vec1.normalize(3); //expected = vec1.times(vec1).times(vec1); // double sum = expected.zSum(); // cube = Math.pow(sum, 1.0/3); double cube = Math.pow(36, 1.0 / 3); expected = vec1.divide(cube); assertEquals(norm, expected); norm = vec1.normalize(Double.POSITIVE_INFINITY); norm2 = vec2.normalize(Double.POSITIVE_INFINITY); // The max is 3, so we divide by that. expected.setQuick(0, 1.0 / 3); expected.setQuick(1, 2.0 / 3); expected.setQuick(2, 3.0 / 3); assertEquals(norm, expected); assertEquals(norm2, expected); norm = vec1.normalize(0); // The max is 3, so we divide by that. expected.setQuick(0, 1.0 / 3); expected.setQuick(1, 2.0 / 3); expected.setQuick(2, 3.0 / 3); assertEquals(norm, expected); try { vec1.normalize(-1); fail(); } catch (IllegalArgumentException e) { // expected } try { vec2.normalize(-1); fail(); } catch (IllegalArgumentException e) { // expected } } @Test public void testLogNormalize() { Vector vec1 = new RandomAccessSparseVector(3); vec1.setQuick(0, 1); vec1.setQuick(1, 2); vec1.setQuick(2, 3); Vector norm = vec1.logNormalize(); assertNotNull("norm1 is null and it shouldn't be", norm); Vector vec2 = new SequentialAccessSparseVector(3); vec2.setQuick(0, 1); vec2.setQuick(1, 2); vec2.setQuick(2, 3); Vector norm2 = vec2.logNormalize(); assertNotNull("norm1 is null and it shouldn't be", norm2); Vector expected = new DenseVector(new double[]{ 0.2672612419124244, 0.4235990463273581, 0.5345224838248488 }); assertVectorEquals(expected, norm, 1.0e-15); assertVectorEquals(expected, norm2, 1.0e-15); norm = vec1.logNormalize(2); assertVectorEquals(expected, norm, 1.0e-15); norm2 = vec2.logNormalize(2); assertVectorEquals(expected, norm2, 1.0e-15); try { vec1.logNormalize(1); fail("Should fail with power == 1"); } catch (IllegalArgumentException e) { // expected } try { vec1.logNormalize(-1); fail("Should fail with negative power"); } catch (IllegalArgumentException e) { // expected } try { vec2.logNormalize(Double.POSITIVE_INFINITY); fail("Should fail with positive infinity norm"); } catch (IllegalArgumentException e) { // expected } } private static void assertVectorEquals(Vector expected, Vector actual, double epsilon) { assertEquals(expected.size(), actual.size()); for (Vector.Element x : expected) { assertEquals(x.get(), actual.get(x.index()), epsilon); } } @Test public void testMax() { Vector vec1 = new RandomAccessSparseVector(3); vec1.setQuick(0, -1); vec1.setQuick(1, -3); vec1.setQuick(2, -2); double max = vec1.maxValue(); assertEquals(-1.0, max, 0.0); int idx = vec1.maxValueIndex(); assertEquals(0, idx); vec1 = new RandomAccessSparseVector(3); vec1.setQuick(0, -1); vec1.setQuick(2, -2); max = vec1.maxValue(); assertEquals(0.0, max, 0.0); idx = vec1.maxValueIndex(); assertEquals(1, idx); vec1 = new SequentialAccessSparseVector(3); vec1.setQuick(0, -1); vec1.setQuick(2, -2); max = vec1.maxValue(); assertEquals(0.0, max, 0.0); idx = vec1.maxValueIndex(); assertEquals(1, idx); vec1 = new DenseVector(3); vec1.setQuick(0, -1); vec1.setQuick(2, -2); max = vec1.maxValue(); assertEquals(0.0, max, 0.0); idx = vec1.maxValueIndex(); assertEquals(1, idx); vec1 = new RandomAccessSparseVector(3); max = vec1.maxValue(); assertEquals(0.0, max, EPSILON); vec1 = new DenseVector(3); max = vec1.maxValue(); assertEquals(0.0, max, EPSILON); vec1 = new SequentialAccessSparseVector(3); max = vec1.maxValue(); assertEquals(0.0, max, EPSILON); vec1 = new RandomAccessSparseVector(0); max = vec1.maxValue(); assertEquals(Double.NEGATIVE_INFINITY, max, EPSILON); vec1 = new DenseVector(0); max = vec1.maxValue(); assertEquals(Double.NEGATIVE_INFINITY, max, EPSILON); vec1 = new SequentialAccessSparseVector(0); max = vec1.maxValue(); assertEquals(Double.NEGATIVE_INFINITY, max, EPSILON); } @Test public void testMin() { Vector vec1 = new RandomAccessSparseVector(3); vec1.setQuick(0, 1); vec1.setQuick(1, 3); vec1.setQuick(2, 2); double max = vec1.minValue(); assertEquals(1.0, max, 0.0); int idx = vec1.maxValueIndex(); assertEquals(1, idx); vec1 = new RandomAccessSparseVector(3); vec1.setQuick(0, -1); vec1.setQuick(2, -2); max = vec1.maxValue(); assertEquals(0.0, max, 0.0); idx = vec1.maxValueIndex(); assertEquals(1, idx); vec1 = new SequentialAccessSparseVector(3); vec1.setQuick(0, -1); vec1.setQuick(2, -2); max = vec1.maxValue(); assertEquals(0.0, max, 0.0); idx = vec1.maxValueIndex(); assertEquals(1, idx); vec1 = new DenseVector(3); vec1.setQuick(0, -1); vec1.setQuick(2, -2); max = vec1.maxValue(); assertEquals(0.0, max, 0.0); idx = vec1.maxValueIndex(); assertEquals(1, idx); vec1 = new RandomAccessSparseVector(3); max = vec1.maxValue(); assertEquals(0.0, max, EPSILON); vec1 = new DenseVector(3); max = vec1.maxValue(); assertEquals(0.0, max, EPSILON); vec1 = new SequentialAccessSparseVector(3); max = vec1.maxValue(); assertEquals(0.0, max, EPSILON); vec1 = new RandomAccessSparseVector(0); max = vec1.maxValue(); assertEquals(Double.NEGATIVE_INFINITY, max, EPSILON); vec1 = new DenseVector(0); max = vec1.maxValue(); assertEquals(Double.NEGATIVE_INFINITY, max, EPSILON); vec1 = new SequentialAccessSparseVector(0); max = vec1.maxValue(); assertEquals(Double.NEGATIVE_INFINITY, max, EPSILON); } @Test public void testDenseVector() { Vector vec1 = new DenseVector(3); Vector vec2 = new DenseVector(3); doTestVectors(vec1, vec2); } @Test public void testVectorView() { RandomAccessSparseVector vec1 = new RandomAccessSparseVector(3); RandomAccessSparseVector vec2 = new RandomAccessSparseVector(6); SequentialAccessSparseVector vec3 = new SequentialAccessSparseVector(3); SequentialAccessSparseVector vec4 = new SequentialAccessSparseVector(6); Vector vecV1 = new VectorView(vec1, 0, 3); Vector vecV2 = new VectorView(vec2, 2, 3); Vector vecV3 = new VectorView(vec3, 0, 3); Vector vecV4 = new VectorView(vec4, 2, 3); doTestVectors(vecV1, vecV2); doTestVectors(vecV3, vecV4); } /** Asserts a vector using enumeration equals a given dense vector */ private static void doTestEnumeration(double[] apriori, Vector vector) { double[] test = new double[apriori.length]; Iterator<Vector.Element> iter = vector.iterateNonZero(); while (iter.hasNext()) { Vector.Element e = iter.next(); test[e.index()] = e.get(); } for (int i = 0; i < test.length; i++) { assertEquals(apriori[i], test[i], EPSILON); } } @Test public void testEnumeration() { double[] apriori = {0, 1, 2, 3, 4}; doTestEnumeration(apriori, new VectorView(new DenseVector(new double[]{ -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}), 2, 5)); doTestEnumeration(apriori, new DenseVector(new double[]{0, 1, 2, 3, 4})); Vector sparse = new RandomAccessSparseVector(5); sparse.set(0, 0); sparse.set(1, 1); sparse.set(2, 2); sparse.set(3, 3); sparse.set(4, 4); doTestEnumeration(apriori, sparse); sparse = new SequentialAccessSparseVector(5); sparse.set(0, 0); sparse.set(1, 1); sparse.set(2, 2); sparse.set(3, 3); sparse.set(4, 4); doTestEnumeration(apriori, sparse); } @Test public void testAggregation() { Vector v = new DenseVector(5); Vector w = new DenseVector(5); setUpFirstVector(v); setUpSecondVector(w); doTestAggregation(v, w); v = new RandomAccessSparseVector(5); w = new RandomAccessSparseVector(5); setUpFirstVector(v); doTestAggregation(v, w); setUpSecondVector(w); doTestAggregation(w, v); v = new SequentialAccessSparseVector(5); w = new SequentialAccessSparseVector(5); setUpFirstVector(v); doTestAggregation(v, w); setUpSecondVector(w); doTestAggregation(w, v); } private static void doTestAggregation(Vector v, Vector w) { assertEquals("aggregate(plus, pow(2)) not equal to " + v.getLengthSquared(), v.getLengthSquared(), v.aggregate(Functions.PLUS, Functions.pow(2)), EPSILON); assertEquals("aggregate(plus, abs) not equal to " + v.norm(1), v.norm(1), v.aggregate(Functions.PLUS, Functions.ABS), EPSILON); assertEquals("aggregate(max, abs) not equal to " + v.norm(Double.POSITIVE_INFINITY), v.norm(Double.POSITIVE_INFINITY), v.aggregate(Functions.MAX, Functions.ABS), EPSILON); assertEquals("v.dot(w) != v.aggregate(w, plus, mult)", v.dot(w), v.aggregate(w, Functions.PLUS, Functions.MULT), EPSILON); assertEquals("|(v-w)|^2 != v.aggregate(w, plus, chain(pow(2), minus))", v.minus(w).dot(v.minus(w)), v.aggregate(w, Functions.PLUS, Functions.chain(Functions.pow(2), Functions.MINUS)), EPSILON); } @Test(expected = IllegalArgumentException.class) public void testEmptyAggregate1() { assertEquals(1.0, new DenseVector(new double[]{1}).aggregate(Functions.MIN, Functions.IDENTITY), EPSILON); assertEquals(1.0, new DenseVector(new double[]{2, 1}).aggregate(Functions.MIN, Functions.IDENTITY), EPSILON); new DenseVector(new double[0]).aggregate(Functions.MIN, Functions.IDENTITY); } @Test(expected = IllegalArgumentException.class) public void testEmptyAggregate2() { assertEquals(3.0, new DenseVector(new double[]{1}).aggregate( new DenseVector(new double[]{2}),Functions.MIN, Functions.PLUS), EPSILON); new DenseVector(new double[0]).aggregate(new DenseVector(new double[0]), Functions.MIN, Functions.PLUS); } private static void setUpFirstVector(Vector v) { v.setQuick(1, 2); v.setQuick(2, 0.5); v.setQuick(3, -5); } private static void setUpSecondVector(Vector v) { v.setQuick(0, 3); v.setQuick(1, -1.5); v.setQuick(2, -5); v.setQuick(3, 2); } @Test public void testHashCodeEquivalence() { // Hash codes must be equal if the vectors are considered equal Vector sparseLeft = new RandomAccessSparseVector(3); Vector denseRight = new DenseVector(3); sparseLeft.setQuick(0, 1); sparseLeft.setQuick(1, 2); sparseLeft.setQuick(2, 3); denseRight.setQuick(0, 1); denseRight.setQuick(1, 2); denseRight.setQuick(2, 3); assertEquals(sparseLeft, denseRight); assertEquals(sparseLeft.hashCode(), denseRight.hashCode()); sparseLeft = new SequentialAccessSparseVector(3); sparseLeft.setQuick(0, 1); sparseLeft.setQuick(1, 2); sparseLeft.setQuick(2, 3); assertEquals(sparseLeft, denseRight); assertEquals(sparseLeft.hashCode(), denseRight.hashCode()); Vector denseLeft = new DenseVector(3); denseLeft.setQuick(0, 1); denseLeft.setQuick(1, 2); denseLeft.setQuick(2, 3); assertEquals(denseLeft, denseRight); assertEquals(denseLeft.hashCode(), denseRight.hashCode()); Vector sparseRight = new SequentialAccessSparseVector(3); sparseRight.setQuick(0, 1); sparseRight.setQuick(1, 2); sparseRight.setQuick(2, 3); assertEquals(sparseLeft, sparseRight); assertEquals(sparseLeft.hashCode(), sparseRight.hashCode()); DenseVector emptyLeft = new DenseVector(0); Vector emptyRight = new SequentialAccessSparseVector(0); assertEquals(emptyLeft, emptyRight); assertEquals(emptyLeft.hashCode(), emptyRight.hashCode()); emptyRight = new RandomAccessSparseVector(0); assertEquals(emptyLeft, emptyRight); assertEquals(emptyLeft.hashCode(), emptyRight.hashCode()); } @Test public void testHashCode() { // Make sure that hash([1,0,2]) != hash([1,2,0]) Vector left = new SequentialAccessSparseVector(3); Vector right = new SequentialAccessSparseVector(3); left.setQuick(0, 1); left.setQuick(2, 2); right.setQuick(0, 1); right.setQuick(1, 2); assertFalse(left.equals(right)); assertFalse(left.hashCode() == right.hashCode()); left = new RandomAccessSparseVector(3); right = new RandomAccessSparseVector(3); left.setQuick(0, 1); left.setQuick(2, 2); right.setQuick(0, 1); right.setQuick(1, 2); assertFalse(left.equals(right)); assertFalse(left.hashCode() == right.hashCode()); // Make sure that hash([1,0,2,0,0,0]) != hash([1,0,2]) right = new SequentialAccessSparseVector(5); right.setQuick(0, 1); right.setQuick(2, 2); assertFalse(left.equals(right)); assertFalse(left.hashCode() == right.hashCode()); right = new RandomAccessSparseVector(5); right.setQuick(0, 1); right.setQuick(2, 2); assertFalse(left.equals(right)); assertFalse(left.hashCode() == right.hashCode()); } }