/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.math.interpolation.data; import java.io.Serializable; import java.util.Iterator; import java.util.Map; import java.util.NavigableMap; import com.opengamma.util.ArgumentChecker; /** * An implementation of {@link Interpolator1DDataBundle} backed by a * {@link NavigableMap}. * */ public class NavigableMapInterpolator1DDataBundle implements Interpolator1DDataBundle, Serializable { private final NavigableMap<Double, Double> _backingMap; public NavigableMapInterpolator1DDataBundle(final NavigableMap<Double, Double> backingMap) { ArgumentChecker.notNull(backingMap, "Backing map"); ArgumentChecker.isTrue(backingMap.size() > 0, "Must have at least two data points."); _backingMap = backingMap; } @Override public Double getLowerBoundKey(final Double value) { if (value < firstKey()) { throw new IllegalArgumentException("Could not get lower bound key for " + value + ": lowest x-value is " + firstKey()); } if (value > lastKey()) { throw new IllegalArgumentException("Could not get lower bound key for " + value + ": highest x-value is " + lastKey()); } return _backingMap.floorKey(value); } @Override public int getLowerBoundIndex(final Double value) { final Double lower = getLowerBoundKey(value); int i = 0; final Iterator<Double> iter = _backingMap.keySet().iterator(); Double key = iter.next(); while (!key.equals(lower)) { key = iter.next(); i++; } return i; } @Override public Double get(final Double key) { return _backingMap.get(key); } @Override public Double lastKey() { return _backingMap.lastKey(); } @Override public Double lastValue() { return _backingMap.lastEntry().getValue(); } @Override public Double higherKey(final Double key) { if (key < firstKey()) { throw new IllegalArgumentException("Could not get lower bound key for " + key + ": lowest x-value is " + firstKey()); } if (key > lastKey()) { throw new IllegalArgumentException("Could not get lower bound key for " + key + ": highest x-value is " + lastKey()); } return _backingMap.higherKey(key); } @Override public Double higherValue(final Double key) { final Map.Entry<Double, Double> entry = _backingMap.higherEntry(key); if (entry == null) { return null; } return entry.getValue(); } @Override public int size() { return _backingMap.size(); } @Override public double[] getKeys() { final double[] result = new double[size()]; int i = 0; for (final Double d : _backingMap.keySet()) { result[i++] = d; } assert i == size(); return result; } @Override public double[] getValues() { final double[] result = new double[size()]; int i = 0; for (final Double d : _backingMap.values()) { result[i++] = d; } assert i == size(); return result; } @Override public Double firstKey() { return _backingMap.firstKey(); } @Override public Double firstValue() { return _backingMap.firstEntry().getValue(); } @Override public boolean containsKey(final Double key) { return _backingMap.containsKey(key); } @Override public InterpolationBoundedValues getBoundedValues(final Double key) { final Double lowerBoundKey = getLowerBoundKey(key); final Double higherKey = higherKey(key); if (higherKey.equals(lastKey())) { return new InterpolationBoundedValues(getLowerBoundIndex(key), lastKey(), lastValue(), null, null); } return new InterpolationBoundedValues(getLowerBoundIndex(key), lowerBoundKey, get(lowerBoundKey), higherKey, higherValue(key)); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((_backingMap == null) ? 0 : _backingMap.hashCode()); return result; } @Override public boolean equals(final Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final NavigableMapInterpolator1DDataBundle other = (NavigableMapInterpolator1DDataBundle) obj; if (_backingMap == null) { if (other._backingMap != null) { return false; } } else if (!_backingMap.equals(other._backingMap)) { return false; } return true; } @Override public void setYValueAtIndex(final int index, final double y) { ArgumentChecker.notNegative(index, "index"); if (index >= size()) { throw new IllegalArgumentException("Index was greater than number of data points"); } int count = 0; for (final Map.Entry<Double, Double> entry : _backingMap.entrySet()) { if (count == index) { _backingMap.put(entry.getKey(), y); } count++; } } }