/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.core.marketdatasnapshot; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.SortedSet; import java.util.TreeSet; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.opengamma.OpenGammaRuntimeException; import com.opengamma.id.UniqueIdentifiable; import com.opengamma.util.ArgumentChecker; import com.opengamma.util.money.Currency; import com.opengamma.util.tuple.FirstThenSecondPairComparator; import com.opengamma.util.tuple.ObjectsPair; import com.opengamma.util.tuple.Pair; /** * Data structure to hold a particular volatility surface's data points. * Note no interpolation or fitting is done in this code. * * @param <X> Type of the x-data * @param <Y> Type of the y-data */ public class VolatilitySurfaceData<X, Y> { /** Default name for the x axis */ public static final String DEFAULT_X_LABEL = "x"; /** Default name for the y axis */ public static final String DEFAULT_Y_LABEL = "y"; private static final Comparator<Pair<?, ?>> COMPARATOR = FirstThenSecondPairComparator.INSTANCE; private final String _definitionName; private final String _specificationName; private final UniqueIdentifiable _target; private final Map<Pair<X, Y>, Double> _values; private final X[] _xs; private final Y[] _ys; private final SortedSet<X> _uniqueXs; private final Map<X, List<ObjectsPair<Y, Double>>> _strips; private final String _xLabel; private final String _yLabel; public VolatilitySurfaceData(final String definitionName, final String specificationName, final UniqueIdentifiable target, final X[] xs, final Y[] ys, final Map<Pair<X, Y>, Double> values) { this(definitionName, specificationName, target, xs, DEFAULT_X_LABEL, ys, DEFAULT_Y_LABEL, values); } public VolatilitySurfaceData(final String definitionName, final String specificationName, final UniqueIdentifiable target, final X[] xs, final String xLabel, final Y[] ys, final String yLabel, final Map<Pair<X, Y>, Double> values) { ArgumentChecker.notNull(definitionName, "Definition Name"); ArgumentChecker.notNull(specificationName, "Specification Name"); ArgumentChecker.notNull(target, "Target"); ArgumentChecker.notNull(xs, "X axis values"); ArgumentChecker.notNull(xLabel, "x label"); ArgumentChecker.notNull(ys, "Y axis values"); ArgumentChecker.notNull(yLabel, "y label"); ArgumentChecker.notNull(values, "Volatility Values Map"); _definitionName = definitionName; _specificationName = specificationName; _target = target; _values = Maps.newHashMap(values); _xs = xs; _xLabel = xLabel; _ys = ys; _yLabel = yLabel; _uniqueXs = new TreeSet<X>(); _strips = Maps.newHashMap(); for (Map.Entry<Pair<X, Y>, Double> entries : values.entrySet()) { if (_strips.containsKey(entries.getKey().getFirst())) { _strips.get(entries.getKey().getFirst()).add(ObjectsPair.of(entries.getKey().getSecond(), entries.getValue())); } else { _uniqueXs.add(entries.getKey().getFirst()); final List<ObjectsPair<Y, Double>> list = Lists.newArrayList(); list.add(ObjectsPair.of(entries.getKey().getSecond(), entries.getValue())); _strips.put(entries.getKey().getFirst(), list); } } } public int size() { return _values.size(); } public X[] getXs() { return _xs; } public String getXLabel() { return _xLabel; } public Y[] getYs() { return _ys; } public String getYLabel() { return _yLabel; } public Double getVolatility(final X x, final Y y) { return _values.get(ObjectsPair.of(x, y)); } public SortedSet<X> getUniqueXValues() { return _uniqueXs; } public List<ObjectsPair<Y, Double>> getYValuesForX(final X x) { ArgumentChecker.notNull(x, "x"); if (!_strips.containsKey(x)) { throw new OpenGammaRuntimeException("Could not get strip for x value " + x); } List<ObjectsPair<Y, Double>> result = _strips.get(x); Collections.sort(result, COMPARATOR); return result; } public Map<Pair<X, Y>, Double> asMap() { return _values; } public String getDefinitionName() { return _definitionName; } public String getSpecificationName() { return _specificationName; } public UniqueIdentifiable getTarget() { return _target; } /** * @deprecated use getTarget() * @throws ClassCastException if target not a currency * @return currency assuming that the target is a currency */ @Deprecated public Currency getCurrency() { return (Currency) _target; } @Override public boolean equals(final Object o) { if (o == null) { return false; } if (!(o instanceof VolatilitySurfaceData)) { return false; } final VolatilitySurfaceData<?, ?> other = (VolatilitySurfaceData<?, ?>) o; return getDefinitionName().equals(other.getDefinitionName()) && getSpecificationName().equals(other.getSpecificationName()) && getTarget().equals(other.getTarget()) && Arrays.equals(getXs(), other.getXs()) && Arrays.equals(getYs(), other.getYs()) && getXLabel().equals(other.getXLabel()) && getYLabel().equals(other.getYLabel()) && _values.equals(other._values); } @Override public int hashCode() { return getDefinitionName().hashCode() * getSpecificationName().hashCode() * getTarget().hashCode(); } @Override public String toString() { return "VolatilitySurfaceData [" + "_definitionName='" + _definitionName + "'" + ", _specificationName='" + _specificationName + "'" + ", _target=" + _target + ", _xLabel='" + _xLabel + "'" + ", _yLabel='" + _yLabel + "'" + ", _xs=" + (_xs == null ? null : Arrays.asList(_xs)) + ", _ys=" + (_ys == null ? null : Arrays.asList(_ys)) + ", _values=" + _values + ", _uniqueXs=" + _uniqueXs + ", _strips=" + _strips + "]"; } }