ScaleContig { public int interpolate(long value) { final Set<Long> keySet = positionMap.keySet(); if (positionMap.containsKey(value)) { return positionMap.get(value); } long minValue = keySet.stream().mapToLong(x -> x).min().orElse(0); long maxValue = keySet.stream().mapToLong(x -> x).max().orElse(0); long closestToStart = keySet.stream().filter(x -> x < value).mapToLong(x -> x).max().orElse(minValue); long closestToEnd = keySet.stream().filter(x -> x > value).mapToLong(x -> x).min().orElse(maxValue); if (closestToStart == closestToEnd) { return positionMap.get(closestToStart); } double longDistanceProportion = Math.abs(value - closestToStart) / ((double) Math.abs(closestToEnd - closestToStart)); int clostestIntToStart = positionMap.get(closestToStart); int clostestIntToEnd = positionMap.get(closestToEnd); return clostestIntToStart + (int) Math.floor(longDistanceProportion * Math.abs(clostestIntToEnd - clostestIntToStart)); } @VisibleForTesting  ScaleContig(@NotNull final String contig, Map<Long, Integer> positionMap);   ScaleContig(@NotNull final String contig, @NotNull final List<Long> positions); boolean isEmpty(); String contig(); int length(); void expand(double factor); int scale(long position); int interpolate(long value);  }
@Test public void testInterpolate() { final Map<Long, Integer> map = Maps.newHashMap(); map.put(1000L, 10); final ScaleContig victim = new ScaleContig("Dummy", map); assertEquals(10, victim.interpolate(900L)); assertEquals(10, victim.interpolate(1000L)); assertEquals(10, victim.interpolate(1100L)); map.put(2000L, 20); assertEquals(10, victim.interpolate(900L)); assertEquals(10, victim.interpolate(1000L)); assertEquals(11, victim.interpolate(1100L)); assertEquals(15, victim.interpolate(1500L)); assertEquals(20, victim.interpolate(2000L)); assertEquals(20, victim.interpolate(2100L)); map.put(3000L, 40); assertEquals(20, victim.interpolate(2000L)); assertEquals(22, victim.interpolate(2100L)); assertEquals(30, victim.interpolate(2500L)); assertEquals(40, victim.interpolate(3000L)); }