< prev index next >

src/java.base/share/classes/java/util/stream/DoublePipeline.java

Print this page
rev 52916 : [mq]: 8214761-Bug-in-parallel-Kahan-summation-implementation-for-Doublestream-sum
   1 /*
   2  * Copyright (c) 2013, 2017, 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


 400         return boxed().distinct().mapToDouble(i -> (double) i);
 401     }
 402 
 403     // Terminal ops from DoubleStream
 404 
 405     @Override
 406     public void forEach(DoubleConsumer consumer) {
 407         evaluate(ForEachOps.makeDouble(consumer, false));
 408     }
 409 
 410     @Override
 411     public void forEachOrdered(DoubleConsumer consumer) {
 412         evaluate(ForEachOps.makeDouble(consumer, true));
 413     }
 414 
 415     @Override
 416     public final double sum() {
 417         /*
 418          * In the arrays allocated for the collect operation, index 0
 419          * holds the high-order bits of the running sum, index 1 holds
 420          * the low-order bits of the sum computed via compensated
 421          * summation, and index 2 holds the simple sum used to compute
 422          * the proper result if the stream contains infinite values of
 423          * the same sign.
 424          */
 425         double[] summation = collect(() -> new double[3],
 426                                (ll, d) -> {
 427                                    Collectors.sumWithCompensation(ll, d);
 428                                    ll[2] += d;
 429                                },
 430                                (ll, rr) -> {
 431                                    Collectors.sumWithCompensation(ll, rr[0]);
 432                                    Collectors.sumWithCompensation(ll, rr[1]);
 433                                    ll[2] += rr[2];
 434                                });
 435 
 436         return Collectors.computeFinalSum(summation);
 437     }
 438 
 439     @Override
 440     public final OptionalDouble min() {
 441         return reduce(Math::min);
 442     }
 443 
 444     @Override
 445     public final OptionalDouble max() {
 446         return reduce(Math::max);
 447     }
 448 
 449     /**
 450      * {@inheritDoc}
 451      *
 452      * @implNote The {@code double} format can represent all
 453      * consecutive integers in the range -2<sup>53</sup> to
 454      * 2<sup>53</sup>. If the pipeline has more than 2<sup>53</sup>
 455      * values, the divisor in the average computation will saturate at
 456      * 2<sup>53</sup>, leading to additional numerical errors.
 457      */
 458     @Override
 459     public final OptionalDouble average() {
 460         /*
 461          * In the arrays allocated for the collect operation, index 0
 462          * holds the high-order bits of the running sum, index 1 holds
 463          * the low-order bits of the sum computed via compensated
 464          * summation, index 2 holds the number of values seen, index 3
 465          * holds the simple sum.
 466          */
 467         double[] avg = collect(() -> new double[4],
 468                                (ll, d) -> {
 469                                    ll[2]++;
 470                                    Collectors.sumWithCompensation(ll, d);
 471                                    ll[3] += d;
 472                                },
 473                                (ll, rr) -> {
 474                                    Collectors.sumWithCompensation(ll, rr[0]);
 475                                    Collectors.sumWithCompensation(ll, rr[1]);
 476                                    ll[2] += rr[2];
 477                                    ll[3] += rr[3];
 478                                });
 479         return avg[2] > 0
 480             ? OptionalDouble.of(Collectors.computeFinalSum(avg) / avg[2])
 481             : OptionalDouble.empty();
 482     }
 483 
 484     @Override
 485     public final long count() {
 486         return evaluate(ReduceOps.makeDoubleCounting());
 487     }
 488 
 489     @Override
 490     public final DoubleSummaryStatistics summaryStatistics() {
 491         return collect(DoubleSummaryStatistics::new, DoubleSummaryStatistics::accept,
 492                        DoubleSummaryStatistics::combine);
 493     }
 494 
 495     @Override


   1 /*
   2  * Copyright (c) 2013, 2018, 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


 400         return boxed().distinct().mapToDouble(i -> (double) i);
 401     }
 402 
 403     // Terminal ops from DoubleStream
 404 
 405     @Override
 406     public void forEach(DoubleConsumer consumer) {
 407         evaluate(ForEachOps.makeDouble(consumer, false));
 408     }
 409 
 410     @Override
 411     public void forEachOrdered(DoubleConsumer consumer) {
 412         evaluate(ForEachOps.makeDouble(consumer, true));
 413     }
 414 
 415     @Override
 416     public final double sum() {
 417         /*
 418          * In the arrays allocated for the collect operation, index 0
 419          * holds the high-order bits of the running sum, index 1 holds
 420          * the (negative) low-order bits of the sum computed via
 421          * compensated summation, and index 2 holds the simple sum used
 422          * to compute the proper result if the stream contains infinite
 423          * values of the same sign.
 424          */
 425         double[] summation = collect(() -> new double[3],
 426                                (ll, d) -> {
 427                                    Collectors.sumWithCompensation(ll, d);
 428                                    ll[2] += d;
 429                                },
 430                                (ll, rr) -> {
 431                                    Collectors.sumWithCompensation(ll, rr[0]);
 432                                    Collectors.sumWithCompensation(ll, -rr[1]);
 433                                    ll[2] += rr[2];
 434                                });
 435 
 436         return Collectors.computeFinalSum(summation);
 437     }
 438 
 439     @Override
 440     public final OptionalDouble min() {
 441         return reduce(Math::min);
 442     }
 443 
 444     @Override
 445     public final OptionalDouble max() {
 446         return reduce(Math::max);
 447     }
 448 
 449     /**
 450      * {@inheritDoc}
 451      *
 452      * @implNote The {@code double} format can represent all
 453      * consecutive integers in the range -2<sup>53</sup> to
 454      * 2<sup>53</sup>. If the pipeline has more than 2<sup>53</sup>
 455      * values, the divisor in the average computation will saturate at
 456      * 2<sup>53</sup>, leading to additional numerical errors.
 457      */
 458     @Override
 459     public final OptionalDouble average() {
 460         /*
 461          * In the arrays allocated for the collect operation, index 0
 462          * holds the high-order bits of the running sum, index 1 holds
 463          * the (negative) low-order bits of the sum computed via
 464          * compensated summation, index 2 holds the number of values
 465          * seen, index 3 holds the simple sum.
 466          */
 467         double[] avg = collect(() -> new double[4],
 468                                (ll, d) -> {
 469                                    ll[2]++;
 470                                    Collectors.sumWithCompensation(ll, d);
 471                                    ll[3] += d;
 472                                },
 473                                (ll, rr) -> {
 474                                    Collectors.sumWithCompensation(ll, rr[0]);
 475                                    Collectors.sumWithCompensation(ll, -rr[1]);
 476                                    ll[2] += rr[2];
 477                                    ll[3] += rr[3];
 478                                });
 479         return avg[2] > 0
 480             ? OptionalDouble.of(Collectors.computeFinalSum(avg) / avg[2])
 481             : OptionalDouble.empty();
 482     }
 483 
 484     @Override
 485     public final long count() {
 486         return evaluate(ReduceOps.makeDoubleCounting());
 487     }
 488 
 489     @Override
 490     public final DoubleSummaryStatistics summaryStatistics() {
 491         return collect(DoubleSummaryStatistics::new, DoubleSummaryStatistics::accept,
 492                        DoubleSummaryStatistics::combine);
 493     }
 494 
 495     @Override


< prev index next >