# Swifty Algebra

A Swift playground for Abstract Algebra. This project is intended to understand Algebra by implementing abstract concepts and playing with concrete objects such as Numbers, Matrices, Polynomials, etc.

## How to Build / Run

Open `SwiftyAlgebra.xcworkspace` and press โถ๏ธ to build the framework. You can run the playgrounds under the project. ย

## Using Mathematical Symbols

We make use of mathematical symbols such as sets ๐, ๐, ๐, ๐ and operators โ, โ etc. Copy the folder `CodeSnippets` to `~/Library/Xcode/UserData/` then you can quickly input these symbols by the completion of Xcode.

## Examples

### Rational Numbers

```let a = ๐(4, 5)  // 4/5
let b = ๐(3, 2)  // 3/2

a + b  // 23/10
a * b  // 6/5
b / a  // 15/8```

### Matrices (type safe)

```typealias M = Matrix<_2, _2, ๐> // Matrix of integers with fixed size 2ร2.

let a = M(1, 2, 3, 4)  // [1, 2; 3, 4]
let b = M(2, 1, 1, 2)  // [2, 1; 1, 2]

a + b  // [3, 3; 4, 6]
a * b  // [4, 5; 10, 11]

a + b == b + a  // true: addition is commutative
a * b == b * a  // false: multiplication is noncommutative```

### Permutation (Symmetric Group)

```typealias S_5 = Permutation<_5>

let s = S_5(cyclic: 0, 1, 2) // cyclic notation
let t = S_5([0: 2, 1: 3, 2: 4, 3: 0, 4: 1]) // two-line notation

s[1]  // 2
t[2]  // 4

(s * t)[3]  // 3 -> 0 -> 1
(t * s)[3]  // 3 -> 3 -> 0```

### Polynomials

```typealias P = Polynominal<๐>

let f = P(0, 2, -3, 1) // x^3 โ 3x^2 + 2x
let g = P(6, -5, 1)    // x^2 โ 5x + 6

f + g  // x^3 - 2x^2 - 3x + 6
f * g  // x^5 - 8x^4 + 23x^3 - 28x^2 + 12x
f % g  // 6x - 12

gcd(f, g) // 6x - 12```

### Integer Quotients, Finite Fields

```typealias Z_4 = IntegerQuotientRing<_4>
``````+	|	0	1	2	3
----------------------
0	|	0	1	2	3
1	|	1	2	3	0
2	|	2	3	0	1
3	|	3	0	1	2
``````
```typealias F_5 = IntegerQuotientField<_5>
F_5.printMulTable()```
``````*	|	0	1	2	3	4
--------------------------
0	|	0	0	0	0	0
1	|	0	1	2	3	4
2	|	0	2	4	1	3
3	|	0	3	1	4	2
4	|	0	4	3	2	1
``````

### Algebraic Extension

```// Construct an algebraic extension over ๐:
// K = ๐(โ2) = ๐[x]/(x^2 - 2).

struct p: _Polynomial {                            // p = x^2 - 2, as a struct
typealias K = ๐
static let value = Polynomial<๐>(-2, 0, 1)
}

typealias I = PolynomialIdeal<p>                   // I = (x^2 - 2)
typealias K = QuotientField<Polynomial<๐>, I>      // K = ๐[x]/I

let a = Polynomial<๐>(0, 1).asQuotient(in: K.self) // a = x mod I
a * a == 2                                         // true!```

### Homology, Cohomology

```let S2 = SimplicialComplex.sphere(dim: 2)
let H = Homology(S2, ๐.self)
print("H(S^2; ๐) =", H.detailDescription, "\n")```
``````H(S^2; ๐) = {
0 : ๐,    [(v1)],
1 : 0,    [],
2 : ๐,    [-1(v0, v2, v3) + -1(v0, v1, v2) + (v1, v2, v3) + (v0, v1, v3)]
}
``````
```let RP2 = SimplicialComplex.realProjectiveSpace(dim: 2)
let H = Homology(RP2, ๐โ.self)
print("H(RP^2; ๐โ) =", H.detailDescription, "\n")```
``````H(RP^2; ๐โ) = {
0 : ๐โ,    [(v1)],
1 : ๐โ,    [(v0, v1) + (v1, v2) + (v0, v3) + (v2, v3)],
2 : ๐โ,    [(v0, v2, v3) + (v3, v4, v5) + (v2, v3, v5) + (v1, v2, v5) + (v0, v4, v5) + (v1, v3, v4) + (v0, v1, v5) + (v1, v2, v4) + (v0, v2, v4) + (v0, v1, v3)]
}
``````