GithubHelp home page GithubHelp logo

juliamath / kahansummation.jl Goto Github PK

View Code? Open in Web Editor NEW
20.0 8.0 12.0 63 KB

Sum and cumulative sum using the Kahan-Babuska-Neumaier algorithm

License: MIT License

Julia 100.00%
julia math summation kahan-summation

kahansummation.jl's Introduction

KahanSummation.jl

Travis Coveralls

This package provides variants of sum and cumsum, called sum_kbn and cumsum_kbn respectively, using the Kahan-Babuska-Neumaier (KBN) algorithm for additional precision. These functions are typically slower and less memory efficient than sum and cumsum.

These functions were formerly part of Julia's Base library. This package works and is supported.


Examples

julia> using KahanSummation

julia> vec = [1.0, 1.0e16, -1.0e16, -0.5];

julia> sum(vec), sum_kbn(vec)
(-0.5, 0.5)

julia> vec = [1.0, 1.0e16, 1.0, -1.0e16];

julia> cumsum_kbn(vec) .- cumsum(vec)
4-element Array{Float64,1}:
 0.0
 0.0
 2.0
 1.0

see the tests for more examples.

kahansummation.jl's People

Contributors

ararslan avatar dependabot[bot] avatar dilumaluthge avatar fredrikekre avatar goerch avatar inkydragon avatar jeffreysarnoff avatar juliatagbot avatar mortenpi avatar ranocha avatar simonbyrne avatar stevengj avatar timholy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kahansummation.jl's Issues

`sum_kbn` no longer works with general iterators

Commit 132c74b, which closed #4 by adjusting existing type restrictions, also introduced restrictions on the input to sum_kbn. As one example, the following case now fails.

julia> sum_kbn(Iterators.filter(isodd, 1:10))
ERROR: MethodError: no method matching sum_kbn(::Base.Iterators.Filter{typeof(isodd), UnitRange{Int64}})
Closest candidates are:
  sum_kbn(::Union{Base.Generator, StepRange}) at ~/Projects/julia-packages/KahanSummation.jl/src/KahanSummation.jl:90
  sum_kbn(::Union{Tuple{Vararg{Typ, N}}, AbstractArray{Typ}}) where {N, Typ<:Number} at ~/Projects/julia-packages/KahanSummation.jl/src/KahanSummation.jl:70
Stacktrace:
 [1] top-level scope
   @ REPL[8]:1

The function is designed to work generically with any iterable object, which is why it iterates explicitly using iterate rather than relying on indexing. It should be safe to remove those restrictions entirely (with a test based on a type not covered in the current restrictions).

Imprecise summation for Float32

This package can have less precision than the standard sum() on julia-1.7.3. For example:

julia> using KahanSummation

julia> x = rand(Float32, 10_000_000) .+ 1f5;

julia> sum_kbn(x)
9.9479867f11

julia> sum(x)
1.00000504f12

Is this expected?

sum_kbn(f, x)

Might be nice to support some of the same variations as sum, especially the mapreduce-like variant where you pass a function as the first argument.

v0.7 ambiguity

julia> using  KahanSummation; sum_kbn = KahanSummation.sum_kbn;
...
julia> ints = [rand(Int64) for i in 1:10_000];
julia> bigints = map(BigInt, ints);
...
julia> ints_sum, bigints_sum = sum_kbn(ints), sum_kbn(bigints);
ERROR: MethodError: zero(::Type{Union{}}) is ambiguous. Candidates:
  zero(::Union{Type{P}, P}) where P<:Dates.Period in Dates at /home/jas/Public/julia/julia/usr/share/julia/site/v0.7/Dates/src/periods.jl:44
  zero(::Type{T}) where T<:SafeUnsigned in SaferIntegers at /home/jas/.julia/v0.7/SaferIntegers/src/int_ops.jl:8
  zero(::Type{T}) where T<:SafeSigned in SaferIntegers at /home/jas/.julia/v0.7/SaferIntegers/src/int_ops.jl:8
Possible fix, define
  zero(::Type{Union{}})
Stacktrace:
 [1] sum_kbn(::Array{Int64,1}) at /home/jas/.julia/v0.7/KahanSummation/src/KahanSummation.jl:96
 [2] top-level scope

sum_kbn requires too many allocations

Here's a quick example:

julia> using BenchmarkTools,KahanSummation

julia> y = rand(10_000);

julia> include("my_sum_kbn.jl")
my_sum_kbn (generic function with 1 method)

julia> @btime sum_kbn(y)
  621.360 μs (39488 allocations: 929.47 KiB)
4948.622651455085

julia> @btime my_sum_kbn(y)
  27.639 μs (3 allocations: 78.22 KiB)
4948.622651455085

julia> sum_kbn(y)-my_sum_kbn(y)
0.0

julia> sum_kbn(y)==my_sum_kbn(y)
true

my_sum_kbn.jl is this:

function my_sum_kbn(A)
    T = Base.@default_eltype(A)
    c = Base.reduce_empty(+, T)
    isempty(A) && return c
    s = A[1]
    for Ai in A[2:end]
        t = s + Ai
        if abs(s) >= abs(Ai)
            c -= ((s-t) + Ai)
        else
            c -= ((Ai-t) + s)
        end
        s = t
    end
    s - c
end

I am not sure the old (start,next,done) used to be allocate similarly (?). So posting this here meanwhile -- though this might be an issue for the iterate function

additional functionality

Part of my reason for #7 was to make it easier to extend. Some other functions we should provide:

  • dot_kbn: compute the dot-products using double-double, then sum up using Kahan summation
  • mean_kbn: divide the extended-precision sum using a 2-div style, so that mean_kbn(fill(0.1,10)) == 0.1

TagBot trigger issue

This issue is used to trigger TagBot; feel free to unsubscribe.

If you haven't already, you should update your TagBot.yml to include issue comment triggers.
Please see this post on Discourse for instructions and more details.

If you'd like for me to do this for you, comment TagBot fix on this issue.
I'll open a PR within a few hours, please be patient!

cumsum_kbn signature is too restrictive

The signature cumsum_kbn(v::AbstractVector{T}) where T<:AbstractFloat seems too restrictive. What about summing Complex{Float64} or SVector{Float64,3}, for example?

sum_kbn accepts any type, which seems more reasonable. (If you pass something like an array of integers, it will still work, just wasting some computations.)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.