You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@eval (Base.$op)(i::Mod{M}, j::Mod{M}) where {M} =Mod{M}($op(Int(i), Int(j)))
we see that Int overflow can happen before the modulo operation % is applied, which leads to incorrect results:
using Ripserer, Primes
p=9223372036854775783
print(isprime(p))
x, y = Mod{p}(p-1), Mod{p}(p-2)
(x+y).value, p-3 # we see these are different, even though they should be equal: (p-1)+(p-2) ≡ 2p-3 ≡ p-3 (mod p)
The current implementation of + and * operations gives a correct result when 1<p<sqrt(typemax(Int)), as this inequality makes sure that no overflow happens. Perhaps you could add this assertion somewhere in your code.
Otherwise, a better implementation of integers modulo m can be found in this issue of mine.
Does the original Ripser in C++ have such an implementation of integers modulo m? Would you be so kind and point me to the line in code where I could find this?
The text was updated successfully, but these errors were encountered:
Nice catch thanks! I always assumed people will use integers modulo a small number (maybe up to 17 or so), so integer overflow never even crossed my mind.
I wasn't aware of the Mods package. I'll check to see how fast it is for my specific usecase. It would be good to depend on a high quality implementation rather than rolling my own.
In the meantime, ripserer should work fine with coefficients from that package. You can run it that way by providing the field keyword to it.
Regarding the Mods package, its performance is slow. I benchmarked my implementation with several others in the issue, and my simple code proved to be much faster than the others. Feel free to use my implementation.
In source code
Ripserer.jl/src/base/primefield.jl
Line 75 in 3f2d63f
Int
overflow can happen before the modulo operation%
is applied, which leads to incorrect results:The current implementation of
+
and*
operations gives a correct result when1<p<sqrt(typemax(Int))
, as this inequality makes sure that no overflow happens. Perhaps you could add this assertion somewhere in your code.Otherwise, a better implementation of integers modulo
m
can be found in this issue of mine.Does the original Ripser in C++ have such an implementation of integers modulo m? Would you be so kind and point me to the line in code where I could find this?
The text was updated successfully, but these errors were encountered: