I want to calculate the product of two quantities A and B and then compute the product modulo F. In general, A and B are matrices with large numbers so the operation is the conventional matrix multiplication. Let's consider for simplicity A and B as scalars. The Python code with all the methods I have tested is the following:
from __future__ import division
import numpy as np
from sympy import Matrix
from sympy import *
A = 2251875000001
B = 28839630
F = 33232924804801
#Method 1: pure Python
C1 = (A*B) % F
A_mat = np.matrix(A).astype(np.int64)
B_mat = np.matrix(B).astype(np.int64)
#Method 2: numpy matrices and pure Python
C2 = (A_mat*B_mat) % F
#Method 3: numpy
C3 = np.dot(A, B) % F
#Method 4: numpy
C4 = np.dot(A_mat, B_mat) % F
#Method 5: Python objects and numpy
A_mat2 = np.matrix(A, dtype=object)
B_mat2 = np.matrix(B, dtype=object)
C5 = np.dot(A_mat2, B_mat2) % F
C5 = np.concatenate(C5).astype(np.int64)
#Method 6: sympy
A_sp = Matrix(1,1,[A])
B_sp = Matrix(1,1,[B])
C6 = A_sp*B_sp
f = lambda x: x%F
C6 = C6.applyfunc(f)
print(C6)
C6 = matrix2numpy(C6, dtype='int64')
Now the result should be
(2251875000001 * 28839630) mod 33232924804801 = 25112458407047
When I run the above code what I get for C1 == 25112458407047
is correct for this example, but when I test multiplication of large matrices most of the entries I am getting with this method are wrong. However, the values of C2
, C3
, C4
all equal to 12062945446480
which is wrong. C5
and C6
are also calculated correctly.
You can assume that 64bit precision of int64
is more than enough for the numbers I am working with, but the default 32bit is not.
I tried Sympy (see method 6) since it's supposed to have arbitrary precision according to here.
I am using Python 2.7.14, Numpy 1.14.2 and Sympy 1.1.1.
My first question is why do I get some of the results wrong in the above code?
Finally, methods 5 and 6 even though they are always correct, they seem to be slower than the other methods. Can you explain that? How do the above methods differ in terms of complexity of matrix multiplication and what do you suggest?
EDIT
I thought this should be clear from the functions I use in the code, but anyway, the operation I am interested in is conventional matrix multiplication. Also, I apologize for the fact that my example was actually an overflow, but the question of performance is still valid.