下面列出了java.util.function.DoubleUnaryOperator#applyAsDouble ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Returns an infinite sequential ordered {@code DoubleStream} produced by iterative
* application of a function {@code f} to an initial element {@code seed},
* producing a {@code Stream} consisting of {@code seed}, {@code f(seed)},
* {@code f(f(seed))}, etc.
*
* <p>The first element (position {@code 0}) in the {@code DoubleStream}
* will be the provided {@code seed}. For {@code n > 0}, the element at
* position {@code n}, will be the result of applying the function {@code f}
* to the element at position {@code n - 1}.
*
* @param seed the initial element
* @param f a function to be applied to to the previous element to produce
* a new element
* @return a new sequential {@code DoubleStream}
*/
public static DoubleStream iterate(final double seed, final DoubleUnaryOperator f) {
Objects.requireNonNull(f);
final PrimitiveIterator.OfDouble iterator = new PrimitiveIterator.OfDouble() {
double t = seed;
@Override
public boolean hasNext() {
return true;
}
@Override
public double nextDouble() {
double v = t;
t = f.applyAsDouble(t);
return v;
}
};
return StreamSupport.doubleStream(Spliterators.spliteratorUnknownSize(
iterator,
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL), false);
}
/**
* Returns an infinite sequential ordered {@code DoubleStream} produced by iterative
* application of a function {@code f} to an initial element {@code seed},
* producing a {@code Stream} consisting of {@code seed}, {@code f(seed)},
* {@code f(f(seed))}, etc.
*
* <p>The first element (position {@code 0}) in the {@code DoubleStream}
* will be the provided {@code seed}. For {@code n > 0}, the element at
* position {@code n}, will be the result of applying the function {@code f}
* to the element at position {@code n - 1}.
*
* @param seed the initial element
* @param f a function to be applied to to the previous element to produce
* a new element
* @return a new sequential {@code DoubleStream}
*/
public static DoubleStream iterate(final double seed, final DoubleUnaryOperator f) {
Objects.requireNonNull(f);
final PrimitiveIterator.OfDouble iterator = new PrimitiveIterator.OfDouble() {
double t = seed;
@Override
public boolean hasNext() {
return true;
}
@Override
public double nextDouble() {
double v = t;
t = f.applyAsDouble(t);
return v;
}
};
return StreamSupport.doubleStream(Spliterators.spliteratorUnknownSize(
iterator,
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL), false);
}
/**
* Returns an infinite sequential ordered {@code DoubleStream} produced by iterative
* application of a function {@code f} to an initial element {@code seed},
* producing a {@code Stream} consisting of {@code seed}, {@code f(seed)},
* {@code f(f(seed))}, etc.
*
* <p>The first element (position {@code 0}) in the {@code DoubleStream}
* will be the provided {@code seed}. For {@code n > 0}, the element at
* position {@code n}, will be the result of applying the function {@code f}
* to the element at position {@code n - 1}.
*
* @param seed the initial element
* @param f a function to be applied to the previous element to produce
* a new element
* @return a new sequential {@code DoubleStream}
*/
public static DoubleStream iterate(final double seed, final DoubleUnaryOperator f) {
Objects.requireNonNull(f);
final PrimitiveIterator.OfDouble iterator = new PrimitiveIterator.OfDouble() {
double t = seed;
@Override
public boolean hasNext() {
return true;
}
@Override
public double nextDouble() {
double v = t;
t = f.applyAsDouble(t);
return v;
}
};
return StreamSupport.doubleStream(Spliterators.spliteratorUnknownSize(
iterator,
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL), false);
}
@Override
List<Data<Number, Number>> getPercentileData(int percentileOutputTicksPerHalf,
DoubleUnaryOperator xConversion,
DoubleUnaryOperator yConversion) {
DoublePercentileIterator percentileIterator = new DoublePercentileIterator(
accumulatedHistogram,
percentileOutputTicksPerHalf);
List<Data<Number, Number>> percentileData = new ArrayList<>(512);
while (percentileIterator.hasNext()) {
DoubleHistogramIterationValue value = percentileIterator.next();
final double x = xConversion.applyAsDouble(value.getPercentileLevelIteratedTo());
final double y = yConversion.applyAsDouble(value.getValueIteratedTo());
if (Double.isInfinite(x))
break;
percentileData.add(new Data<>(x, y));
}
return percentileData;
}
/**
* Returns an infinite sequential ordered {@code DoubleStream} produced by iterative
* application of a function {@code f} to an initial element {@code seed},
* producing a {@code Stream} consisting of {@code seed}, {@code f(seed)},
* {@code f(f(seed))}, etc.
*
* <p>The first element (position {@code 0}) in the {@code DoubleStream}
* will be the provided {@code seed}. For {@code n > 0}, the element at
* position {@code n}, will be the result of applying the function {@code f}
* to the element at position {@code n - 1}.
*
* @param seed the initial element
* @param f a function to be applied to to the previous element to produce
* a new element
* @return a new sequential {@code DoubleStream}
*/
public static DoubleStream iterate(final double seed, final DoubleUnaryOperator f) {
Objects.requireNonNull(f);
final PrimitiveIterator.OfDouble iterator = new PrimitiveIterator.OfDouble() {
double t = seed;
@Override
public boolean hasNext() {
return true;
}
@Override
public double nextDouble() {
double v = t;
t = f.applyAsDouble(t);
return v;
}
};
return StreamSupport.doubleStream(Spliterators.spliteratorUnknownSize(
iterator,
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL), false);
}
/**
* Atomically updates the element at index {@code i} with the results
* of applying the given function, returning the previous value. The
* function should be side-effect-free, since it may be re-applied
* when attempted updates fail due to contention among threads.
*
* @param i the index
* @param updateFunction a side-effect-free function
* @return the previous value
*/
public final double getAndUpdate(int i, DoubleUnaryOperator updateFunction)
{
double prev, next;
do
{
prev = get(i);
next = updateFunction.applyAsDouble(prev);
}
while (!compareAndSet(i, prev, next));
return prev;
}
@Override
public RandomVariable apply(final DoubleUnaryOperator operator) {
if(isDeterministic()) {
return new RandomVariableFromFloatArray(time, operator.applyAsDouble(valueIfNonStochastic));
} else
{
// Still faster than a parallel stream (2014.04)
final double[] result = new double[realizations.length];
for(int i=0; i<result.length; i++) {
result[i] = operator.applyAsDouble(realizations[i]);
}
return new RandomVariableFromFloatArray(time, result);
}
}
/**
* Atomically updates the element at index {@code i} with the results
* of applying the given function, returning the updated value. The
* function should be side-effect-free, since it may be re-applied
* when attempted updates fail due to contention among threads.
*
* @param i the index
* @param updateFunction a side-effect-free function
* @return the updated value
*/
public final double updateAndGet(int i, DoubleUnaryOperator updateFunction)
{
double prev, next;
do
{
prev = get(i);
next = updateFunction.applyAsDouble(prev);
}
while (!compareAndSet(i, prev, next));
return next;
}
/**
* This test compares the numerical sampled density (from a histogram) of the Brownian motion W(T)
* with the analytic density.
*/
@Test
public void testDensity() {
final int seed = 3141;
final int numberOfFactors = 1;
final int numberOfPaths = 10000000;
final TimeDiscretization timeDiscretization = new TimeDiscretizationFromArray(0, 10, 1.0);
final BrownianMotion brownianMotion = new BrownianMotionFromMersenneRandomNumbers(timeDiscretization, numberOfFactors, numberOfPaths, seed, abstractRandomVariableFactory);
RandomVariable brownianMotionAtTime = brownianMotion.getBrownianIncrement(0, 0);
for(int timeIndex=1; timeIndex<timeDiscretization.getNumberOfTimeSteps(); timeIndex++) {
final double[] intervalPoints = (new TimeDiscretizationFromArray(-2, 101, 4.0/100)).getAsDoubleArray();
final double[] histOfNormalFromBM = brownianMotionAtTime.getHistogram(intervalPoints);
final double time = brownianMotionAtTime.getFiltrationTime();
final DoubleUnaryOperator densityAnalytic = new DoubleUnaryOperator() {
@Override
public double applyAsDouble(final double x) { return Math.exp(-x*x/2.0/time) / Math.sqrt(2 * Math.PI * time); }
};
for(int i=0; i<intervalPoints.length-1; i++) {
final double center = (intervalPoints[i+1]+intervalPoints[i])/2.0;
final double size = intervalPoints[i+1]-intervalPoints[i];
final double density = histOfNormalFromBM[i+1] / size;
final double densityAnalyt = densityAnalytic.applyAsDouble(center);
Assert.assertEquals("Density", densityAnalyt, density, 5E-3);
}
brownianMotionAtTime = brownianMotionAtTime.add(brownianMotion.getBrownianIncrement(timeIndex, 0));
}
}
@Override
public RandomVariable apply(final DoubleUnaryOperator operator) {
if(isDeterministic()) {
return new RandomVariableFromDoubleArray(time, operator.applyAsDouble(valueIfNonStochastic));
}
else
{
// Still faster than a parallel stream (2014.04)
final double[] result = new double[realizations.length];
for(int i=0; i<result.length; i++) {
result[i] = operator.applyAsDouble(realizations[i]);
}
return new RandomVariableFromDoubleArray(time, result);
}
}
@Override
public RandomVariable apply(final DoubleUnaryOperator operator) {
if(isDeterministic()) {
return new RandomVariableFromDoubleArray(time, operator.applyAsDouble(valueIfNonStochastic));
}
else
{
// Still faster than a parallel stream (2014.04)
final double[] result = new double[realizations.length];
for(int i=0; i<result.length; i++) {
result[i] = operator.applyAsDouble(realizations[i]);
}
return new RandomVariableFromDoubleArray(time, result);
}
}
/**
* This test compares the numerical sampled density (from a histogram) of the Brownian motion W(T)
* with the analytic density.
*/
@Test
public void testDensity() {
final int seed = 3141;
final int numberOfFactors = 1;
final int numberOfPaths = 10000000;
final TimeDiscretization timeDiscretization = new TimeDiscretizationFromArray(0, 10, 1.0);
final BrownianMotion brownianMotion = new BrownianMotionFromMersenneRandomNumbers(timeDiscretization, numberOfFactors, numberOfPaths, seed, abstractRandomVariableFactory);
RandomVariable brownianMotionAtTime = brownianMotion.getBrownianIncrement(0, 0);
for(int timeIndex=1; timeIndex<timeDiscretization.getNumberOfTimeSteps(); timeIndex++) {
final double[] intervalPoints = (new TimeDiscretizationFromArray(-2, 101, 4.0/100)).getAsDoubleArray();
final double[] histOfNormalFromBM = brownianMotionAtTime.getHistogram(intervalPoints);
final double time = brownianMotionAtTime.getFiltrationTime();
final DoubleUnaryOperator densityAnalytic = new DoubleUnaryOperator() {
@Override
public double applyAsDouble(final double x) { return Math.exp(-x*x/2.0/time) / Math.sqrt(2 * Math.PI * time); }
};
for(int i=0; i<intervalPoints.length-1; i++) {
final double center = (intervalPoints[i+1]+intervalPoints[i])/2.0;
final double size = intervalPoints[i+1]-intervalPoints[i];
final double density = histOfNormalFromBM[i+1] / size;
final double densityAnalyt = densityAnalytic.applyAsDouble(center);
Assert.assertEquals("Density", densityAnalyt, density, 5E-3);
}
brownianMotionAtTime = brownianMotionAtTime.add(brownianMotion.getBrownianIncrement(timeIndex, 0));
}
}
public static double integrate(DoubleUnaryOperator f, double a, double b) {
return f.applyAsDouble(a);
}
@Override
public BondFutureOptionSensitivity mapSensitivity(DoubleUnaryOperator operator) {
return new BondFutureOptionSensitivity(
volatilitiesName, expiry, futureExpiryDate, strikePrice, futurePrice, currency, operator.applyAsDouble(sensitivity));
}
@Override
public OvernightRateSensitivity mapSensitivity(DoubleUnaryOperator operator) {
return new OvernightRateSensitivity(observation, endDate, currency, operator.applyAsDouble(sensitivity));
}
@Override
public IborCapletFloorletSabrSensitivity mapSensitivity(DoubleUnaryOperator operator) {
return new IborCapletFloorletSabrSensitivity(
volatilitiesName, expiry, sensitivityType, currency, operator.applyAsDouble(sensitivity));
}
/**
* Get the integral \( \int_{a}^{b} g(f(x)) dx \) of this function \( f \) plugged into a given function \( g \)
* for given bounds \( a, b \).
*
* @param lowerBound The lower bound a.
* @param upperBound The upper bound b.
* @param operator The given function g.
* @return The integral \( \int_{a}^{b} g(f(x)) dx \).
*/
public double getIntegral(double lowerBound, double upperBound, DoubleUnaryOperator operator) {
if(lowerBound == upperBound) {
return 0.0;
}
if(lowerBound > upperBound) {
return -getIntegral(upperBound, lowerBound);
}
int indexUpperOfLowerBound = Arrays.binarySearch(intervalRightPoints, lowerBound);
if(indexUpperOfLowerBound < 0) {
indexUpperOfLowerBound = -indexUpperOfLowerBound-1;
}
int indexLowerOfUpperBound = Arrays.binarySearch(intervalRightPoints, upperBound);
if(indexLowerOfUpperBound < 0) {
indexLowerOfUpperBound = -indexLowerOfUpperBound-1;
}
indexLowerOfUpperBound--;
if(indexLowerOfUpperBound < indexUpperOfLowerBound) {
// lower and upper bound fall in the same intervall
return operator.applyAsDouble(values[indexUpperOfLowerBound]) * (upperBound-lowerBound);
}
else {
// running error of error correction
double error = 0.0;
// right part of interval where lower bound is
double integral = operator.applyAsDouble(values[indexUpperOfLowerBound]) * (intervalRightPoints[indexUpperOfLowerBound]-lowerBound);
// in between intervals (if any)
for(int i=indexUpperOfLowerBound; i<indexLowerOfUpperBound; i++) {
final double value = operator.applyAsDouble(values[i+1]) * (intervalRightPoints[i+1]-intervalRightPoints[i]) - error;
final double newIntegral = integral + value;
error = newIntegral - integral - value;
integral = newIntegral;
}
// left part of interval where uper bound is
integral += operator.applyAsDouble(values[indexLowerOfUpperBound+1]) * (upperBound-intervalRightPoints[indexLowerOfUpperBound]) - error;
return integral;
}
}
@Override
public PointSensitivityBuilder mapSensitivity(DoubleUnaryOperator operator) {
value = operator.applyAsDouble(value);
return this;
}
@Override
public SwaptionSabrSensitivity mapSensitivity(DoubleUnaryOperator operator) {
return new SwaptionSabrSensitivity(
volatilitiesName, expiry, tenor, sensitivityType, currency, operator.applyAsDouble(sensitivity));
}
/**
* Applies an operation to the amount.
* <p>
* This is generally used to apply a mathematical operation to the amount.
* For example, the operator could multiply the amount by a constant, or take the inverse.
* <pre>
* multiplied = base.mapAmount(value -> (value < 0 ? 0 : value * 3));
* </pre>
*
* @param mapper the operator to be applied to the amount
* @return a copy of this amount with the mapping applied to the original amount
*/
public CurrencyAmount mapAmount(DoubleUnaryOperator mapper) {
ArgChecker.notNull(mapper, "mapper");
return new CurrencyAmount(currency, mapper.applyAsDouble(amount));
}