/** * Compute the sum of the squares of elements of a map (optimized). * @param v The vector * @return The sum of the squares of the values of {@code v}. */ public static double sumOfSquares(Long2DoubleSortedArrayMap v) { final int sz = v.size(); double ssq = 0; for (int i = 0; i < sz; i++) { double val = v.getValueByIndex(i); ssq += val * val; } return ssq; }
/** * Compute the dot product of two maps (optimized). This method assumes any value missing in one map is 0, so it is the dot * product of the values of common keys. * @param v1 The first vector. * @param v2 The second vector. * @return The sum of the products of corresponding values in the two vectors. */ public static double dotProduct(Long2DoubleSortedArrayMap v1, Long2DoubleSortedArrayMap v2) { double result; result = 0; final int sz1 = v1.size(); final int sz2 = v2.size(); int i1 = 0, i2 = 0; while (i1 < sz1 && i2 < sz2) { final long k1 = v1.getKeyByIndex(i1); final long k2 = v2.getKeyByIndex(i2); if (k1 < k2) { i1++; } else if (k2 < k1) { i2++; } else { result += v1.getValueByIndex(i1) * v2.getValueByIndex(i2); i1++; i2++; } } return result; }
@Test public void testSubMapIndexes() { Long2DoubleMap map = new Long2DoubleOpenHashMap(); map.put(1, 1.0); map.put(2, 2.0); map.put(3, 3.0); map.put(4, 4.0); Long2DoubleSortedArrayMap sam = Long2DoubleSortedArrayMap.create(map); Long2DoubleSortedArrayMap s2 = sam.subMap(2, 4); assertThat(s2.keySet(), contains(2L, 3L)); assertThat(s2.getKeyByIndex(0), equalTo(2L)); assertThat(s2.getKeyByIndex(1), equalTo(3L)); assertThat(s2.getValueByIndex(0), equalTo(2.0)); assertThat(s2.getValueByIndex(1), equalTo(3.0)); } }
/** * 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); }
/** * 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); }
/** * Compute the sum of the squares of elements of a map (optimized). * @param v The vector * @return The sum of the squares of the values of {@code v}. */ public static double sumOfSquares(Long2DoubleSortedArrayMap v) { final int sz = v.size(); double ssq = 0; for (int i = 0; i < sz; i++) { double val = v.getValueByIndex(i); ssq += val * val; } return ssq; }
/** * Compute the dot product of two maps (optimized). This method assumes any value missing in one map is 0, so it is the dot * product of the values of common keys. * @param v1 The first vector. * @param v2 The second vector. * @return The sum of the products of corresponding values in the two vectors. */ public static double dotProduct(Long2DoubleSortedArrayMap v1, Long2DoubleSortedArrayMap v2) { double result; result = 0; final int sz1 = v1.size(); final int sz2 = v2.size(); int i1 = 0, i2 = 0; while (i1 < sz1 && i2 < sz2) { final long k1 = v1.getKeyByIndex(i1); final long k2 = v2.getKeyByIndex(i2); if (k1 < k2) { i1++; } else if (k2 < k1) { i2++; } else { result += v1.getValueByIndex(i1) * v2.getValueByIndex(i2); i1++; i2++; } } return result; }
/** * 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); }
/** * 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); }