/** * Converts the sensitivities in this instance to an equivalent in the specified currency. * * <p>Any FX conversion that is required will use rates from the provider. * * @param resultCurrency the currency of the result * @param rateProvider the provider of FX rates * @return the sensitivity object expressed in terms of the result currency * @throws RuntimeException if no FX rate could be found */ @Override public CurveCurrencyParameterSensitivities convertedTo( Currency resultCurrency, FxRateProvider rateProvider) { List<CurveCurrencyParameterSensitivity> mutable = new ArrayList<>(); for (CurveCurrencyParameterSensitivity sens : sensitivities) { insert(mutable, sens.convertedTo(resultCurrency, rateProvider)); } return new CurveCurrencyParameterSensitivities(ImmutableList.copyOf(mutable)); }
// inserts a sensitivity into the mutable list in the right location // merges the entry with an existing entry if the key matches private static void insert( List<CurveCurrencyParameterSensitivity> mutable, CurveCurrencyParameterSensitivity addition) { int index = Collections.binarySearch(mutable, addition, CurveCurrencyParameterSensitivity::compareKey); if (index >= 0) { CurveCurrencyParameterSensitivity base = mutable.get(index); double[] combined = DoubleArrayMath.combineByAddition(base.getSensitivity(), addition.getSensitivity()); mutable.set(index, base.withSensitivity(combined)); } else { int insertionPoint = -(index + 1); mutable.add(insertionPoint, addition); } }
/** * Checks if this sensitivity equals another within the specified tolerance. * * <p>This returns true if the two instances have the same keys, with arrays of the same length, * where the {@code double} values are equal within the specified tolerance. * * @param other the other sensitivity * @param tolerance the tolerance * @return true if equal up to the tolerance */ public boolean equalWithTolerance(CurveCurrencyParameterSensitivities other, double tolerance) { List<CurveCurrencyParameterSensitivity> mutable = new ArrayList<>(other.sensitivities); // for each sensitivity in this instance, find matching in other instance for (CurveCurrencyParameterSensitivity sens1 : sensitivities) { // list is already sorted so binary search is safe int index = Collections.binarySearch(mutable, sens1, CurveCurrencyParameterSensitivity::compareKey); if (index >= 0) { // matched, so must be equal CurveCurrencyParameterSensitivity sens2 = mutable.get(index); if (!DoubleArrayMath.fuzzyEquals( sens1.getSensitivity(), sens2.getSensitivity(), tolerance)) { return false; } mutable.remove(index); } else { // did not match, so must be zero if (!DoubleArrayMath.fuzzyEqualsZero(sens1.getSensitivity(), tolerance)) { return false; } } } // all that remain from other instance must be zero for (CurveCurrencyParameterSensitivity sens2 : mutable) { if (!DoubleArrayMath.fuzzyEqualsZero(sens2.getSensitivity(), tolerance)) { return false; } } return true; }