Modular congruence: Difference between revisions

From LifeWiki
Jump to navigation Jump to search
Confocal (talk | contribs)
+
m fix leading sentence's grammar (copied mistakenly), note coprimeness requirement for Euler's theorem and alternative version of Fermat's little theorem
 
(5 intermediate revisions by 3 users not shown)
Line 1: Line 1:
{{stub}}{{Glossary}}
{{cleanup}}{{Glossary}}
Two numbers <tt>a,b</tt> are '''congruent''' modulo a third number <tt>n</tt> if their values are equal when integer multiples of <tt>n</tt> are added or subtracted from them such that they both lie in the range <tt>0<=x<n</tt> (an operation denoted with the <tt>%</tt> symbol).<ref group="n">When either operand is negative, programming languages' implementations differ in convention. Python ensures that the sign of the output matches that of the second input (the 'modulo base'), ie. <tt>0>=x%n>n</tt> if n is negative, to make <tt>x//n*n+x%n=x</tt> hold, because Python's floordiv operator <tt>//</tt> rounds towards <tt>-∞</tt>, whereas C matches the first, ie. <tt>-4%3=-1</tt>, because its integer division operator, <tt>/</tt>, returns integers but rounds towards <tt>0</tt>, this article will use the Python convention for signed modulo.</ref> A function returning the value of <tt>x</tt> modulo <tt>n</tt> is given in most programming languages with the <tt>%</tt> operator (ie. <tt>x%n</tt>), and according to the C specification (followed by languages like Python), modulo has the same precedence as multiplication and division, and expressions involving multiple of the same precedence adjacent without brackets will be evaluated left-to-right.<ref group="n">Without modulo or floordiv (only multiplication and division), this is equivalent to division being evaluated before multiplication, as is taught in schools.</ref>


Such equalities under the modulo operation are denoted as <tt>a≡b (mod n)</tt>. For instance, <tt>5≡8 (mod 3)</tt>, because both of them (after multiples of <tt>3</tt> are subtracted) evaluate to <tt>2</tt>. Alternatively (for integer modulo bases <tt>n</tt>), <tt>x%n</tt> is equivalent to taking <tt>x</tt>'s expansion in base <tt>n</tt> and truncating the digits with greater place value than <tt>1</tt>. Modular arithmetic is generally concerned with the behaviour of operations under the modulo operation with a fixed base.
Let <tt>p%q = p-⌊{{frac|p|q}}⌋*q</tt> ("<tt>p</tt> modulo <tt>q</tt>"), ie. adding or subtracting integer multiples of <tt>q</tt> to <tt>p</tt> such that it lies in the range <tt>0 &le; x < q</tt>.<ref group="n">Note that for <tt>p &ne; 0</tt>, this causes <tt>sgn(p%q) = sgn(q)</tt>, to make <tt>⌊{{frac|p|q}}⌋*q+p%q=p</tt> hold, as in Python. In other programming languages such as C, <tt>p%q = |p-⌊{{frac|p|q}}⌋*q|*sgn(p)</tt>, so ie. <tt>-4%3=-1</tt>, since its integer integer division operator, <tt>/</tt>, rounds towards <tt>0</tt> instead of <tt>-∞</tt>. In most programming languages, modulo has the same precedence as multiplication and division, and expressions involving multiple of the same precedence adjacent without brackets are evaluated left-to-right.</ref>


