Is there an efficient implementation of double factorial somewhere?

Hey friends, is there an efficient implementation of double factorial somewhere? I implemented this one (any tips on improving its performance are welcome):

function doublefactorial(number)
    fact = one(number)
    if number % 2 == 0
        for m = 1:number
            if m % 2 == 0
                fact *= m
            end
        end
    elseif number % 2 == 1
        for m = 1:number
            if m % 2 == 1
                fact *= m
            end
        end
    end

    return fact
end
1 Like

I don’t think you need to worry too much about performance here — if you’re using Int64s, this will overflow in 33 operations! But here’s a slight simplification:

function doublefactorial(number)
    fact = one(number)
    for m in iseven(number)+1:2:number
        fact *= m
    end
    return fact
end

Optimization would really only matter if you’re talking about BigInts — and then you’d have to delve into GMP internals to really do anything of note.

If you hate typing:

using Base.Iterators
function df2(n)
    foldl(Base.:*, range(n, 1, step=-2))
end
1 Like

Of course, it’s df3(n) = prod(n:-2:1)! Even better, it looks like Base already has the GMP-internals optimizations you’d want here. :slight_smile:

5 Likes

(This is a classic case where declaring the argument as number::Integer is a good idea, since otherwise it will silently given the wrong result for non-integer inputs like 1.5.)

4 Likes