Skip to content

Commit

Permalink
Quartz sync: Sep 6, 2024, 6:11 PM
Browse files Browse the repository at this point in the history
  • Loading branch information
jackddouglas committed Sep 6, 2024
1 parent 01fc26d commit 4b0e7b0
Show file tree
Hide file tree
Showing 17 changed files with 586 additions and 0 deletions.
Empty file removed content/.gitkeep
Empty file.
3 changes: 3 additions & 0 deletions content/Abelian group.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
AKA commutative group

Group operation is commutative. Group in which the result of applying the group operation to two group elements does not depend on order in which they are written.
60 changes: 60 additions & 0 deletions content/Euclidean algorithm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
id: Euclidean algorithm
aliases:
- standard Euclidean algorithm
tags: []
---

see also: [[extended Euclidean algorithm]]

# Euclidean algorithm
A simple and efficient method for computing the greatest common divisor (GCD) of two numbers.

1. Start with two positive integers a and b.
2. Divide a by b and get the remainder r.
3. If r is 0, b is the GCD.
4. If not, replace a with b and b with r.
5. Repeat from step 2 until r becomes 0.

## Rust Implementation
```rust
fn gcd(mut a: u64, mut b: u64) -> u64 {
while b != 0 {
let temp = b;
b = a % b;
a = temp;
}
a
}

fn main() {
let a = 48;
let b = 18;
let result = gcd(a, b);
println!("The GCD of {} and {} is {}", a, b, result);

let c = 17;
let d = 23;
let result2 = gcd(c, d);
println!("The GCD of {} and {} is {}", c, d, result2);
}
```

This implementation:
1. Takes two unsigned 64-bit integers as input.
2. Uses a while loop to repeatedly apply the division step.
3. Swaps the values of a and b in each iteration, with b becoming the remainder.
4. Continues until b becomes 0, at which point a is the GCD.

The algorithm works because of the following property:
If a = bq + r, then GCD(a,b) = GCD(b,r)

This property allows us to continually reduce the problem to smaller numbers until we reach the GCD.

Key points about the Euclidean algorithm:

1. It's efficient: the number of steps is at most 5 times the number of digits in the smaller number.
2. It works with any two positive integers, regardless of which is larger.
3. It can be extended to find the GCD of more than two numbers by repeatedly applying it.

The main difference between the standard and [[extended Euclidean algorithm|extended Euclidean algorithms]] is that the extended version also finds the coefficients of [[Bézout's identity]], which expresses the GCD as a linear combination of the two original numbers.
3 changes: 3 additions & 0 deletions content/Eurler's Theorem.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Expansion of [[Fermat's Little Theorem]].

States that for any integer $a$ and any positive integer $n$ s.t. $a$ is coprime to $n$, and $\varphi(n)$ is the number of positive integers ($\leq n$) that are coprime to $n$, then$$a^{\varphi(n)}\equiv1\text{ (mod n)}$$
5 changes: 5 additions & 0 deletions content/Fermat's Little Theorem.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
AKA Fermat's remainder theorem

