math.extras: adding a more exact sum for floats.
parent
972fa0fbab
commit
aaabe0a142
|
|
@ -130,6 +130,9 @@ tools.test ;
|
||||||
{ { 0 1 2 3 0 0 1 } } [ { 1 2 3 3 2 1 2 } [ <= ] monotonic-count ] unit-test
|
{ { 0 1 2 3 0 0 1 } } [ { 1 2 3 3 2 1 2 } [ <= ] monotonic-count ] unit-test
|
||||||
{ 4 } [ { 1 2 3 1 2 3 4 5 } [ < ] max-monotonic-count ] unit-test
|
{ 4 } [ { 1 2 3 1 2 3 4 5 } [ < ] max-monotonic-count ] unit-test
|
||||||
|
|
||||||
|
{ 4.0 } [ { 1e-30 1 3 -1e-30 } sum-floats ] unit-test
|
||||||
|
{ 1.0000000000000002e16 } [ { 1e-16 1 1e16 } sum-floats ] unit-test
|
||||||
|
|
||||||
{ 2470 } [ 20 <iota> sum-squares ] unit-test
|
{ 2470 } [ 20 <iota> sum-squares ] unit-test
|
||||||
{ 2470 } [ 20 <iota> >array sum-squares ] unit-test
|
{ 2470 } [ 20 <iota> >array sum-squares ] unit-test
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -290,6 +290,53 @@ PRIVATE>
|
||||||
[ 0.0 0.0 ] 2dip [ 2dip rot kahan+ ] curry
|
[ 0.0 0.0 ] 2dip [ 2dip rot kahan+ ] curry
|
||||||
[ -rot ] prepose each nip ; inline
|
[ -rot ] prepose each nip ; inline
|
||||||
|
|
||||||
|
<PRIVATE
|
||||||
|
|
||||||
|
! Adaptive Precision Floating-Point Arithmetic and Fast Robust Geometric Predicates
|
||||||
|
! www-2.cs.cmu.edu/afs/cs/project/quake/public/papers/robust-arithmetic.ps
|
||||||
|
|
||||||
|
: sort-partial ( x y -- x' y' )
|
||||||
|
2dup [ abs ] bi@ < [ swap ] when ; inline
|
||||||
|
|
||||||
|
:: partial+ ( x y -- hi lo )
|
||||||
|
x y + dup x - :> yr y yr - ; inline
|
||||||
|
|
||||||
|
:: partial-sums ( seq -- seq' )
|
||||||
|
V{ } clone :> partials
|
||||||
|
seq [
|
||||||
|
0 partials [
|
||||||
|
swapd sort-partial partial+ swapd
|
||||||
|
[ over partials set-nth 1 + ] unless-zero
|
||||||
|
] each :> i
|
||||||
|
i partials shorten
|
||||||
|
[ i partials set-nth ] unless-zero
|
||||||
|
] each partials ;
|
||||||
|
|
||||||
|
:: sum-exact ( partials -- n )
|
||||||
|
partials empty? [ 0.0 ] [
|
||||||
|
! sum from the top, stop when sum becomes inexact
|
||||||
|
0.0 0.0 partials [
|
||||||
|
nip partial+ dup 0.0 = not
|
||||||
|
] find-last drop :> ( lo n )
|
||||||
|
|
||||||
|
! make half-even rounding work across multiple partials
|
||||||
|
n [ 0 > ] [ f ] if* [
|
||||||
|
n 1 - partials nth
|
||||||
|
[ 0.0 < lo 0.0 < and ]
|
||||||
|
[ 0.0 > lo 0.0 > and ] bi or [
|
||||||
|
lo 2.0 * :> y
|
||||||
|
dup y + :> x
|
||||||
|
x over - :> yr
|
||||||
|
y yr = [ drop x ] when
|
||||||
|
] when
|
||||||
|
] when
|
||||||
|
] if ;
|
||||||
|
|
||||||
|
PRIVATE>
|
||||||
|
|
||||||
|
: sum-floats ( seq -- n )
|
||||||
|
partial-sums sum-exact ;
|
||||||
|
|
||||||
! SYNTAX: .. dup pop scan-object [a,b) suffix! ;
|
! SYNTAX: .. dup pop scan-object [a,b) suffix! ;
|
||||||
! SYNTAX: ... dup pop scan-object [a,b] suffix! ;
|
! SYNTAX: ... dup pop scan-object [a,b] suffix! ;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue