In source code
|
@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?
In source code
Ripserer.jl/src/base/primefield.jl
Line 75 in 3f2d63f
Intoverflow 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
mcan 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?