/** * Create a new long-to-double map backed by a key index and a corresponding value array. * @param keys The keys. * @param vs The values (the array is used as-is, it is *not* copied). * @return The array map. */ public static Long2DoubleSortedArrayMap wrap(SortedKeyIndex keys, double[] vs) { return new Long2DoubleSortedArrayMap(keys, vs); }
/** * Create a new sorted array map from input data. * @param data The input data. * @return The sorted array map. */ @SuppressWarnings("deprecation") public static Long2DoubleSortedArrayMap create(Map<Long,Double> data) { if (data instanceof Long2DoubleSortedArrayMap) { return (Long2DoubleSortedArrayMap) data; } else { return new Long2DoubleSortedArrayMap(data); } }
/** * Create a frozen long-to-double map. This effectively creates a copy of a map, but if the provided map is an * instance of {@link org.lenskit.util.keys.Long2DoubleSortedArrayMap}, which is immutable, it is returned as-is * for efficiency. * * @param map The source map. * @return An immutable map with the same data as {@code map}. */ public static Long2DoubleSortedMap frozenMap(Map<Long,Double> map) { if (map instanceof Long2DoubleSortedArrayMap) { return (Long2DoubleSortedMap) map; } else { return new Long2DoubleSortedArrayMap(map); } }
/** * Create a new long-to-double sorted array map from another map. * * Using this method instead of the constructor allows copies of immutable vectors * to be skipped. * * @param input The vector to copy. * @return A new vector with the same data as {@code input}. */ public static Long2DoubleSortedArrayMap create(Long2DoubleMap input) { if (input instanceof Long2DoubleSortedArrayMap) { return (Long2DoubleSortedArrayMap) input; } else { return new Long2DoubleSortedArrayMap(input); } }
private Long2DoubleSortedArrayMap createSubMap(int lb, int ub) { return new Long2DoubleSortedArrayMap(keys.subIndex(lb, ub), values); }
/** * Create a new long-to-double map backed by a key index and a corresponding value array. * @param keys The keys. * @param vs The values (the array is used as-is, it is *not* copied). * @return The array map. */ public static Long2DoubleSortedArrayMap wrap(SortedKeyIndex keys, double[] vs) { return new Long2DoubleSortedArrayMap(keys, vs); }
/** * Create a new sorted array map from input data. * @param data The input data. * @return The sorted array map. */ @SuppressWarnings("deprecation") public static Long2DoubleSortedArrayMap create(Map<Long,Double> data) { if (data instanceof Long2DoubleSortedArrayMap) { return (Long2DoubleSortedArrayMap) data; } else { return new Long2DoubleSortedArrayMap(data); } }
@Override public synchronized Long2DoubleMap getUserRatingVector(long userId) { // FIXME Don't make this so locky if (cache == null) { cache = new Long2ObjectOpenHashMap<>(); } Long2DoubleMap data = cache.get(userId); if (data != null) { return data; } else { Collection<RatingMatrixEntry> prefs = this.getUserRatings(userId); Long2DoubleMap map = new Long2DoubleOpenHashMap(); for (RatingMatrixEntry e: prefs) { map.put(e.getItemId(), e.getValue()); } data = new Long2DoubleSortedArrayMap(map); cache.put(userId, data); return data; } }
@Test public void testSublist() { double[] values = { 1.5, 2.4, -3.2, 4.3, -5.7 }; Long2DoubleSortedMap map = new Long2DoubleSortedArrayMap(SortedKeyIndex.create(1, 2, 3, 4, 5), values); assertThat(map.size(), equalTo(5)); Long2DoubleSortedMap sub = map.subMap(2, 5); assertThat(sub.size(), equalTo(3)); assertThat(sub.containsKey(2L), equalTo(true)); assertThat(sub.containsKey(1L), equalTo(false)); assertThat(sub.containsKey(5L), equalTo(false)); assertThat(sub.containsKey(4L), equalTo(true)); assertThat(sub.keySet(), contains(2L, 3L, 4L)); }
/** * Create a new long-to-double sorted array map from another map. * * Using this method instead of the constructor allows copies of immutable vectors * to be skipped. * * @param input The vector to copy. * @return A new vector with the same data as {@code input}. */ public static Long2DoubleSortedArrayMap create(Long2DoubleMap input) { if (input instanceof Long2DoubleSortedArrayMap) { return (Long2DoubleSortedArrayMap) input; } else { return new Long2DoubleSortedArrayMap(input); } }
/** * Create a frozen long-to-double map. This effectively creates a copy of a map, but if the provided map is an * instance of {@link org.lenskit.util.keys.Long2DoubleSortedArrayMap}, which is immutable, it is returned as-is * for efficiency. * * @param map The source map. * @return An immutable map with the same data as {@code map}. */ public static Long2DoubleSortedMap frozenMap(Map<Long,Double> map) { if (map instanceof Long2DoubleSortedArrayMap) { return (Long2DoubleSortedMap) map; } else { return new Long2DoubleSortedArrayMap(map); } }
@Test public void testSingletonMap() { Long2DoubleSortedMap map = new Long2DoubleSortedArrayMap(SortedKeyIndex.create(42), new double[]{3.5}); assertThat(map.get(42L), equalTo(3.5)); assertThat(map.size(), equalTo(1)); assertThat(map.isEmpty(), equalTo(false)); assertThat(map.keySet(), contains(42L)); assertThat(map.values(), contains(3.5)); assertThat(map.entrySet(), hasSize(1)); assertThat(map.firstLongKey(), equalTo(42L)); assertThat(map.lastLongKey(), equalTo(42L)); Map.Entry<Long, Double> ent = map.entrySet().first(); assertThat(ent, notNullValue()); assertThat(ent.getKey(), equalTo(42L)); assertThat(ent.getValue(), equalTo(3.5)); assertThat(map.entrySet().contains(Pair.of(42L, 3.5)), equalTo(true)); assertThat(map.entrySet().contains(Pair.of(42L, 3.7)), equalTo(false)); assertThat(map.entrySet().contains(Pair.of(41L, 3.5)), equalTo(false)); assertThat(map.entrySet().first(), equalTo((Object) Pair.of(42L, 3.5))); assertThat(map.entrySet().last(), equalTo((Object) Pair.of(42L, 3.5))); }
@Test public void testIterStartFrom() { double[] values = { 1.5, 2.4, -3.2, 4.3, -5.7 }; Long2DoubleSortedMap map = new Long2DoubleSortedArrayMap(SortedKeyIndex.create(1, 2, 3, 4, 5), values); AbstractLong2DoubleMap.BasicEntry key = new AbstractLong2DoubleMap.BasicEntry(2, 2.0); ObjectBidirectionalIterator<Long2DoubleMap.Entry> iter = map.long2DoubleEntrySet().iterator(key); assertThat(iter.next().getLongKey(), equalTo(3L)); assertThat(iter.previous().getLongKey(), equalTo(3L)); assertThat(iter.previous().getLongKey(), equalTo(2L)); }
@Test public void testFastIterStartFrom() { double[] values = { 1.5, 2.4, -3.2, 4.3, -5.7 }; Long2DoubleSortedArrayMap map = new Long2DoubleSortedArrayMap(SortedKeyIndex.create(1, 2, 3, 4, 5), values); AbstractLong2DoubleMap.BasicEntry key = new AbstractLong2DoubleMap.BasicEntry(2, 2.0); ObjectBidirectionalIterator<Long2DoubleMap.Entry> iter = map.long2DoubleEntrySet().fastIterator(key); assertThat(iter.next().getLongKey(), equalTo(3L)); assertThat(iter.previous().getLongKey(), equalTo(3L)); assertThat(iter.previous().getLongKey(), equalTo(2L)); }
@Test public void testSubMapUnpacked() { SortedKeyIndex idx = SortedKeyIndex.create(1, 2, 3, 4, 5); double[] values = { 1.5, 2.4, -3.2, 4.3, -5.7 }; Long2DoubleSortedArrayMap map = new Long2DoubleSortedArrayMap(idx, values); assertThat(map.size(), equalTo(5)); Long2DoubleSortedMap sub = map.subMap(new LongOpenHashSet(LongUtils.packedSet(2L, 10L, 4L))); assertThat(sub.size(), equalTo(2)); assertThat(sub.containsKey(2L), equalTo(true)); assertThat(sub.containsKey(1L), equalTo(false)); assertThat(sub.containsKey(5L), equalTo(false)); assertThat(sub.containsKey(4L), equalTo(true)); assertThat(sub.containsKey(3L), equalTo(false)); assertThat(sub.keySet(), contains(2L, 4L)); assertThat(sub, hasEntry(2L, 2.4)); assertThat(sub, hasEntry(4L, 4.3)); }
@Test public void testSubMap() { SortedKeyIndex idx = SortedKeyIndex.create(1, 2, 3, 4, 5); double[] values = { 1.5, 2.4, -3.2, 4.3, -5.7 }; Long2DoubleSortedArrayMap map = new Long2DoubleSortedArrayMap(idx, values); assertThat(map.size(), equalTo(5)); Long2DoubleSortedMap sub = map.subMap(LongUtils.packedSet(2L, 4L)); assertThat(sub.size(), equalTo(2)); assertThat(sub.containsKey(2L), equalTo(true)); assertThat(sub.containsKey(1L), equalTo(false)); assertThat(sub.containsKey(5L), equalTo(false)); assertThat(sub.containsKey(4L), equalTo(true)); assertThat(sub.containsKey(3L), equalTo(false)); assertThat(sub.keySet(), contains(2L, 4L)); assertThat(sub, hasEntry(2L, 2.4)); assertThat(sub, hasEntry(4L, 4.3)); }
@Test public void testEmptyMap() { Long2DoubleSortedMap map = new Long2DoubleSortedArrayMap(SortedKeyIndex.empty(), new double[0]); assertThat(map.size(), equalTo(0)); assertThat(map.isEmpty(), equalTo(true)); assertThat(map.keySet(), hasSize(0)); assertThat(map.entrySet(), hasSize(0)); assertThat(map.values(), hasSize(0)); assertThat(map.long2DoubleEntrySet(), hasSize(0)); assertThat(map.get(42L), equalTo(0.0)); assertThat(map.get((Long) 42L), nullValue()); try { map.entrySet().first(); fail("entrySet.first should fail"); } catch (NoSuchElementException e) { /* expected */ } try { map.entrySet().last(); fail("entrySet.last should fail"); } catch (NoSuchElementException e) { /* expected */ } }
@Test public void testCreateWithLists() { for (Set<Long> keys: someSets(longs(), integers(0, 500))) { LongSortedSet sorted = LongUtils.packedSet(keys); SortedKeyIndex dom = SortedKeyIndex.fromCollection(keys); double[] values = new double[dom.size()]; for (int i = 0; i < dom.size(); i++) { values[i] = doubles().next(); } Long2DoubleSortedMap map = new Long2DoubleSortedArrayMap(dom, values); assertThat(map.size(), equalTo(dom.size())); assertThat(map.size(), equalTo(keys.size())); if (map.size() > 0) { assertThat(map.entrySet().first().getKey(), equalTo(sorted.firstLong())); assertThat(map.entrySet().last().getKey(), equalTo(sorted.lastLong())); assertThat(map.firstLongKey(), equalTo(sorted.firstLong())); assertThat(map.lastLongKey(), equalTo(sorted.lastLong())); } assertThat(map.keySet(), equalTo(sorted)); for (Long k: keys) { assertThat(map.containsKey(k), equalTo(true)); } } }
private Long2DoubleSortedArrayMap createSubMap(int lb, int ub) { return new Long2DoubleSortedArrayMap(keys.subIndex(lb, ub), values); }
@Test public void testDotSortedVectors() { for (Map<Long,Double> map: someMaps(longs(), doubles(-1000, 1000))) { Long2DoubleMap m = new Long2DoubleSortedArrayMap(map); assertThat(Vectors.dotProduct(m, m), equalTo(Vectors.sumOfSquares(m))); if (!m.isEmpty()) { long k1 = m.keySet().iterator().nextLong(); double v1 = m.get(k1); Long2DoubleMap m2 = new Long2DoubleOpenHashMap(m); m2.remove(k1); long k2 = k1; // find a key we haven't seen yet while (m2.containsKey(k2) || k2 == k1) { k2++; } m2.put(k2, v1); m2 = new Long2DoubleSortedArrayMap(m2); // and test that it is missing from the dot product assertThat(Vectors.dotProduct(m, m2), closeTo(Vectors.sumOfSquares(m) - v1 * v1, 1.0e-6)); } } }