@Override public default Curve withPerturbation(ParameterPerturbation perturbation) { return (Curve) ParameterizedData.super.withPerturbation(perturbation); }
private ParameterizedDataCombiner(ParameterizedData[] underlyings) { ArgChecker.notEmpty(underlyings, "underlyings"); int size = underlyings.length; this.underlyings = underlyings; int[] lookup = new int[size]; for (int i = 1; i < size; i++) { lookup[i] = lookup[i - 1] + underlyings[i - 1].getParameterCount(); } this.lookup = lookup; this.paramCount = lookup[size - 1] + underlyings[size - 1].getParameterCount(); }
/** * Returns a perturbed copy of the data. * <p> * The perturbation instance will be invoked once for each parameter in this instance, * returning the perturbed value for that parameter. The result of this method is a * new instance that is based on those perturbed values. * <p> * This instance is immutable and unaffected by this method call. * * @param perturbation the perturbation to apply * @return a parameterized data instance based on this with the specified perturbation applied */ public default ParameterizedData withPerturbation(ParameterPerturbation perturbation) { ParameterizedData result = this; for (int i = 0; i < getParameterCount(); i++) { double currentValue = getParameter(i); double perturbedValue = perturbation.perturbParameter(i, currentValue, getParameterMetadata(i)); // compare using Double.doubleToLongBits() result = JodaBeanUtils.equal(currentValue, perturbedValue) ? result : result.withParameter(i, perturbedValue); } return result; }
public void test_withPerturbation() { assertSame(CURVE.withPerturbation((i, v, m) -> v), CURVE); assertEquals(CURVE.withPerturbation((i, v, m) -> v + 2d).getParameter(0), 3d); }
/** * Gets the value of the parameter at the specified index. * <p> * This gets the parameter from the correct instance. * * @param parameterIndex the zero-based index of the parameter to get * @return the value of the parameter * @throws IndexOutOfBoundsException if the index is invalid */ public double getParameter(int parameterIndex) { int underlyingIndex = findUnderlyingIndex(parameterIndex); int adjustment = lookup[underlyingIndex]; return underlyings[underlyingIndex].getParameter(parameterIndex - adjustment); }
/** * Updates a parameter on the specified list of underlying instances. * <p> * The correct underlying is identified and updated, with the list returned. * * @param <R> the type of the underlying * @param underlyingType the type of the parameterized data at the specified index * @param parameterIndex the zero-based index of the parameter to change * @param newValue the new value for the specified parameter * @return a parameterized data instance based on this with the specified parameter altered * @throws IndexOutOfBoundsException if the index is invalid */ public <R extends ParameterizedData> List<R> withParameter( Class<R> underlyingType, int parameterIndex, double newValue) { int underlyingIndex = findUnderlyingIndex(parameterIndex); ImmutableList.Builder<R> builder = ImmutableList.builder(); for (int i = 0; i < underlyings.length; i++) { ParameterizedData underlying = underlyings[i]; if (i == underlyingIndex) { int adjustment = lookup[underlyingIndex]; ParameterizedData perturbed = underlying.withParameter(parameterIndex - adjustment, newValue); builder.add(underlyingType.cast(perturbed)); } else { builder.add(underlyingType.cast(underlying)); } } return builder.build(); }
/** * Gets the metadata of the parameter at the specified index. * <p> * This gets the parameter metadata from the correct instance. * * @param parameterIndex the zero-based index of the parameter to get * @return the metadata of the parameter * @throws IndexOutOfBoundsException if the index is invalid */ public ParameterMetadata getParameterMetadata(int parameterIndex) { int underlyingIndex = findUnderlyingIndex(parameterIndex); int adjustment = lookup[underlyingIndex]; return underlyings[underlyingIndex].getParameterMetadata(parameterIndex - adjustment); }
/** * Updates a parameter on the specified underlying. * <p> * This should be invoked once for each of the underlying instances. * It is intended to be used to pass the result of each invocation to the * constructor of the combined instance. * <p> * If the parameter index applies to the underlying, it is updated. * If the parameter index does not apply to the underlying, no error occurs. * * @param <R> the type of the underlying * @param underlyingIndex the index of the underlying instance * @param underlyingType the type of the parameterized data at the specified index * @param parameterIndex the zero-based index of the parameter to change * @param newValue the new value for the specified parameter * @return a parameterized data instance based on this with the specified parameter altered * @throws IndexOutOfBoundsException if the index is invalid */ public <R extends ParameterizedData> R underlyingWithParameter( int underlyingIndex, Class<R> underlyingType, int parameterIndex, double newValue) { ParameterizedData perturbed = underlyings[underlyingIndex]; if (findUnderlyingIndex(parameterIndex) == underlyingIndex) { int adjustment = lookup[underlyingIndex]; perturbed = perturbed.withParameter(parameterIndex - adjustment, newValue); } return underlyingType.cast(perturbed); }
@Override public default Surface withPerturbation(ParameterPerturbation perturbation) { return (Surface) ParameterizedData.super.withPerturbation(perturbation); }
/** * Applies a perturbation to the specified underlying. * <p> * This should be invoked once for each of the underlying instances. * It is intended to be used to pass the result of each invocation to the * constructor of the combined instance. * * @param <R> the type of the underlying * @param underlyingIndex the index of the underlying instance * @param underlyingType the type of the parameterized data at the specified index * @param perturbation the perturbation to apply * @return a parameterized data instance based on this with the specified perturbation applied */ public <R extends ParameterizedData> R underlyingWithPerturbation( int underlyingIndex, Class<R> underlyingType, ParameterPerturbation perturbation) { ParameterizedData underlying = underlyings[underlyingIndex]; // perturb using a derived perturbation that adjusts the index int adjustment = lookup[underlyingIndex]; ParameterizedData perturbed = underlying.withPerturbation( (idx, value, meta) -> perturbation.perturbParameter(idx + adjustment, value, meta)); return underlyingType.cast(perturbed); }
private ParameterizedData applyShifts(int scenarioIndex, ParameterizedData prams) { return prams.withPerturbation((index, value, meta) -> { double shiftAmount = shiftForNode(scenarioIndex, meta); return shiftType.applyShift(value, shiftAmount); }); }