NAME
Sidef::Types::Number::Mod - Modular arithmetic in Sidef
DESCRIPTION
This class implements modular arithmetic operations in Sidef. A Mod object represents an integer modulo some modulus, allowing efficient computation of arithmetic operations in modular rings. This is particularly useful in number theory, cryptography, and computational mathematics.
The Mod class supports standard arithmetic operations (addition, subtraction, multiplication, division, exponentiation) as well as specialized number-theoretic functions (modular square roots, multiplicative order, etc.), all performed modulo a specified modulus.
SYNOPSIS
var a = Mod(13, 19) # 13 modulo 19
a += 15 # Mod(9, 19) -- (13 + 15) mod 19
a *= 99 # Mod(17, 19) -- (9 * 99) mod 19
a /= 17 # Mod(1, 19) -- (17 * 17^(-1)) mod 19
say a # Mod(1, 19)
# Modular exponentiation
var b = Mod(2, 1000)
say b**100 # Mod(376, 1000) -- 2^100 mod 1000
# Modular inverse
var c = Mod(3, 7)
say c.inv # Mod(5, 7) -- 3 * 5 ≡ 1 (mod 7)
# Chinese Remainder Theorem
var x = Mod(2, 3)
var y = Mod(3, 5)
var z = Mod(2, 7)
say chinese(x,y,z) # Mod(23, 105)
INHERITS
Inherits methods from:
* Sidef::Types::Number::Number
METHODS
new
Mod(n, m)
Mod.new(n, m)
Creates a new Mod object representing the integer n modulo m. The value is automatically reduced so that 0 ≤ n < m.
var a = Mod(17, 5) # Mod(2, 5)
var b = Mod(-3, 7) # Mod(4, 7)
If called on an existing Mod object, it evaluates a polynomial at the given point.
Aliases: call
to_n
x.to_n
Returns the underlying integer value (the residue) of the modular number, without the modulus information.
var a = Mod(17, 5)
say a.to_n # 2
Aliases: lift
modulus
x.modulus
Returns the modulus of the modular number.
var a = Mod(17, 5)
say a.modulus # 5
re
x.re
Returns the real part of the modular number. For a non-zero residue, returns the residue itself; for zero, returns the modulus.
var a = Mod(3, 7)
say a.re # 3
var b = Mod(0, 7)
say b.re # 7
Aliases: real
norm
x.norm
Returns the norm (absolute value) of the real part of the modular number.
+
a + b
Adds two modular numbers or adds an integer to a modular number. The result is reduced modulo the modulus of a.
var a = Mod(10, 13)
say a + 5 # Mod(2, 13) -- (10 + 5) mod 13
Aliases: add
-
a - b
Subtracts two modular numbers or subtracts an integer from a modular number.
var a = Mod(3, 10)
say a - 5 # Mod(8, 10) -- (3 - 5) mod 10
Aliases: sub
*
a * b
Multiplies two modular numbers or multiplies a modular number by an integer.
var a = Mod(7, 13)
say a * 4 # Mod(2, 13) -- (7 * 4) mod 13
Aliases: mul
/
a / b
Divides a modular number by another. This computes a * b^(-1) (mod m), where b^(-1) is the modular inverse of b.
var a = Mod(10, 13)
say a / 2 # Mod(5, 13) -- 10 * 2^(-1) mod 13
Raises an error if b has no modular inverse (i.e., if gcd(b, m) ≠ 1).
Aliases: ÷, div
**
a ** b
Computes modular exponentiation: a^b (mod m). Uses efficient binary exponentiation.
var a = Mod(2, 1000)
say a ** 100 # Mod(376, 1000)
Aliases: pow
++
a++
++a
Increments the modular number by 1.
var a = Mod(12, 13)
say ++a # Mod(0, 13)
Aliases: inc
--
a--
--a
Decrements the modular number by 1.
var a = Mod(0, 13)
say --a # Mod(12, 13)
Aliases: dec
neg
x.neg
-x
Returns the additive inverse (negation) of the modular number.
var a = Mod(3, 7)
say a.neg # Mod(4, 7) -- (-3) mod 7
abs
x.abs
Returns the absolute value of the underlying residue (as a regular integer, not a Mod object).
var a = Mod(3, 7)
say a.abs # 3
inv
x.inv
Returns the multiplicative inverse of the modular number. If x ≡ a (mod m), returns y such that a * y ≡ 1 (mod m).
var a = Mod(3, 7)
say a.inv # Mod(5, 7) -- 3 * 5 ≡ 1 (mod 7)
Raises an error if the number has no inverse (i.e., if gcd(a, m) ≠ 1).
sqr
x.sqr
Returns the square of the modular number.
var a = Mod(5, 13)
say a.sqr # Mod(12, 13) -- 5^2 mod 13
sqrt
x.sqrt
Returns a modular square root of the number. If x^2 ≡ a (mod m), returns one value of x.
var a = Mod(4, 13)
say a.sqrt # Mod(2, 13) or Mod(11, 13)
May not return a result if no square root exists modulo m.
!
x!
x.factorial
Computes the factorial of the modular number's residue, reduced modulo m: x! (mod m).
var a = Mod(5, 13)
say a! # Mod(3, 13) -- 5! = 120 ≡ 3 (mod 13)
Aliases: factorial
==
a == b
Tests if two modular numbers are equal (have the same residue modulo the modulus of a).
var a = Mod(15, 7)
var b = Mod(1, 7)
say (a == b) # true -- 15 ≡ 1 (mod 7)
Aliases: eq
!=
a != b
Tests if two modular numbers are not equal.
var a = Mod(5, 7)
var b = Mod(3, 7)
say (a != b) # true
Aliases: ne
<
a < b
Compares the underlying residues of two modular numbers.
var a = Mod(2, 7)
var b = Mod(5, 7)
say (a < b) # true
Aliases: lt
>
a > b
Compares the underlying residues: returns true if a's residue is greater than b's.
var a = Mod(6, 11)
var b = Mod(3, 11)
say (a > b) # true
Aliases: gt
≤
a ≤ b
Less than or equal comparison of underlying residues.
var a = Mod(3, 7)
var b = Mod(3, 7)
say (a ≤ b) # true
Aliases: <=, le
≥
a ≥ b
Greater than or equal comparison of underlying residues.
Aliases: >=, ge
<=>
a <=> b
Three-way comparison operator. Returns -1, 0, or 1 depending on whether a's residue is less than, equal to, or greater than b's residue.
var a = Mod(5, 13)
var b = Mod(8, 13)
say (a <=> b) # -1
Aliases: cmp
&
a & b
Bitwise AND operation on the underlying residues, with the result reduced modulo a's modulus.
var a = Mod(12, 100) # binary: 1100
var b = Mod(10, 100) # binary: 1010
say (a & b) # Mod(8, 100) -- binary: 1000
Aliases: and
|
a | b
Bitwise OR operation on the underlying residues, with the result reduced modulo a's modulus.
var a = Mod(12, 100) # binary: 1100
var b = Mod(10, 100) # binary: 1010
say (a | b) # Mod(14, 100) -- binary: 1110
Aliases: or
^
a ^ b
Bitwise XOR operation on the underlying residues, with the result reduced modulo a's modulus.
var a = Mod(12, 100) # binary: 1100
var b = Mod(10, 100) # binary: 1010
say (a ^ b) # Mod(6, 100) -- binary: 0110
Aliases: xor
<<
a << b
Left bit shift operation: multiplies a by 2^b, reduced modulo a's modulus.
var a = Mod(5, 100)
say (a << 3) # Mod(40, 100) -- 5 * 2^3
Aliases: lsft, shift_left
>>
a >> b
Right bit shift operation: divides a by 2^b, reduced modulo a's modulus.
var a = Mod(40, 100)
say (a >> 3) # Mod(5, 100) -- 40 / 2^3
Aliases: rsft, shift_right
is_zero
x.is_zero
Returns true if the modular number's residue is zero.
var a = Mod(0, 7)
say a.is_zero # true
var b = Mod(7, 7)
say b.is_zero # true -- 7 ≡ 0 (mod 7)
is_one
x.is_one
Returns true if the modular number's residue is one.
var a = Mod(1, 7)
say a.is_one # true
is_mone
x.is_mone
Returns true if the modular number's residue is minus one (or equivalently, m-1).
var a = Mod(-1, 7)
say a.is_mone # true -- -1 ≡ 6 (mod 7)
is_neg
x.is_neg
Returns true if the underlying residue is considered negative (inherited from the Number class behavior).
is_pos
x.is_pos
Returns true if the underlying residue is considered positive (inherited from the Number class behavior).
is_nan
x.is_nan
Returns true if the underlying residue is NaN (Not a Number).
is_inf
x.is_inf
Returns true if the underlying residue is positive infinity.
is_ninf
x.is_ninf
Returns true if the underlying residue is negative infinity.
is_real
x.is_real
Returns true if the underlying residue is a real number (typically always true for valid Mod objects).
znorder
x.znorder
Computes the multiplicative order of x modulo m. This is the smallest positive integer k such that x^k ≡ 1 (mod m).
var a = Mod(2, 7)
say a.znorder # 3 -- 2^3 ≡ 1 (mod 7)
The element must be coprime to the modulus.
Aliases: multiplicative_order
chinese
[m1, m2, m3, ...].chinese
Applies the Chinese Remainder Theorem to solve a system of modular congruences. Given Mod objects representing x ≡ a₁ (mod m₁), x ≡ a₂ (mod m₂), etc., returns a single Mod object representing the solution.
var a = Mod(2, 3) # x ≡ 2 (mod 3)
var b = Mod(3, 5) # x ≡ 3 (mod 5)
var c = Mod(2, 7) # x ≡ 2 (mod 7)
say chinese(a, b, c) # Mod(23, 105)
# 23 ≡ 2 (mod 3)
# 23 ≡ 3 (mod 5)
# 23 ≡ 2 (mod 7)
The moduli should be pairwise coprime for a unique solution.
fib
x.fib
Computes the x-th Fibonacci number modulo m: F(x) (mod m).
var a = Mod(10, 100)
say a.fib # Mod(55, 100) -- F(10) = 55
Aliases: fibonacci
lucas
x.lucas
Computes the x-th Lucas number modulo m: L(x) (mod m).
var a = Mod(10, 1000)
say a.lucas # Mod(123, 1000) -- L(10) = 123
lucasu
x.lucasu(P, Q)
Computes the x-th Lucas U sequence value with parameters P and Q, modulo m: U(P,Q,x) (mod m).
var a = Mod(10, 1000)
say a.lucasu(1, -1) # Equivalent to Fibonacci
Aliases: lucasU
lucasv
x.lucasv(P, Q)
Computes the x-th Lucas V sequence value with parameters P and Q, modulo m: V(P,Q,x) (mod m).
var a = Mod(10, 1000)
say a.lucasv(1, -1) # Equivalent to Lucas numbers
Aliases: lucasV
chebyshevt
x.chebyshevt(n)
Evaluates the n-th Chebyshev polynomial of the first kind at x, modulo m: T_n(x) (mod m).
var a = Mod(2, 100)
say a.chebyshevt(5) # T_5(2) mod 100
Aliases: chebyshevT
chebyshevu
x.chebyshevu(n)
Evaluates the n-th Chebyshev polynomial of the second kind at x, modulo m: U_n(x) (mod m).
var a = Mod(2, 100)
say a.chebyshevu(5) # U_5(2) mod 100
Aliases: chebyshevU
cyclotomic
x.cyclotomic(n)
Evaluates the n-th cyclotomic polynomial at x, modulo m: Φ_n(x) (mod m).
var a = Mod(2, 100)
say a.cyclotomic(5) # Φ_5(2) mod 100
eval
x.eval(v)
Evaluates a polynomial (if x represents one) at the value v, with the result computed modulo m.
This is used when the Mod object contains a polynomial instead of a simple integer.
to_s
x.to_s
Returns a string representation of the modular number in the form "Mod(n, m)".
var a = Mod(17, 5)
say a.to_s # "Mod(2, 5)"
dump
x.dump
Returns a detailed string representation of the modular number, including dump representations of both the residue and modulus.
var a = Mod(17, 5)
say a.dump # "Mod(2, 5)"
pretty
x.pretty
Returns a formatted string representation of the modular number.
var a = Mod(17, 5)
say a.pretty # "Mod(2, 5)"
MATHEMATICAL BACKGROUND
Modular Arithmetic
In modular arithmetic, numbers "wrap around" upon reaching a certain value called the modulus. Two integers a and b are said to be congruent modulo m if their difference is divisible by m, written as:
a ≡ b (mod m)
Operations
All standard arithmetic operations in the Mod class are performed modulo m:
Addition: (a + b) mod m
Subtraction: (a - b) mod m
Multiplication: (a * b) mod m
Division: a * b^(-1) mod m (where b^(-1) is the modular inverse of b)
Exponentiation: a^b mod m
Modular Inverse
An integer a has a multiplicative inverse modulo m if and only if gcd(a, m) = 1. The inverse a^(-1) satisfies:
a * a^(-1) ≡ 1 (mod m)
Chinese Remainder Theorem
If m₁, m₂, ..., m_k are pairwise coprime, then the system of congruences:
x ≡ a₁ (mod m₁)
x ≡ a₂ (mod m₂)
...
x ≡ a_k (mod m_k)
has a unique solution modulo M = m₁ * m₂ * ... * m_k.
EXAMPLES
Basic Arithmetic
var a = Mod(7, 12)
var b = Mod(5, 12)
say (a + b) # Mod(0, 12) -- 7 + 5 = 12 ≡ 0 (mod 12)
say (a * b) # Mod(11, 12) -- 7 * 5 = 35 ≡ 11 (mod 12)
say (a - b) # Mod(2, 12) -- 7 - 5 = 2
Modular Exponentiation
# Compute 2^100 mod 1000
var x = Mod(2, 1000)
say x**100 # Mod(376, 1000)
Solving Linear Congruences
# Solve: 3x ≡ 7 (mod 11)
var a = Mod(7, 11)
var b = Mod(3, 11)
say (a / b) # Mod(6, 11) -- solution: x = 6
# Verify: 3 * 6 = 18 ≡ 7 (mod 11) ✓
Finding Multiplicative Order
# Find the order of 2 modulo 15
var a = Mod(2, 15)
say a.znorder # 4 -- 2^4 = 16 ≡ 1 (mod 15)
Chinese Remainder Theorem
# Solve the system:
# x ≡ 2 (mod 3)
# x ≡ 3 (mod 4)
# x ≡ 1 (mod 5)
var crt = chinese(Mod(2, 3), Mod(3, 4), Mod(1, 5))
say crt # Mod(11, 60)
# Verify: 11 mod 3 = 2 ✓
# 11 mod 4 = 3 ✓
# 11 mod 5 = 1 ✓
Fibonacci Numbers Modulo m
# Compute F(100) mod 1000
var n = Mod(100, 1000)
say n.fib # Mod(..., 1000)
SEE ALSO
AUTHOR
Daniel "Trizen" Șuteu
LICENSE
This library is free software; you can redistribute it and/or modify it under the same terms as Sidef itself.