1 /*
2 * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
639 * absolute magnitude tend to yield more accurate results. If any recorded
640 * value is a {@code NaN} or the sum is at any point a {@code NaN} then the
641 * sum will be {@code NaN}.
642 *
643 * @param <T> the type of the input elements
644 * @param mapper a function extracting the property to be summed
645 * @return a {@code Collector} that produces the sum of a derived property
646 */
647 public static <T> Collector<T, ?, Double>
648 summingDouble(ToDoubleFunction<? super T> mapper) {
649 /*
650 * In the arrays allocated for the collect operation, index 0
651 * holds the high-order bits of the running sum, index 1 holds
652 * the low-order bits of the sum computed via compensated
653 * summation, and index 2 holds the simple sum used to compute
654 * the proper result if the stream contains infinite values of
655 * the same sign.
656 */
657 return new CollectorImpl<>(
658 () -> new double[3],
659 (a, t) -> { sumWithCompensation(a, mapper.applyAsDouble(t));
660 a[2] += mapper.applyAsDouble(t);},
661 (a, b) -> { sumWithCompensation(a, b[0]);
662 a[2] += b[2];
663 return sumWithCompensation(a, b[1]); },
664 a -> computeFinalSum(a),
665 CH_NOID);
666 }
667
668 /**
669 * Incorporate a new double value using Kahan summation /
670 * compensation summation.
671 *
672 * High-order bits of the sum are in intermediateSum[0], low-order
673 * bits of the sum are in intermediateSum[1], any additional
674 * elements are application-specific.
675 *
676 * @param intermediateSum the high-order and low-order words of the intermediate sum
677 * @param value the name value to be included in the running sum
678 */
679 static double[] sumWithCompensation(double[] intermediateSum, double value) {
680 double tmp = value - intermediateSum[1];
751 * @implNote The {@code double} format can represent all
752 * consecutive integers in the range -2<sup>53</sup> to
753 * 2<sup>53</sup>. If the pipeline has more than 2<sup>53</sup>
754 * values, the divisor in the average computation will saturate at
755 * 2<sup>53</sup>, leading to additional numerical errors.
756 *
757 * @param <T> the type of the input elements
758 * @param mapper a function extracting the property to be summed
759 * @return a {@code Collector} that produces the sum of a derived property
760 */
761 public static <T> Collector<T, ?, Double>
762 averagingDouble(ToDoubleFunction<? super T> mapper) {
763 /*
764 * In the arrays allocated for the collect operation, index 0
765 * holds the high-order bits of the running sum, index 1 holds
766 * the low-order bits of the sum computed via compensated
767 * summation, and index 2 holds the number of values seen.
768 */
769 return new CollectorImpl<>(
770 () -> new double[4],
771 (a, t) -> { sumWithCompensation(a, mapper.applyAsDouble(t)); a[2]++; a[3]+= mapper.applyAsDouble(t);},
772 (a, b) -> { sumWithCompensation(a, b[0]); sumWithCompensation(a, b[1]); a[2] += b[2]; a[3] += b[3]; return a; },
773 a -> (a[2] == 0) ? 0.0d : (computeFinalSum(a) / a[2]),
774 CH_NOID);
775 }
776
777 /**
778 * Returns a {@code Collector} which performs a reduction of its
779 * input elements under a specified {@code BinaryOperator} using the
780 * provided identity.
781 *
782 * @apiNote
783 * The {@code reducing()} collectors are most useful when used in a
784 * multi-level reduction, downstream of {@code groupingBy} or
785 * {@code partitioningBy}. To perform a simple reduction on a stream,
786 * use {@link Stream#reduce(Object, BinaryOperator)}} instead.
787 *
788 * @param <T> element type for the input and output of the reduction
789 * @param identity the identity value for the reduction (also, the value
790 * that is returned when there are no input elements)
791 * @param op a {@code BinaryOperator<T>} used to reduce the input elements
|
1 /*
2 * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
639 * absolute magnitude tend to yield more accurate results. If any recorded
640 * value is a {@code NaN} or the sum is at any point a {@code NaN} then the
641 * sum will be {@code NaN}.
642 *
643 * @param <T> the type of the input elements
644 * @param mapper a function extracting the property to be summed
645 * @return a {@code Collector} that produces the sum of a derived property
646 */
647 public static <T> Collector<T, ?, Double>
648 summingDouble(ToDoubleFunction<? super T> mapper) {
649 /*
650 * In the arrays allocated for the collect operation, index 0
651 * holds the high-order bits of the running sum, index 1 holds
652 * the low-order bits of the sum computed via compensated
653 * summation, and index 2 holds the simple sum used to compute
654 * the proper result if the stream contains infinite values of
655 * the same sign.
656 */
657 return new CollectorImpl<>(
658 () -> new double[3],
659 (a, t) -> { double val = mapper.applyAsDouble(t);
660 sumWithCompensation(a, val);
661 a[2] += val;},
662 (a, b) -> { sumWithCompensation(a, b[0]);
663 a[2] += b[2];
664 return sumWithCompensation(a, b[1]); },
665 a -> computeFinalSum(a),
666 CH_NOID);
667 }
668
669 /**
670 * Incorporate a new double value using Kahan summation /
671 * compensation summation.
672 *
673 * High-order bits of the sum are in intermediateSum[0], low-order
674 * bits of the sum are in intermediateSum[1], any additional
675 * elements are application-specific.
676 *
677 * @param intermediateSum the high-order and low-order words of the intermediate sum
678 * @param value the name value to be included in the running sum
679 */
680 static double[] sumWithCompensation(double[] intermediateSum, double value) {
681 double tmp = value - intermediateSum[1];
752 * @implNote The {@code double} format can represent all
753 * consecutive integers in the range -2<sup>53</sup> to
754 * 2<sup>53</sup>. If the pipeline has more than 2<sup>53</sup>
755 * values, the divisor in the average computation will saturate at
756 * 2<sup>53</sup>, leading to additional numerical errors.
757 *
758 * @param <T> the type of the input elements
759 * @param mapper a function extracting the property to be summed
760 * @return a {@code Collector} that produces the sum of a derived property
761 */
762 public static <T> Collector<T, ?, Double>
763 averagingDouble(ToDoubleFunction<? super T> mapper) {
764 /*
765 * In the arrays allocated for the collect operation, index 0
766 * holds the high-order bits of the running sum, index 1 holds
767 * the low-order bits of the sum computed via compensated
768 * summation, and index 2 holds the number of values seen.
769 */
770 return new CollectorImpl<>(
771 () -> new double[4],
772 (a, t) -> { double val = mapper.applyAsDouble(t); sumWithCompensation(a, val); a[2]++; a[3]+= val;},
773 (a, b) -> { sumWithCompensation(a, b[0]); sumWithCompensation(a, b[1]); a[2] += b[2]; a[3] += b[3]; return a; },
774 a -> (a[2] == 0) ? 0.0d : (computeFinalSum(a) / a[2]),
775 CH_NOID);
776 }
777
778 /**
779 * Returns a {@code Collector} which performs a reduction of its
780 * input elements under a specified {@code BinaryOperator} using the
781 * provided identity.
782 *
783 * @apiNote
784 * The {@code reducing()} collectors are most useful when used in a
785 * multi-level reduction, downstream of {@code groupingBy} or
786 * {@code partitioningBy}. To perform a simple reduction on a stream,
787 * use {@link Stream#reduce(Object, BinaryOperator)}} instead.
788 *
789 * @param <T> element type for the input and output of the reduction
790 * @param identity the identity value for the reduction (also, the value
791 * that is returned when there are no input elements)
792 * @param op a {@code BinaryOperator<T>} used to reduce the input elements
|