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/chinese-remainder-theorem.md
+8-138Lines changed: 8 additions & 138 deletions
Original file line number
Diff line number
Diff line change
@@ -209,149 +209,19 @@ It has the solution $53 \pmod{60}$, and indeed $53 \bmod{10} = 3$ and $53 \bmod{
209
209
210
210
## Garner's Algorithm
211
211
212
-
Another consequence of the CRT is that we can represent big numbers using an array of small integers. For example, let $p$ be the product of the first $1000$ primes. From calculations we can see that $p$ has around $3000$ digits.
212
+
Another consequence of the CRT is that we can represent big numbers using an array of small integers.
213
213
214
-
Any number $a$ less than $p$ can be represented as an array $a_1, \ldots, a_k$, where $a_i \equiv a \pmod{p_i}$. But to do this we obviously need to know how to get back the number $a$ from its representation. In this section, we discuss Garner's Algorithm, which can be used for this purpose. We seek a representation on the form
214
+
Instead of doing a lot of computations with very large numbers numbers, which might be expensive (think of doing divisions with 1000-digit numbers), you can pick a couple of coprime moduli and represent the large number as a system of congruences, and perform all operations on the system of equations.
215
+
Any number $a$ less than $m_1 m_2 \cdots m_k$ can be represented as an array $a_1, \ldots, a_k$, where $a \equiv a_i \pmod{m_i}$.
which can be found using the algorithm described in [Modular Inverse](module-inverse.md). Substituting $a$ from the mixed radix representation into the first congruence equation we obtain
226
-
227
-
$$a_1 \equiv x_1 \pmod{p_1}.$$
228
-
229
-
Substituting into the second equation yields
230
-
231
-
$$a_2 \equiv x_1 + x_2 p_1 \pmod{p_2}.$$
232
-
233
-
which can be rewritten by subtracting $x_1$ and dividing by $p_1$ to get
It is worth noting that in practice, we almost always need to compute the answer using Big Integers, but the coefficients $x_i$ can usually be calculated using built-in types, and therefore Garner's algorithm is very efficient.
265
-
266
-
## Implementation of Garner's Algorithm
267
-
268
-
It is convenient to implement this algorithm using Java, because it has built-in support for large numbers through the `BigInteger` class.
269
-
270
-
Here we show an implementation that can store big numbers in the form of a set of congruence equations.
271
-
It supports addition, subtraction and multiplication.
272
-
And with Garner's algorithm we can convert the set of equations into the unique integer.
273
-
In this code, we take 100 prime numbers greater than $10^9$, which allows numbers as large as $10^{900}$.
BigInteger result =BigInteger.ZERO, mult =BigInteger.ONE;
330
-
int x[] =newint[SZ];
331
-
for (int i =0; i <SZ; ++i) {
332
-
x[i] = a[i];
333
-
for (int j =0; j < i; ++j) {
334
-
long cur = (x[i] - x[j]) *1l* r[j][i];
335
-
x[i] = (int)((cur % pr[i] + pr[i]) % pr[i]);
336
-
}
337
-
result = result.add(mult.multiply(BigInteger.valueOf(x[i])));
338
-
mult = mult.multiply(BigInteger.valueOf(pr[i]));
339
-
}
340
-
341
-
if (can_be_negative)
342
-
if (result.compareTo(mult.shiftRight(1)) >=0)
343
-
result = result.subtract(mult);
344
-
345
-
return result;
346
-
}
347
-
}
348
-
```
349
-
350
-
### Note on negative numbers
351
-
352
-
* Let $p$ be the product of all primes.
353
-
354
-
* Modular scheme itself does not allow representing negative numbers. However, it can be seen that if we know that the absolute values our numbers are smaller than $p / 2$, then we know that it must be negative when the resulting number is greater than $p / 2$. The flag `can_be_negative` in this code allows converting it to negative in this case.
223
+
Garner's algorithm, which is discussed in the dedicated article [Garner's algorithm](garners-algorithm.md), computes the coefficients $x_i$.
224
+
And with those coefficients you can restore the full number.
A mixed radix representation is a positional numeral system, that's a generalization of the typical number systems, like the binary numeral system or the decimal numeral system.
19
+
For instance the decimal numeral system is a positional numeral system with the radix (or base) 10.
20
+
Every a number is represented as a string of digits $d_1 d_2 d_3 \dots d_n$ between $0$ and $9$, and
21
+
E.g. the string $415$ represents the number $4 \cdot 10^2 + 1 \cdot 10^1 + 5 \cdot 10^0$.
22
+
In general the string of digits $d_1 d_2 d_3 \dots d_n$ represents the number $d_1 b^{n-1} + d_2 b^{n-2} + \cdots + d_n b^0$ in the positional numberal system with radix $b$.
23
+
24
+
In a mixed radix system, we don't have one radix any more. The base varies from position to position.
25
+
26
+
## Garner's algorithm
27
+
28
+
Garner's algorithm computes the digits $x_1, \ldots, x_k$.
29
+
Notice, that the digits are relatively small.
30
+
The digit $x_i$ is an integer between $0$ and $p_i - 1$.
31
+
32
+
Let $r_{ij}$ denote the inverse of $p_i$ modulo $p_j$
33
+
34
+
$$r_{ij} = (p_i)^{-1} \pmod{p_j}$$
35
+
36
+
which can be found using the algorithm described in [Modular Inverse](module-inverse.md).
37
+
38
+
Substituting $a$ from the mixed radix representation into the first congruence equation we obtain
39
+
40
+
$$a_1 \equiv x_1 \pmod{p_1}.$$
41
+
42
+
Substituting into the second equation yields
43
+
44
+
$$a_2 \equiv x_1 + x_2 p_1 \pmod{p_2},$$
45
+
46
+
which can be rewritten by subtracting $x_1$ and dividing by $p_1$ to get
It is worth noting that in practice, we almost probably need to compute the answer $a$ using [Arbitrary-Precision Arithmetic](big-integer.md), but the digits $x_i$ (because they are small) can usually be calculated using built-in types, and therefore Garner's algorithm is very efficient.
78
+
79
+
## Implementation of Garner's Algorithm
80
+
81
+
It is convenient to implement this algorithm using Java, because it has built-in support for large numbers through the `BigInteger` class.
82
+
83
+
Here we show an implementation that can store big numbers in the form of a set of congruence equations.
84
+
It supports addition, subtraction and multiplication.
85
+
And with Garner's algorithm we can convert the set of equations into the unique integer.
86
+
In this code, we take 100 prime numbers greater than $10^9$, which allows representing numbers as large as $10^{900}$.
0 commit comments