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
Copy file name to clipboardExpand all lines: src/algebra/module-inverse.md
+26-29Lines changed: 26 additions & 29 deletions
Original file line number
Diff line number
Diff line change
@@ -76,45 +76,42 @@ From these results, we can easily find the modular inverse using the [binary exp
76
76
77
77
Even though this method is easier to understand than the method described in previous paragraph, in the case when $m$ is not a prime number, we need to calculate Euler phi function, which involves factorization of $m$, which might be very hard. If the prime factorization of $m$ is known, then the complexity of this method is $O(\log m)$.
78
78
79
-
## Finding the modular inverse for every number modulo $m$ { #mod-inv-all-num data-toc-label="Finding the modular inverse for every number modulo m"}
79
+
## Finding the modular inverse using Euclidean Division
80
80
81
-
The problem is the following:
82
-
we want to compute the modular inverse for every number in the range $[1, m-1]$.
81
+
Given that $m > i$ (or we can modulo to make it smaller in 1 step), according to [Euclidean Division](https://en.wikipedia.org/wiki/Euclidean_division)
83
82
84
-
Applying the algorithms described in the previous sections, we can obtain a solution with complexity $O(m \log m)$.
83
+
$$m = k \cdot i + r$$
85
84
86
-
Here we present a better algorithm with complexity $O(m)$.
87
-
However for this specific algorithm we require that the modulus $m$ is prime.
85
+
where $k = \left\lfloor \frac{m}{i} \right\rfloor$ and $r = m \bmod i$, then
88
86
89
-
We denote by $\text{inv}[i]$ the modular inverse of $i$. Then for $i > 1$ the following equation is valid:
From there we can have the following recursive function (in C++) for computing the modular inverse for number $i$ with respect to module $m$
94
97
95
-
```cpp
96
-
inv[1] = 1;
97
-
for(int i = 2; i < m; ++i)
98
-
inv[i] = m - (m/i) * inv[m%i] % m;
98
+
```{.cpp file=modular_inverse_euclidean_division}
99
+
intinv(int i) {
100
+
return i <= 1 ? i : m - (long long)(m/i) * inv(m % i) % m;
101
+
}
99
102
```
100
103
101
-
### Proof
102
-
103
-
We have:
104
+
The exact time complexity of the this recursion is not known. It's is somewhere between $O(\frac{\log m}{\log\log m})$ and $O(n^{\frac{1}{3} - \frac{2}{177} + \epsilon})$.
105
+
See [On the length of Pierce expansions](https://arxiv.org/abs/2211.08374).
106
+
In practice this implementation is fast, e.g. for the modulus $10^9 + 7$ it will always finish in less than 50 iterations.
104
107
105
-
$$m \bmod i = m - \left\lfloor \frac{m}{i} \right\rfloor \cdot i$$
108
+
Applying this formula, we can also precompute the modular inverse for every number in the range $[1, m-1]$ in $O(m)$.
106
109
107
-
Taking both sides modulo $m$ yields:
108
-
109
-
$$m \bmod i \equiv - \left\lfloor \frac{m}{i} \right\rfloor \cdot i \mod m$$
110
-
111
-
Multiply both sides by $i^{-1} \cdot (m \bmod i)^{-1}$ yields
0 commit comments