I was given a challenge where the solution involves solving a series of linear modular equations in 14 variables. The following is a selection of these equations:
3a + 3b + 3c + 3d + 3e + 3f + 3g + h + i + j + k + l + m + n = 15
7a + 9b + 17c + 11d + 6e + 5f + g = 3
13a + 2b + 9c + 8d + 12f + 13g = 17
5a + 2b + 16c + 12d + 5e + 7f + g = 11
6a + 4b + 9c + 6d + 4e + 9f + 6g + h + 7i + 11j + k + 7l + 11m + n = 8
10a + 15b + 13c + 10d + 15e + 13f + 10g + 12h + 18i + 8j + 12k + 18l + 8m + 12n = 18
9a + 12b + 14c + 4d + 9e + 16f + 3g + 7h + 17i + 11j + 14k + 3l + 18m + n = 15
9a + 12b + 16c + 15d + e + 14f + 6g + 11h + 2i + 9j + 12k + 16l + 15m + n = 14
I ended up copying them into this modular equation solver to get a parameterized solution. However, I want to be able to do this automatically in a Python program, without depending on that website.
Preferably, I should be able to do this with an arbitrary group of (linear) equations, not just these specific ones. Part of my solution for the challenge required me to write a few different equations for different scenarios, and swap them out as needed.
I'm aware that SymPy has a Diophantine equation solver that almost does what I want it to do, but in the docs I didn't see a way to get it to enforce a certain modulus (mod 19, mod 23, etc).
The word diophantine is misleading here. What you want to do is linear algebra over Z_p meaning the integers modulo a prime p. SymPy can do this if you use DomainMatrix instead of Matrix. This is how to do it in SymPy 1.12:
Now you have dM and db as matrices over Z_17 and you can use whatever matrix operations you want and convert back to Matrix with
to_Matrix:You can use these to construct your parametric solution:
The parametric solution is generated from the particular solution and nullspace:
Let's check that: