377 |
377 |
378 @Override |
378 @Override |
379 public final double sum() { |
379 public final double sum() { |
380 /* |
380 /* |
381 * In the arrays allocated for the collect operation, index 0 |
381 * In the arrays allocated for the collect operation, index 0 |
382 * holds the high-order bits of the running sum and index 1 |
382 * holds the high-order bits of the running sum, index 1 holds |
383 * holds the low-order bits of the sum computed via |
383 * the low-order bits of the sum computed via compensated |
384 * compensated summation. |
384 * summation, and index 2 holds the simple sum used to compute |
|
385 * the proper result if the stream contains infinite values of |
|
386 * the same sign. |
385 */ |
387 */ |
386 double[] summation = collect(() -> new double[2], |
388 double[] summation = collect(() -> new double[3], |
387 (ll, d) -> { |
389 (ll, d) -> { |
388 Collectors.sumWithCompensation(ll, d); |
390 Collectors.sumWithCompensation(ll, d); |
389 }, |
391 ll[2] += d; |
390 (ll, rr) -> { |
|
391 Collectors.sumWithCompensation(ll, rr[0]); |
|
392 Collectors.sumWithCompensation(ll, rr[1]); |
|
393 }); |
|
394 |
|
395 // Better error bounds to add both terms as the final sum |
|
396 return summation[0] + summation[1]; |
|
397 } |
|
398 |
|
399 @Override |
|
400 public final OptionalDouble min() { |
|
401 return reduce(Math::min); |
|
402 } |
|
403 |
|
404 @Override |
|
405 public final OptionalDouble max() { |
|
406 return reduce(Math::max); |
|
407 } |
|
408 |
|
409 /** |
|
410 * {@inheritDoc} |
|
411 * |
|
412 * @implNote The {@code double} format can represent all |
|
413 * consecutive integers in the range -2<sup>53</sup> to |
|
414 * 2<sup>53</sup>. If the pipeline has more than 2<sup>53</sup> |
|
415 * values, the divisor in the average computation will saturate at |
|
416 * 2<sup>53</sup>, leading to additional numerical errors. |
|
417 */ |
|
418 @Override |
|
419 public final OptionalDouble average() { |
|
420 /* |
|
421 * In the arrays allocated for the collect operation, index 0 |
|
422 * holds the high-order bits of the running sum, index 1 holds |
|
423 * the low-order bits of the sum computed via compensated |
|
424 * summation, and index 2 holds the number of values seen. |
|
425 */ |
|
426 double[] avg = collect(() -> new double[3], |
|
427 (ll, d) -> { |
|
428 ll[2]++; |
|
429 Collectors.sumWithCompensation(ll, d); |
|
430 }, |
392 }, |
431 (ll, rr) -> { |
393 (ll, rr) -> { |
432 Collectors.sumWithCompensation(ll, rr[0]); |
394 Collectors.sumWithCompensation(ll, rr[0]); |
433 Collectors.sumWithCompensation(ll, rr[1]); |
395 Collectors.sumWithCompensation(ll, rr[1]); |
434 ll[2] += rr[2]; |
396 ll[2] += rr[2]; |
435 }); |
397 }); |
|
398 |
|
399 return Collectors.computeFinalSum(summation); |
|
400 } |
|
401 |
|
402 @Override |
|
403 public final OptionalDouble min() { |
|
404 return reduce(Math::min); |
|
405 } |
|
406 |
|
407 @Override |
|
408 public final OptionalDouble max() { |
|
409 return reduce(Math::max); |
|
410 } |
|
411 |
|
412 /** |
|
413 * {@inheritDoc} |
|
414 * |
|
415 * @implNote The {@code double} format can represent all |
|
416 * consecutive integers in the range -2<sup>53</sup> to |
|
417 * 2<sup>53</sup>. If the pipeline has more than 2<sup>53</sup> |
|
418 * values, the divisor in the average computation will saturate at |
|
419 * 2<sup>53</sup>, leading to additional numerical errors. |
|
420 */ |
|
421 @Override |
|
422 public final OptionalDouble average() { |
|
423 /* |
|
424 * In the arrays allocated for the collect operation, index 0 |
|
425 * holds the high-order bits of the running sum, index 1 holds |
|
426 * the low-order bits of the sum computed via compensated |
|
427 * summation, index 2 holds the number of values seen, index 3 |
|
428 * holds the simple sum. |
|
429 */ |
|
430 double[] avg = collect(() -> new double[4], |
|
431 (ll, d) -> { |
|
432 ll[2]++; |
|
433 Collectors.sumWithCompensation(ll, d); |
|
434 ll[3] += d; |
|
435 }, |
|
436 (ll, rr) -> { |
|
437 Collectors.sumWithCompensation(ll, rr[0]); |
|
438 Collectors.sumWithCompensation(ll, rr[1]); |
|
439 ll[2] += rr[2]; |
|
440 ll[3] += rr[3]; |
|
441 }); |
436 return avg[2] > 0 |
442 return avg[2] > 0 |
437 // Better error bounds to add both terms as the final sum to compute average |
443 ? OptionalDouble.of(Collectors.computeFinalSum(avg) / avg[2]) |
438 ? OptionalDouble.of((avg[0] + avg[1]) / avg[2]) |
|
439 : OptionalDouble.empty(); |
444 : OptionalDouble.empty(); |
440 } |
445 } |
441 |
446 |
442 @Override |
447 @Override |
443 public final long count() { |
448 public final long count() { |