Actions

## Feature #10298

closed

### Array#float_sum (like math.fsum of Python)

Status:
Rejected
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-dev:48579]

Description

Here, I propose Array#float_sum in array.c (or math.c).
Array#float_sum returns an accurate total summation of Float
elements in an array using the Kahan summation algorithm
http://en.wikipedia.org/wiki/Kahan_summation_algorithm .
This algorithm can significantly reduce the numerical
error in the total obtained by adding a sequence of
finite precision floating point numbers, compared to the
obvious approach. Python already have math.fsum
https://docs.python.org/2/library/math.html#math.fsum .

``````[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1].float_sum   #=> 1.0
[].float_sum                                                   #=> 0.0
Array.new( 10, 0.1).float_sum    #=>  1.0
Array.new(100, 0.1).float_sum    #=> 10.0
# cf.
Array.new( 10, 0.1).reduce(:+)   #=>  0.9999999999999999
Array.new(100, 0.1).reduce(:+)   #=>  9.99999999999998
``````

The name of method can be fsum, sum_float, etc., though
I propose float_sum.

This Array#float_sum is inspired by Feature #9834 Float#{next_float,prev_float}.

Files

Related issues 1 (0 open1 closed)

 Related to Ruby master - Feature #12217: Introducing Enumerable#sum for precision compensated summation and revert r54237 Closed mrkn (Kenta Murata) Actions

#### Updated by t-nissie (Takeshi Nishimatsu)over 7 years ago

Timing.
Of course it is fast.

``````\$ uname -sprsv
Darwin 13.3.0 Darwin Kernel Version 13.3.0: Tue Jun  3 21:27:35 PDT 2014; root:xnu-2422.110.17~1/RELEASE_X86_64 i386
\$ sysctl -n machdep.cpu.brand_string
Intel(R) Core(TM) i5-3210M CPU @ 2.50GHz
\$ ./miniruby --version
ruby 2.2.0dev (2014-09-29 trunk 47735) [x86_64-darwin13]
\$ /usr/bin/time ./miniruby -e 'p Array.new(10000000,0.1).reduce(:+)'
999999.9998389754
0.66 real         0.62 user         0.03 sys
\$ /usr/bin/time ./miniruby -e 'sum=0.0; c=0.0; Array.new(10000000,0.1).each{|x|y=x-c; t=sum+y; c=(t-sum)-y; sum=t}; p sum'
1000000.0
1.47 real         1.44 user         0.02 sys
\$ /usr/bin/time ./miniruby -e 'p Array.new(10000000, 0.1).float_sum'
1000000.0
0.10 real         0.06 user         0.03 sys

``````

#### Updated by akr (Akira Tanaka)over 7 years ago

It is not fit to Array class because Array is not only for Float.

I think it is better to implement it as an optimization of reduce(:+).

#### Updated by akr (Akira Tanaka)over 7 years ago

• Status changed from Open to Feedback

https://github.com/nobu/ruby/compare/Feature%2310298-float_sum

It doesn't improve the performance as `Array.float_sum`, though.

#### Updated by t-nissie (Takeshi Nishimatsu)over 7 years ago

Thank you for the quick patch for enum.c.

Timing and test.
I see. performance is not improved.

``````\$ uname -sprsv
Darwin 13.3.0 Darwin Kernel Version 13.3.0: Tue Jun  3 21:27:35 PDT 2014; root:xnu-2422.110.17~1/RELEASE_X86_64 i386
\$ sysctl -n machdep.cpu.brand_string
Intel(R) Core(TM) i5-3210M CPU @ 2.50GHz
\$ ./miniruby --version
ruby 2.2.0dev (2014-10-15 trunk 47735) [x86_64-darwin13]
\$ /usr/bin/time ./miniruby -e 'p Array.new(10000000,0.1).reduce(:+)'
999999.9998389754
0.69 real         0.65 user         0.03 sys
\$ mv optimized/enum.c .
\$ make -j2 miniruby
compiling enum.c
\$ /usr/bin/time ./miniruby -e 'p Array.new(10000000,0.1).reduce(:+)'
1000000.0
0.55 real         0.51 user         0.04 sys
\$ ./miniruby -e 'p Array.new(10000000,0.1).unshift(0.0).reduce(:-)'
-1000000.0
``````

I understand that Array is not only for Float.

``````\$ ./miniruby -e '[1,2,3].float_sum'
-e:1: [BUG] Segmentation fault at 0x00000000000013
``````
Actions #6

#### Updated by akr (Akira Tanaka)about 6 years ago

• Related to Feature #12217: Introducing Enumerable#sum for precision compensated summation and revert r54237 added

#### Updated by akr (Akira Tanaka)over 5 years ago

• Status changed from Feedback to Rejected

Ruby 2.4 implements Array#sum and Enumerable#sum.

Actions

Also available in: Atom PDF