If $p$ is a prime number and $a$ is an integer not divisible by $p$ ($p\nmid a$), then $a$ raised to the power $p-1$ is congruent to $1$ modulo $p$.
$$a^p\equiv a \text{ (mod p)}\Rightarrow a^{p-1}\equiv1\text{ (mod p)}$$
Also expressed as:$$p\mid a^p-a.$$Provable by [[Eurler's Theorem]].
15 changes: 15 additions & 0 deletions content/Groups.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
A group $G$ is a set algebraic structure with the binary operation $*$ that combines two elements $a,b$ in the set to produce a third element $a*b$ in the set. The operation has the following properties:
1. *Closure* — $a*b=c\in G$
2. *Associative* — $(a*b)*c=a*(b*c)$
3. *Existence of Identity element* — $a*0=0*a=a$
4. *Existence of inverse element for every element of set* — $a*b=0$
5. *Commutativity (only Abelian groups)* — $a*b=b*a$

Examples
- $Z$ is a group under addition defined as $(Z,+)$
- $(Z/nZ)^\times$ is a finite group under multiplication
- Equilateral triangles for non-abelian group of order 6 under symmetry
- Invertible $n\times n$ for a non-abelian group under multiplication
\*need to explain last two

A subset of $G$ is a [[subgroup]] of $G$ if the members of subset from a group with respect to the group operation in $G$.
71 changes: 71 additions & 0 deletions content/Miller-Rabin primality test.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
---
id: 1725614892-miller-rabin-primality-test
aliases:
- Miller-Rabin primality test
tags: []
---

# Miller-Rabin primality test
- Probabilistic algorithm used to determine wheter a given number is prime.
- Particularly efficient for large numbers.

1. Concept:
- For a prime number p, the equation a^(p-1) ≡ 1 (mod p) holds for all a coprime to p ([[Fermat's Little Theorem]]).
- Miller-Rabin extends this idea by considering how a number reaches 1 when repeatedly squared.

2. Algorithm steps:
a. Express n-1 as (2^s) * d, where d is odd.
b. Choose a random base a (2 < a < n-2).
c. Compute x = a^d mod n.
d. If x = 1 or x = n-1, the number might be prime.
e. Square x up to s-1 times. If we ever get n-1, the number might be prime.
f. If we never get n-1 in step e, the number is definitely composite.
g. Repeat with different bases for higher confidence.

## Rust Implementation
```rust
fn miller_rabin(n: u64) -> bool {
let witnesses = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37];
for &a in witnesses.iter() {
if n == a {
return true;
}

if !witness(a, n) {
return false;
}
}
true
}
```
- This function tests the number against a fixed set of "witnesses".
- If the number fails the test for any witness, it's composite.
- If it passes for all witnesses, it's probably prime.

```rust
fn witness(a: u64, n: u64) -> bool {
let mut t = n - 1;
let mut s = 0;

while t % 2 == 0 {
t /= 2;
s += 1;
}

let mut x = mod_pow(a, t, n);
if x == 1 || x == n - 1 {
return true;
}

for _ in 0..s-1 {
x = mod_mul(x, x, n);
if x == n - 1 {
return true;
}
}
false
}
```
- This function performs the actual Miller-Rabin test for a single witness.
- It first decomposes n-1 into (2^s) * t.
- Then it computes a^t mod n and checks for the conditions that indicate primality.
56 changes: 56 additions & 0 deletions content/Modular exponentiation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
id: 1725615525-modular-exponentiation
aliases:
- Modular exponentiation
tags: []
---

# Modular exponentiation
Efficient algorithm to calculate (base^exp) % modulus.

## Rust Implementation
```rust
fn mod_pow(mut base: u64, mut exp: u64, modulus: u64) -> u64 {
if modulus == 1 {
return 0;
}

let mut result = 1;
base %= modulus;
while exp > 0 {
if exp % 2 == 1 {
result = mod_mul(result, base, modulus);
}

exp >>= 1;
base = mod_mul(base, base, modulus);
}
result
}

fn mod_mul(a: u64, b: u64, m: u64) -> u64 {
((a as u128 * b as u128) % m as u128) as u64
}
```
1. Function signature:
- Takes three `u64` parameters: `base`, `exp` (exponent), and `modulus`
- Returns a `u64` result

2. Edge case handling:
- If `modulus` is 1, it returns 0 (as any number mod 1 is 0)

3. Initialization:
- `result` is set to 1 (neutral element for multiplication)
- `base` is reduced modulo `modulus` to ensure it's smaller than `modulus`

4. Main loop:
- Continues while `exp` is greater than 0
- Uses the binary exponentiation algorithm:
- If the least significant bit of `exp` is 1, multiply `result` by `base`
- Divide `exp` by 2 (right shift by 1 bit)
- Square `base`
- All multiplications are done using modular arithmetic (via `mod_mul` function)

5. Return the final `result`

This algorithm is efficient because it reduces the number of multiplications needed from O(exp) to O(log(exp)).
5 changes: 5 additions & 0 deletions content/Monoid.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
A set $S$ with binary operation $S\times S\rightarrow S$, denoted as $*$, is a monoid if it satisfies the following two axioms:
**Associativity**
For all $a,b$ and $c$ in $S$, the equation $(a*b)*c=a*(b*c)$ holds.
**Identity Element**
There exists an element $e$ in $S$ s.t. for every element $a$ in $S$, the equalities $e*a=a$ and $a*e=a$ hold.
Loading

0 comments on commit 4b0e7b0

Please sign in to comment.