按绝对量值对(流)加倍排序
Sorting (a stream of) doubles by absolute magnitude
我有一系列双精度值,我想将它们相加并获得最大值。
DoubleStream.summaryStatistics()
听起来很完美。
getSum()
方法有一个 API 注释提醒我在我的一门计算机科学课程中学到的东西:如果值按绝对值排序,求和问题的稳定性往往会更好。但是,DoubleStream
不允许我指定要使用的比较器,如果我在流上调用 sorted()
,它只会使用 Double.compareTo
。
因此我将这些值收集到 final Stream.Builder<Double> values = Stream.builder();
中并调用
values.build()
.sorted(Comparator.comparingDouble(Math::abs))
.mapToDouble(a -> a).summaryStatistics();
然而,这看起来有点冗长,我宁愿使用 DoubleStream.Builder
而不是通用构建器。
我是否错过了什么,或者我真的必须使用流的盒装版本才能指定比较器吗?
排序 DoubleStream
的唯一可能方法是 box/unbox 它:
double[] input = //...
DoubleStream.of(input).boxed()
.sorted(Comparator.comparingDouble(Math::abs))
.mapToDouble(a -> a).summaryStatistics();
不过内部使用的是Kahan求和,应该差别不大。在大多数应用程序中,未排序的输入将产生良好的结果精度。当然你应该自己测试未排序的求和是否满足你的特定任务。
原始流没有重载的 sorted
方法,将按自然顺序排序。但回到您的根本问题,有一些方法可以提高总和的准确性,而无需先对数据进行排序。
一种这样的算法是 Kahan summation algorithm which happens to be used by the OpenJDK/Oracle JDK internally。
无可否认,这是一个实现细节,因此适用通常的注意事项(non-OpenJDK/Oracle JDK 或未来的 OpenJDK JDK 可能会采用其他方法等)
另请参阅此 post:In which order should floats be added to get the most precise result?
我有一系列双精度值,我想将它们相加并获得最大值。
DoubleStream.summaryStatistics()
听起来很完美。
getSum()
方法有一个 API 注释提醒我在我的一门计算机科学课程中学到的东西:如果值按绝对值排序,求和问题的稳定性往往会更好。但是,DoubleStream
不允许我指定要使用的比较器,如果我在流上调用 sorted()
,它只会使用 Double.compareTo
。
因此我将这些值收集到 final Stream.Builder<Double> values = Stream.builder();
中并调用
values.build()
.sorted(Comparator.comparingDouble(Math::abs))
.mapToDouble(a -> a).summaryStatistics();
然而,这看起来有点冗长,我宁愿使用 DoubleStream.Builder
而不是通用构建器。
我是否错过了什么,或者我真的必须使用流的盒装版本才能指定比较器吗?
排序 DoubleStream
的唯一可能方法是 box/unbox 它:
double[] input = //...
DoubleStream.of(input).boxed()
.sorted(Comparator.comparingDouble(Math::abs))
.mapToDouble(a -> a).summaryStatistics();
不过内部使用的是Kahan求和,应该差别不大。在大多数应用程序中,未排序的输入将产生良好的结果精度。当然你应该自己测试未排序的求和是否满足你的特定任务。
原始流没有重载的 sorted
方法,将按自然顺序排序。但回到您的根本问题,有一些方法可以提高总和的准确性,而无需先对数据进行排序。
一种这样的算法是 Kahan summation algorithm which happens to be used by the OpenJDK/Oracle JDK internally。
无可否认,这是一个实现细节,因此适用通常的注意事项(non-OpenJDK/Oracle JDK 或未来的 OpenJDK JDK 可能会采用其他方法等)
另请参阅此 post:In which order should floats be added to get the most precise result?