public Long2DoubleSortedArrayMap getItemOffets() { return Long2DoubleSortedArrayMap.wrap(itemIndex, itemOffsets); } }
/** * Create a map that maps a group of items to the same value. * @param keys The keys. * @param value The value. * @return A map that contains all `keys`, mapping each of them to `value`. */ public static Long2DoubleMap constantDoubleMap(Set<Long> keys, double value) { // TODO Implement this using a flyweight wrapper SortedKeyIndex idx = SortedKeyIndex.fromCollection(keys); double[] values = new double[idx.size()]; Arrays.fill(values, value); return Long2DoubleSortedArrayMap.wrap(idx, values); }
@Override public Long2DoubleMap getUserBiases(LongSet users) { SortedKeyIndex index = SortedKeyIndex.fromCollection(users); final int n = index.size(); double[] values = new double[n]; for (int i = 0; i < n; i++) { values[i] = getUserBias(index.getKey(i)); } return Long2DoubleSortedArrayMap.wrap(index, values); }
public Long2DoubleSortedMap clampVector(Map<Long,Double> scores) { SortedKeyIndex keys = SortedKeyIndex.fromCollection(scores.keySet()); Long2DoubleFunction baseVals = LongUtils.asLong2DoubleMap(scores); double[] values = new double[keys.size()]; for (int i = 0; i < values.length; i++) { long item = keys.getKey(i); values[i] = clampValue(baseVals.get(item)); } return Long2DoubleSortedArrayMap.wrap(keys, values); }
/** * Multiply each element of a vector by a scalar. * @param vector The vector. * @param value The scalar to multiply. * @return A new vector consisting of the same keys as `vector`, with `value` multipled by each. */ @Nonnull public static Long2DoubleMap multiplyScalar(Long2DoubleMap vector, double value) { // TODO Consier implementing this in terms of transform SortedKeyIndex idx = SortedKeyIndex.fromCollection(vector.keySet()); int n = idx.size(); double[] values = new double[n]; for (int i = 0; i < n; i++) { values[i] = vector.get(idx.getKey(i)) * value; } return Long2DoubleSortedArrayMap.wrap(idx, values); }
/** * Create a new {@link Long2DoubleSortedArrayMap} from unsorted key and value * arrays. The provided arrays will be modified and should not be used * by the client after this operation has completed. The key domain of * the new {@link Long2DoubleSortedArrayMap} will be the same as {@code keys}. * * @param keys Array of entry keys. This should be duplicate-free. * @param values The values of the vector, in key order. * @return A sparse vector backed by the provided arrays. * @throws IllegalArgumentException if there is a problem with the provided * arrays (length mismatch, etc.). */ public static Long2DoubleSortedArrayMap wrapUnsorted(long[] keys, double[] values) { IdComparator comparator = new IdComparator(keys); ParallelSwapper swapper = new ParallelSwapper(keys, values); quickSort(0, keys.length, comparator, swapper); int n = keys.length; for (int i = 1; i < n; i++) { if (keys[i-1] == keys[i]) { throw new IllegalArgumentException("duplicate keys"); } } SortedKeyIndex index = SortedKeyIndex.wrap(keys, keys.length); return wrap(index, values); }
@Nullable @Override public Long2DoubleMap apply(@Nullable Long2DoubleMap input) { if (input == null) return null; Map<Long,Double> base = baselineScorer.score(user, input.keySet()); SortedKeyIndex idx = SortedKeyIndex.fromCollection(input.keySet()); int n = idx.size(); double[] values = new double[n]; for (int i = 0; i < n; i++) { long k = idx.getKey(i); Double bp = base.get(k); double bpv = bp != null ? bp : 0; values[i] = input.get(idx.getKey(i)) - bpv; } return Long2DoubleSortedArrayMap.wrap(idx, values); }
/** * Test ItemItemBuildContext when all items have rating data. */ @Test public void testAllItemsData() { SortedKeyIndex items = SortedKeyIndex.create(1, 2, 3, 4); long[] userIds = {101, 102, 103, 104}; SortedKeyIndex idx = SortedKeyIndex.create(userIds); double[] ratings1 = {4.0, 3.0, 2.5, 2.0}; double[] ratings2 = {3.0, 2.5, 4.0, 1.0}; double[] ratings3 = {5.0, 3.5, 0.5, 1.0}; double[] ratings4 = {4.5, 3.0, 3.5, 1.5}; Long2DoubleSortedArrayMap v1 = Long2DoubleSortedArrayMap.wrap(idx, ratings1); Long2DoubleSortedArrayMap v2 = Long2DoubleSortedArrayMap.wrap(idx, ratings2); Long2DoubleSortedArrayMap v3 = Long2DoubleSortedArrayMap.wrap(idx, ratings3); Long2DoubleSortedArrayMap v4 = Long2DoubleSortedArrayMap.wrap(idx, ratings4); Long2DoubleSortedArrayMap[] ratings = { v1, v2, v3, v4 }; ItemItemBuildContext context = new ItemItemBuildContext(items, ratings, new Long2ObjectOpenHashMap<LongSortedSet>()); testRatingIntegrity(items, ratings, context); }
@Override public Long2DoubleMap unapply(Long2DoubleMap input) { if (input == null) return null; Map<Long,Double> base = baselineScorer.score(user, input.keySet()); SortedKeyIndex idx = SortedKeyIndex.fromCollection(input.keySet()); int n = idx.size(); double[] values = new double[n]; for (int i = 0; i < n; i++) { long k = idx.getKey(i); Double bp = base.get(k); double bpv = bp != null ? bp : 0; values[i] = input.get(idx.getKey(i)) + bpv; } return Long2DoubleSortedArrayMap.wrap(idx, values); }
@Inject public PopularityRankItemScorer(final InteractionStatistics stats) { statistics = stats; long[] items = stats.getKnownItems().toLongArray(); LongArrays.quickSort(items, (l1, l2) -> Integer.compare(stats.getInteractionCount(l2), stats.getInteractionCount(l1))); Long2IntMap ranks = LongUtils.itemRanks(LongArrayList.wrap(items)); SortedKeyIndex keys = SortedKeyIndex.fromCollection(ranks.keySet()); int n = keys.size(); double[] values = new double[n]; for (int i = 0; i < n; i++) { values[i] = 1.0 - ranks.get(keys.getKey(i)) / ((double) n); } rankScores = Long2DoubleSortedArrayMap.wrap(keys, values); }
/** * Transform the values of a vector. * * @param input The vector to transform. * @param function The transformation to apply. * @return A new vector that is the result of applying `function` to each value in `input`. */ public static Long2DoubleMap transform(Long2DoubleMap input, DoubleUnaryOperator function) { // FIXME Improve performance when input is also sorted SortedKeyIndex idx = SortedKeyIndex.fromCollection(input.keySet()); int n = idx.size(); double[] values = new double[n]; for (int i = 0; i < n; i++) { values[i] = function.applyAsDouble(input.get(idx.getKey(i))); } return Long2DoubleSortedArrayMap.wrap(idx, values); }
/** * Create a map from an array and index mapping. * * @param mapping The index mapping specifying the keys. * @param values The array of values. * @return A sparse vector mapping the IDs in {@code map} to the values in {@code values}. * @throws IllegalArgumentException if {@code values} not the same size as {@code idx}. */ public static Long2DoubleSortedArrayMap fromArray(KeyIndex mapping, DoubleList values) { Preconditions.checkArgument(values.size() == mapping.size(), "value array and index have different sizes: " + values.size() + " != " + mapping.size()); final int n = values.size(); double[] nvs = new double[n]; SortedKeyIndex index = SortedKeyIndex.fromCollection(mapping.getKeyList()); for (int i = 0; i < n; i++) { long item = index.getKey(i); int origIndex = mapping.getIndex(item); nvs[i] = values.getDouble(origIndex); } return wrap(index, nvs); }
/** * Add a scalar to each element of a vector. * @param vec The vector to rescale. * @param val The value to add. * @return A new map with every value in {@code vec} increased by {@code val}. */ public static Long2DoubleMap addScalar(Long2DoubleMap vec, double val) { SortedKeyIndex keys = SortedKeyIndex.fromCollection(vec.keySet()); final int n = keys.size(); double[] values = new double[n]; if (vec instanceof Long2DoubleSortedArrayMap) { Long2DoubleSortedArrayMap sorted = (Long2DoubleSortedArrayMap) vec; for (int i = 0; i < n; i++) { assert sorted.getKeyByIndex(i) == keys.getKey(i); values[i] = sorted.getValueByIndex(i) + val; } } else { for (int i = 0; i < n; i++) { values[i] = vec.get(keys.getKey(i)) + val; } } return Long2DoubleSortedArrayMap.wrap(keys, values); }
private Long2DoubleSortedArrayMap slowSubMap(LongSet toKeep) { LongSortedSet kept = LongUtils.setIntersect(keySet(), toKeep); double[] nvs = new double[kept.size()]; int i = keys.getLowerBound(); int j = 0; LongIterator iter = kept.iterator(); while (iter.hasNext()) { long key = iter.nextLong(); while (keys.getKey(i) < key) { i++; } nvs[j] = values[i]; j++; i++; } return wrap(SortedKeyIndex.fromCollection(kept), nvs); }
/** * Test ItemItemBuildContext when some items have rating data. */ @Test public void testSomeItemsData() { SortedKeyIndex items = SortedKeyIndex.create(1, 2, 3, 4); long[] userIds = {101, 102, 103, 104}; SortedKeyIndex idx = SortedKeyIndex.create(userIds); double[] ratings1 = {4.0, 3.0, 2.5, 2.0}; double[] ratings4 = {4.5, 3.0, 3.5, 1.5}; Long2DoubleSortedArrayMap v1 = Long2DoubleSortedArrayMap.wrap(idx, ratings1); Long2DoubleSortedArrayMap v4 = Long2DoubleSortedArrayMap.wrap(idx, ratings4); Long2DoubleSortedMap[] ratingMap = { v1, Long2DoubleSortedMaps.EMPTY_MAP, Long2DoubleSortedMaps.EMPTY_MAP, Long2DoubleSortedMaps.EMPTY_MAP, v4 }; ItemItemBuildContext context = new ItemItemBuildContext(items, ratingMap, new Long2ObjectOpenHashMap<LongSortedSet>()); testRatingIntegrity(items, ratingMap, context); }
return wrap(SortedKeyIndex.wrap(nks, ni), nvs);
/** * Test method for {@link Ratings#itemRatingVector(java.util.Collection)}. */ @Test public void testItemRatingVector() { Collection<Rating> ratings = new ArrayList<>(); ratings.add(Rating.create(7, 5, 3.5)); RatingBuilder rb = new RatingBuilder(); ratings.add(Rating.create(3, 5, 1.5)); ratings.add(Rating.create(8, 5, 2)); Long2DoubleMap v = Ratings.itemRatingVector(ratings); assertEquals(3, v.size()); assertEquals(7, Vectors.sum(v), EPSILON); long[] keys = {3, 7, 8}; double[] values = {1.5, 3.5, 2}; Long2DoubleSortedArrayMap sv = Long2DoubleSortedArrayMap.wrap(SortedKeyIndex.create(keys), values); assertEquals(sv, v); } }
/** * Add a vector to another (scaled) vector and a scalar. The result is \\(x_i + s_y y_i + o\\). * * @param x The source vector. * @param y The addition vector. {@link Long2DoubleFunction#defaultReturnValue()} is assumed for missing values. * @param sy The scale by which elements of {@code y} are multipled. * @param o The offset to add. * @return A vector with the same keys as {@code x}, transformed by the specified linear formula. */ public static Long2DoubleMap combine(Long2DoubleMap x, Long2DoubleFunction y, double sy, double o) { SortedKeyIndex idx = SortedKeyIndex.fromCollection(x.keySet()); final int n = idx.size(); double[] values = new double[n]; if (x instanceof Long2DoubleSortedArrayMap) { // TODO make this fast for two sorted maps Long2DoubleSortedArrayMap sx = (Long2DoubleSortedArrayMap) x; assert idx == sx.keySet().getIndex(); for (int i = 0; i < n; i++) { values[i] = sx.getValueByIndex(i) + y.get(idx.getKey(i)) * sy + o; } } else { for (int i = 0; i < n; i++) { long k = idx.getKey(i); values[i] = x.get(k) + y.get(k) * sy + o; } } return Long2DoubleSortedArrayMap.wrap(idx, values); }
/** * Test method for {@link Ratings#userRatingVector(java.util.Collection)}. */ @Test public void testUserRatingVector() { Collection<Rating> ratings = Lists.newArrayList( Rating.create(5, 7, 3.5), Rating.create(5, 3, 1.5), Rating.create(5, 8, 2) ); Long2DoubleMap v = Ratings.userRatingVector(ratings); assertEquals(3, v.size()); assertEquals(7, Vectors.sum(v), EPSILON); long[] keys = {3, 7, 8}; double[] values = {1.5, 3.5, 2}; Long2DoubleSortedArrayMap sv = Long2DoubleSortedArrayMap.wrap(SortedKeyIndex.create(keys), values); assertEquals(sv, v); } }
@Override public Long2DoubleMap getUserBiases(LongSet users) { SortedKeyIndex index = SortedKeyIndex.fromCollection(users); final int n = index.size(); double[] values = new double[n]; for (int i = 0; i < n; i++) { values[i] = getUserBias(index.getKey(i)); } return Long2DoubleSortedArrayMap.wrap(index, values); }