Search code examples
pythonnumpyfloating-pointmodulofractions

Modulo with fractions.Fraction class


My aim is to find np.mod(np.array[int], some_number) for a numpy array containing very large integers. Some_number is rational, but in general not an exact decimal fraction. I want to make sure that the modulos are as accurate as possible since I need to bin the results for a histogram in a later step, so any errors due to floating-point precision might mean that values will end up in the wrong bin.

I am aware that the modulo function with floats is limited by floating-point precision, so I am hesitating to use np.mod(array[int], float). I then came across the fractions module of the python library. Can someone give advice as to whether the results obtained via np.mod(np.array[int], Fraction(int1, int2)) would be more accurate than using a float? If not, what is the best approach for such a problem?


Solution

  • So you have a fraction some_number=n/d

    Computing the modulo is like performing this division:

    a = q*(n/d) + (r/d)
    

    the remainder is a fraction with numerator r. It can be written like this:

    a*d = q * n + r
    

    The problem you have is that a*d could overflow. But the problem can be written like this:

    a = q1 * n + r1
    d = q2 * n + r2
    
    a*d = (q1*q2*n+q1*r2+q2*r1) * n + (r1*r2)
    

    given that n/d is between 10 and 100, n>d, q2=0, r2=d, the algorithm is

    1. compute a modulo n => r1
    2. compute (r1*d) modulo n => r
    3. divide r by d => a modulo n/d

    If it's for putting in bins, you don't need step 3.