/** * 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(); }
/** * 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); }
/** * 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; }