Additional arithmetic rules allow manipulation of expressions involving modulo operations, such as that <tt>x*y%n=(x%n)*(y%n)%n</tt>, with which many computations involving modulo operators can be evaluated more efficiently than explicitly, such as [https://en.wikipedia.org/wiki/Modular_exponentiation modular exponentiation], where calculating <tt>x**p%n</tt> allows you to "unravel" the exponentiation into a series of multiplications, and modulo the result by <tt>n</tt> with each successive multiplication.
Two numbers <tt>a,b</tt> are '''congruent''' modulo a third number <tt>n</tt> {{iff}} <tt>a%n = b%n</tt>.


Beginning with integers <tt>n</tt> and <tt>x</tt> (such that <tt>0<=x<n</tt>) and recursively adding an integer <tt>k</tt> to <tt>x</tt> and modulo'ing by <tt>n</tt> (ie. setting <tt>x=(x+k)%n</tt>) will cause <tt>x</tt>'s value to oscillate with period <tt>n/gcd(n,k)</tt> (equivalently <tt>lcm(n,k)/k</tt>).
Such congruences are denoted as <tt>a ≡ b (mod n)</tt>. For instance, <tt>5 ≡ 8 (mod 3)</tt>, because <tt>5%3 = 5-3 = 8%3 = 8-6 = 2</tt>. Alternatively (for integer modulo bases <tt>n</tt>), <tt>x%n</tt> is equivalent to taking <tt>x</tt>'s expansion in base <tt>n</tt> and removing all but the last digit. Modular arithmetic is generally concerned with the behaviour of operations under modulo by a fixed base.


For a modulo base <tt>n</tt> and period <tt>p</tt>, for there to exist any integers <tt>k</tt> such that recursive addition of <tt>k</tt> has period <tt>p</tt>, <tt>p</tt> must be a factor of <tt>n</tt> (meaning <tt>n%p=0</tt>). These integers <tt>k</tt> are then the set of those <tt>0<k<p</tt> coprime to <tt>p</tt>, each multiplied by <tt>n/p</tt>. The number of such values <tt>k</tt> is then given by <tt>phi(p)</tt>, where <tt>phi</tt> is [https://en.wikipedia.org/wiki/Euler's_totient_function Euler's totient function], {{OEIS|A000010}}.<ref group="n">These can be tabulated by running <tt>print((lambda m: (lambda f: '\n'.join(map(lambda n: 'n='+f(m,n)+': (\n '+',\n '.join(map(lambda p: p[1],filter(lambda p: p[0],map(lambda p: (lambda t: (len(t),'p='+f(m,p)+': ('+','.join(map(str,t))+')'))(tuple(filter(lambda k: n//__import__('math').gcd(n,k)==p,range(n)))),range(1,n+1)))))+')',range(m))))(lambda n,k: ' '*(len(str(n))-len(str(k)))+str(k)))(16))</tt> in the Python terminal. The lengths of the tuples, over all values of <tt>p</tt> (instead of only nonzero ones), is the triangular array {{OEIS|A054522}}.</ref>
Given fixed integers <tt>k,x &ne; 0</tt>, the sequence <tt>a(i) = i*k % n</tt> oscillates, with period <tt>{{frac|n|gcd(n,k)}} = {{frac|lcm(n,k)|k}}</tt>.


There is no similar such statement about modular integer multiplication by a constant, because unlike addition of a constant, the structure of its mapping is not invariant across all inputs.<ref group="n">Also, it is neither injective (such that all numbers <tt>0<=x<n</tt> produce unique values under multiplication by <tt>k</tt> followed by modulo by <tt>n</tt>) nor surjective (such that for given <tt>n,k</tt> every value <tt>y</tt> can have an <tt>x</tt> found such that <tt>k*x%n=y</tt>). An injective function with a range of outputs equal to that of its inputs (like modular addition of a constant) is also surjective, and together they are bijective, meaning an inverse function can be defined. Modular multiplicative inverses (ie. a number <tt>y</tt> such that <tt>x*y%n=1</tt>) can be defined where <tt>x</tt> and <tt>n</tt> are coprime, and is implemented in Python's three-argument [https://docs.python.org/3/library/functions.html#pow <tt>pow</tt>] function.</ref> Due to this, similarly to cellular automata in finite planes as functions on the set of states, recursively applying a multiplication will cause integers to eventually enter one of several cycles, upon which the period depends.<ref group="n">An equivalent program to the previous one (for the cycle obtained by beginning at <tt>x=1</tt>) is <tt>print((lambda m: (lambda f: '\n'.join(map(lambda n: 'n='+f(m,n)+': ('+','.join((lambda t: map(lambda p: f(m,t.count(p)),range(1,n)))(tuple(map(lambda k: (lambda f: f(f))(lambda f: lambda r,t: (lambda r: t.index(r)+1 if r in t else f(f)(r,(r,)+t))(k*r%n))(1,()),range(1,n)))))+')',range(1,m))))(lambda n,k: ' '*(len(str(n))-len(str(k)))+str(k)))(16))</tt>, which generates {{OEIS|A057593}},{{br}}and the number of cycles counting by <tt>print((lambda m: (lambda f: '\n'.join(map(lambda n: 'n='+f(m,n)+': '+','.join(map(lambda k: f(m,(lambda f: f(f))(lambda f: lambda c,i,o,p: (lambda o: o if all(c) else f(f)(c,c.index(0),o,p+1))(o+(c[i]==p)) if c[i] else f(f)(c[:i]+(p,)+c[i+1:],k*i%n,o,p))((0,)*n,0,0,1)),range(n+1))),range(1,m))))(lambda n,k: ' '*(len(str(n))-len(str(k)))+str(k)))(24))</tt> (removing the <tt>k=0</tt> column returns {{OEIS|A348888}}, which has [https://oeis.org/A348888/a348888.pdf a nice diagram] showing the cycles formed by different <tt>n,k</tt>).</ref> Implementations of modular exponentiation to large powers with small modulo bases can be further optimised by detecting the length of the cycle that an exponentiation process enters and finding the phase that it ends in by taking the remaining exponent (upon entry to the cycle) modulo this length, and using it as the index in the cycle.
For a modulo base <tt>n</tt> and period <tt>p</tt>, for there to exist any integers <tt>k</tt> with sequences of period <tt>p</tt>, <tt>p</tt> must be a divisor of <tt>n</tt> (written <tt>p|n</tt>). The number of <tt>k</tt> whose addition has period <tt>p</tt> is
:<tt>#({k: k ∈ ℕ and k<n and {{frac|n|gcd(n,k)}}=p}) = { <span style="display:inline-grid;vertical-align:middle"><span>φ(p)<font style="opacity:0"> . </font>p|n</span><span>0<font style="opacity:0"> . . .</font>else</span></span></tt>
where <tt>φ(p)</tt> is {{LinkWikipedia|Euler's_totient_function|name=Euler's totient function|nobullet=no|nosuffix=no}}, the number of <tt>1 ≤ k < p</tt> such that <tt>gcd(p,k)=0</tt> (<tt>{{OEIS|A000010|tt=tt}}</tt>).<ref group="n">These can be tabulated by running <tt>print('\n'.join(map(λ n: 'n='+f(m,n)+': (\n '+',\n '.join(map(λ p: p[1],filter(λ p: p[0],map(λ p: (λ t: (len(t),'p='+f(m,p)+': ('+','.join(map(str,t))+')'))(tuple(filter(λ k: n//gcd(n,k)==p,range(n)))),range(1,n+1)))))+')',range(m:=16))))</tt> in the Python terminal. The lengths of the tuples, over all values of <tt>p</tt> (instead of only nonzero ones), is the triangular array <tt>{{OEIS|A054522|tt=tt}}</tt>.</ref>
 
==Modular multiplication==
Two numbers <tt>a,b</tt> are called multiplicative inverses modulo <tt>n</tt> if <tt>a*b ≡ 1 (mod n)</tt>, and <tt>b</tt> is then occasionally written <tt>a<sup>-1</sup></tt>.
 
If <tt>gcd(n,a) &ne; 1</tt>, <tt>gcd(n,a)</tt> will divide any number of the form <tt>a*b % n</tt>, which as such cannot equal <tt>1</tt>, so <tt>a</tt> does not have a multiplicative inverse. However, the set <tt>S = {k: k ∈ ℕ and k<n and k|n}</tt> form a {{LinkWikipedia|Group_(mathematics)|name=group|nobullet=no|nosuffix=no}} under multiplication, meaning that for all integers <tt>c ∈ S</tt>, <tt>{c*k%n: k ∈ S} = S</tt> (ie. mapping a multiplication over the set permutes it<ref group="n">a multiplication by a coprime to <tt>n</tt> also permutes the entire set of congruence classes, not just the other coprimes.</ref>), and every member has an inverse in the set (findable using the {{LinkWikipedia|Extended_Euclidean_algorithm|name=extended Euclid's algorithm|nobullet=no|nosuffix=no}}).
 
There is no similarly simple statement for fixed <tt>n</tt> and <tt>p</tt>, enumerating the <tt>k</tt> such that the period of multiplication by <tt>k</tt> (modulo <tt>n</tt>) is <tt>p</tt>. Multiplication by numbers not coprime to <tt>n</tt> is neither
*injective (such that all numbers <tt>0 &le; x < n</tt> produce distinct values under multiplication by <tt>k</tt> modulo <tt>n</tt>), since there are only <tt>{{frac|n|gcd(n,k)}}</tt> destinations they can be mapped to, nor
*surjective (such that for given <tt>n,k</tt>, every value <tt>y</tt> can have an <tt>x</tt> found such that <tt>k*x ≡ y (mod n)</tt>), since <tt>x</tt> would generally have to equal <tt>y*k<sup>-1</sup></tt>.
Due to this, similarly to cellular automata in spaces with finitely many states, recursively applying a multiplication will cause integers to eventually enter one of several cycles, across which the period varies.<ref group="n">An equivalent program to the previous one (for the cycle obtained by beginning at <tt>x=1</tt>) is <tt>print('\n'.join(map(λ n: 'n='+f(m,n)+': ('+','.join((λ t: map(λ p: f(m,t.count(p)),range(1,n)))(tuple(map(λ k: (λ f: f(f))(λ f: λ r,t: (λ r: t.index(r)+1 if r in t else f(f)(r,(r,)+t))(k*r%n))(1,()),range(1,n)))))+')',range(1,m:=16))))</tt>, which generates <tt>{{OEIS|A057593|tt=tt}}</tt>,<br />and the number of cycles by <tt>print('\n'.join(map(λ n: 'n='+f(m,n)+': '+','.join(map(λ k: f(m,(λ f: f(f))(λ f: λ c,i,o,p: (λ o: o if all(c) else f(f)(c,c.index(0),o,p+1))(o+(c[i]==p)) if c[i] else f(f)(c[:i]+(p,)+c[i+1:],k*i%n,o,p))((0,)*n,0,0,1)),range(n))),range(1,m:=24))))</tt> (returning <tt>{{OEIS|A348888|tt=tt}}</tt>, which has [https://oeis.org/A348888/a348888.pdf a nice diagram] showing the cycles formed by different <tt>n,k</tt>).</ref> Implementations of modular exponentiation to large powers with small modulo bases can be further optimised by detecting the length of the cycle that an exponentiation process enters and finding the phase that it ends in by taking the remaining exponent (upon entry to the cycle) modulo this length, and using it as the index in the cycle.
 
The {{LinkWikipedia|Chinese_remainder_theorem|name=Chinese remainder theorem|nobullet=no|nosuffix=no}} states that an unknown <tt>x</tt>'s value <tt>(mod n)</tt> can be determined uniquely from a set of congruences of the form <tt>x ≡ c<sub>i</sub> (mod m<sub>i</sub>)</tt> for <tt>{{product|m<sub>i</sub> ∈ m|<font style{{=}}"opacity:0">.</font>|m<sub>i</sub>}} = n</tt>, where all pairs of indexes <tt>i &ne; j</tt> have <tt>gcd(m<sub>i</sub>,m<sub>j</sub>)</tt>.


==Relationship with bitwise operators==
==Relationship with bitwise operators==
In programming, where <tt>x,n</tt> are integer (as is usually necessary for bitwise operators) and <tt>n</tt> is known to be a power of <tt>2</tt>, because it corresponds with truncating <tt>x</tt>'s <tt>n</tt>-ary expansion to the last digit, and its binary expansion to the last <tt>log_2(n)</tt> digits, <tt>x%n=x&n-1</tt>, the latter of which can be more efficient to compute. The Stanford bit-twiddling hacks explain [https://graphics.stanford.edu/~seander/bithacks.html#ModulusDivision division by <tt>1</tt> less than a power of <tt>2</tt>].
In programming, where <tt>x,n</tt> are integer (as is usually necessary for bitwise operators), because it corresponds with truncating <tt>x</tt>'s base-<tt>2<sup>n</sup></tt> expansion to the last digit, and its binary expansion to the last <tt>n</tt> bits, <tt>x % 2<sup>n</sup> = x & 2<sup>n</sup>-1</tt>, the latter of which can be more efficient to compute. The Stanford bit-twiddling hacks explain [https://graphics.stanford.edu/~seander/bithacks.html#ModulusDivision division by <tt>1</tt> less than a power of <tt>2</tt>].


==Notable congruences==
==Notable congruences==
These provide algebraic reduction steps for forms that can arise generally in modular arithmetic problems.
These provide algebraic reduction steps for forms that can arise generally in modular arithmetic problems.
* [https://en.wikipedia.org/wiki/Fermat's_little_theorem Fermat's little theorem] states that for a prime <tt>p</tt> and other integer <tt>c</tt>, <tt>c**p≡c (mod p)</tt>.
* {{LinkWikipedia|Fermat's_little_theorem|name=Fermat's little theorem|nobullet=no|nosuffix=no}} states that for a prime <tt>p</tt> and other integer <tt>c</tt>, <tt>c<sup>p</sup> ≡ c (mod p)</tt>.<ref group="n">Being prime is sufficient but not necessary, composite <tt>p</tt> for which <tt>n<sup>p</sup> ≡ n (mod p)</tt> are called Fermat pseudoprimes to base <tt>n</tt>. The smallest composite pseudoprime <tt>p</tt> to <tt>n</tt> is <tt>{{OEIS|A000790|tt=tt}}(n)</tt>, which is periodic over <tt>n</tt> with period <tt>277# * 23#</tt>, where <tt>#</tt> is the primorial.</ref>
* [https://en.wikipedia.org/wiki/Wilson's_theorem Wilson's theorem] states that for an integer <tt>n</tt>, <tt>(n-1)! ≡ -1 (mod n)</tt>.
:: It is also given as <tt>c<sup>p-1</sup> ≡ 1 (mod p)</tt>, however this pertains only for coprime <tt>c,p</tt>, whereas <tt>c<sup>p</sup> ≡ n (mod p)</tt> is irrespective
* {{LinkWikipedia|Wilson's_theorem|name=Wilson's theorem|nobullet=no|nosuffix=no}} states that for an integer <tt>n</tt>, <tt>(n-1)! ≡ -1 (mod n)</tt> if <tt>n</tt> is prime, otherwise <tt>(n-1)! ≡ 0 (mod n)</tt> unless <tt>n = 4</tt>, in which case it is congruent instead to <tt>2</tt>.<ref group="n">Explained as an exercise in the MODA chapter involving placements of rooks on toroidal chessboards, and in [[Pólya_enumeration_theorem#Wilson's_theorem|the Pólya enumeration theorem article]]</ref>
* {{LinkWikipedia|Lucas's_theorem|name=Lucas's theorem|nobullet=no|nosuffix=no}}: <tt>{{choose|n|k}} ≡ {{product|i{{=}}0|∞|{{choose|n<sub>i</sub>|k<sub>i</sub>}}|brac=}}<!--{{product|i{{=}}0|∞|{{choose|⌊{{frac|n|b<sup>i</sup>}}⌋%b|⌊{{frac|k|b<sup>i</sup>}}⌋%b}}|brac=}}--> (mod b)</tt>, where <tt>n<sub>i</sub></tt> is the <tt>i</tt>th base-<tt>b</tt> digit of <tt>n</tt>.
===for {{LinkWikipedia|Modular_exponentiation|name=modular exponentiation|nobullet=no|nosuffix=no}} computation===
* <tt>x*y ≡ (x%n)*(y%n) (mod n)</tt>, so <tt>x<sup>p</sup>%n</tt> can be calculated as <tt>(( ... (((x%n)*x)%n)* ... )*x)%n</tt> (preventing any number partway through the computation from exceeding <tt>(n-1)*x</tt>)
* {{LinkWikipedia|Euler's_theorem|name=Euler's theorem|nobullet=no|nosuffix=no}}: For coprime <tt>x,m</tt> <tt>x<sup>φ(m)</sup> ≡ 1 (mod m)</tt>, so <tt>x<sup>n</sup> ≡ x<sup>n%φ(m)</sup> (mod m)</tt>.
:* If <tt>n</tt> is computed from its factorisation, <tt>n%φ(m)</tt> can be computed efficiently also
:* Note that Fermat's little theorem is the special case of Euler's theorem, since for primes <tt>p</tt>, <tt>φ(p) = p-1</tt>
:''see also {{LinkWikipedia|Exponentiation_by_squaring|name=exponentiation by squaring|nobullet=no|nosuffix=no}}''
 
==Uses in Conway's Game of Life==
* [[Colour]] is mod 2.
* [[Trombone slide]]s are mod 8.
* [[Filter]]s for glider streams require certain characteristics, e.g. 8 mod 16 for [[Rich's p16]] and 5 mod 15 or 10 mod 15 for [[Karel's p15]].
* [[Phase shift]]ers make use of modular arithmetic, e.g. [[28P7.1]] phase shifts once when the overall period is 1 mod 7.
* [[Pentadecathlon]] phase shifters work when the overall period is 6, 9, or 14 mod 15, depending on the mechanism. 6 corresponds to the [[monoicosathlon]], 9 to one modification of the [[p54 shuttle]], and 14 to the [[p44 pi-heptomino hassler]].
* Many of the [[SKOP|smallest known oscillators of a period]] that are part of infinite families rely on modular arithmetic, such as [[6 bits]] being 45 mod 120 and the number of gliders required in a [[rectifier]] being dependent on period mod 8 and the existence of a working 22hd reflector requiring the period being 4 mod 8.


==See also==
==See also==
* [[Pólya enumeration theorem]] (through application of a corollary of which, the theorems above can be proven)
* [[Pólya enumeration theorem]] (the enumeration equations must return integers, so the division in the averaging is equivalent to floordiv, meaning the output of the equivalent modulo must be <tt>0</tt>, through which the theorems above can be proven)


==Notes==
==Notes==
<references group="n"></references>
Let <tt>f=λ n,k: ' '*(len(str(n))-len(str(k)))+str(k)</tt>
<references group="n" />


== Further reading ==
== Further reading ==

Latest revision as of 15:30, 7 March 2024

This article may require cleanup to meet LifeWiki's quality standards.

Let p%q = p-⌊pq⌋*q ("p modulo q"), ie. adding or subtracting integer multiples of q to p such that it lies in the range 0 ≤ x < q.[n 1]

Two numbers a,b are congruent modulo a third number n iff a%n = b%n.

Such congruences are denoted as a ≡ b (mod n). For instance, 5 ≡ 8 (mod 3), because 5%3 = 5-3 = 8%3 = 8-6 = 2. Alternatively (for integer modulo bases n), x%n is equivalent to taking x's expansion in base n and removing all but the last digit. Modular arithmetic is generally concerned with the behaviour of operations under modulo by a fixed base.

Given fixed integers k,x ≠ 0, the sequence a(i) = i*k % n oscillates, with period ngcd(n,k) = lcm(n,k)k.

For a modulo base n and period p, for there to exist any integers k with sequences of period p, p must be a divisor of n (written p|n). The number of k whose addition has period p is

#({k: k ∈ ℕ and k<n and ngcd(n,k)=p}) = { φ(p) . p|n0 . . .else

where φ(p) is Euler's totient function , the number of 1 ≤ k < p such that gcd(p,k)=0 (A000010).[n 2]

Modular multiplication

Two numbers a,b are called multiplicative inverses modulo n if a*b ≡ 1 (mod n), and b is then occasionally written a-1.

If gcd(n,a) ≠ 1, gcd(n,a) will divide any number of the form a*b % n, which as such cannot equal 1, so a does not have a multiplicative inverse. However, the set S = {k: k ∈ ℕ and k<n and k|n} form a group under multiplication, meaning that for all integers c ∈ S, {c*k%n: k ∈ S} = S (ie. mapping a multiplication over the set permutes it[n 3]), and every member has an inverse in the set (findable using the extended Euclid's algorithm ).

There is no similarly simple statement for fixed n and p, enumerating the k such that the period of multiplication by k (modulo n) is p. Multiplication by numbers not coprime to n is neither

  • injective (such that all numbers 0 ≤ x < n produce distinct values under multiplication by k modulo n), since there are only ngcd(n,k) destinations they can be mapped to, nor
  • surjective (such that for given n,k, every value y can have an x found such that k*x ≡ y (mod n)), since x would generally have to equal y*k-1.

Due to this, similarly to cellular automata in spaces with finitely many states, recursively applying a multiplication will cause integers to eventually enter one of several cycles, across which the period varies.[n 4] Implementations of modular exponentiation to large powers with small modulo bases can be further optimised by detecting the length of the cycle that an exponentiation process enters and finding the phase that it ends in by taking the remaining exponent (upon entry to the cycle) modulo this length, and using it as the index in the cycle.

The Chinese remainder theorem states that an unknown x's value (mod n) can be determined uniquely from a set of congruences of the form x ≡ ci (mod mi) for ∏.mi ∈ m(mi) = n, where all pairs of indexes i ≠ j have gcd(mi,mj).

Relationship with bitwise operators

In programming, where x,n are integer (as is usually necessary for bitwise operators), because it corresponds with truncating x's base-2n expansion to the last digit, and its binary expansion to the last n bits, x % 2n = x & 2n-1, the latter of which can be more efficient to compute. The Stanford bit-twiddling hacks explain division by 1 less than a power of 2.

Notable congruences

These provide algebraic reduction steps for forms that can arise generally in modular arithmetic problems.

It is also given as cp-1 ≡ 1 (mod p), however this pertains only for coprime c,p, whereas cp ≡ n (mod p) is irrespective
  • Wilson's theorem states that for an integer n, (n-1)! ≡ -1 (mod n) if n is prime, otherwise (n-1)! ≡ 0 (mod n) unless n = 4, in which case it is congruent instead to 2.[n 6]
  • Lucas's theorem : (nk) ≡ ∏∞i=0(niki) (mod b), where ni is the ith base-b digit of n.

for modular exponentiation computation

  • x*y ≡ (x%n)*(y%n) (mod n), so xp%n can be calculated as (( ... (((x%n)*x)%n)* ... )*x)%n (preventing any number partway through the computation from exceeding (n-1)*x)
  • Euler's theorem : For coprime x,m xφ(m) ≡ 1 (mod m), so xn ≡ xn%φ(m) (mod m).
  • If n is computed from its factorisation, n%φ(m) can be computed efficiently also
  • Note that Fermat's little theorem is the special case of Euler's theorem, since for primes p, φ(p) = p-1
see also exponentiation by squaring

Uses in Conway's Game of Life

See also

  • Pólya enumeration theorem (the enumeration equations must return integers, so the division in the averaging is equivalent to floordiv, meaning the output of the equivalent modulo must be 0, through which the theorems above can be proven)

Notes

Let f=λ n,k: ' '*(len(str(n))-len(str(k)))+str(k)

  1. ↑ Note that for p ≠ 0, this causes sgn(p%q) = sgn(q), to make ⌊pq⌋*q+p%q=p hold, as in Python. In other programming languages such as C, p%q = |p-⌊pq⌋*q|*sgn(p), so ie. -4%3=-1, since its integer integer division operator, /, rounds towards 0 instead of -∞. In most programming languages, modulo has the same precedence as multiplication and division, and expressions involving multiple of the same precedence adjacent without brackets are evaluated left-to-right.
  2. ↑ These can be tabulated by running print('\n'.join(map(λ n: 'n='+f(m,n)+': (\n '+',\n '.join(map(λ p: p[1],filter(λ p: p[0],map(λ p: (λ t: (len(t),'p='+f(m,p)+': ('+','.join(map(str,t))+')'))(tuple(filter(λ k: n//gcd(n,k)==p,range(n)))),range(1,n+1)))))+')',range(m:=16)))) in the Python terminal. The lengths of the tuples, over all values of p (instead of only nonzero ones), is the triangular array A054522.
  3. ↑ a multiplication by a coprime to n also permutes the entire set of congruence classes, not just the other coprimes.
  4. ↑ An equivalent program to the previous one (for the cycle obtained by beginning at x=1) is print('\n'.join(map(λ n: 'n='+f(m,n)+': ('+','.join((λ t: map(λ p: f(m,t.count(p)),range(1,n)))(tuple(map(λ k: (λ f: f(f))(λ f: λ r,t: (λ r: t.index(r)+1 if r in t else f(f)(r,(r,)+t))(k*r%n))(1,()),range(1,n)))))+')',range(1,m:=16)))), which generates A057593,
    and the number of cycles by print('\n'.join(map(λ n: 'n='+f(m,n)+': '+','.join(map(λ k: f(m,(λ f: f(f))(λ f: λ c,i,o,p: (λ o: o if all(c) else f(f)(c,c.index(0),o,p+1))(o+(c[i]==p)) if c[i] else f(f)(c[:i]+(p,)+c[i+1:],k*i%n,o,p))((0,)*n,0,0,1)),range(n))),range(1,m:=24)))) (returning A348888, which has a nice diagram showing the cycles formed by different n,k).
  5. ↑ Being prime is sufficient but not necessary, composite p for which np ≡ n (mod p) are called Fermat pseudoprimes to base n. The smallest composite pseudoprime p to n is A000790(n), which is periodic over n with period 277# * 23#, where # is the primorial.
  6. ↑ Explained as an exercise in the MODA chapter involving placements of rooks on toroidal chessboards, and in the Pólya enumeration theorem article

Further reading