-
Notifications
You must be signed in to change notification settings - Fork 66
/
Copy pathgroups.py
105 lines (77 loc) · 2.99 KB
/
groups.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
"""A module implementing the basic functionality of mathematical groups.
This version of the module uses inheritance.
"""
from numbers import Integral
import numpy as np
class Element:
"""An element of the specified group.
Parameters
----------
group: Group
The group of which this is an element.
value:
The value of this entity. Valid values depend on the group.
"""
def __init__(self, group, value):
group._validate(value)
self.group = group
self.value = value
def __mul__(self, other):
"""Use * to represent the group operation."""
return Element(self.group,
self.group.operation(self.value,
other.value))
def __str__(self):
"""Return a string of the form value_group."""
return f"{self.value}_{self.group}"
def __repr__(self):
"""Return the canonical string representation of the element."""
return f"{type(self).__name__}{self.group, self.value!r}"
class Group:
"""A base class containing methods common to many groups.
Each subclass represents a family of parametrised groups.
Parameters
----------
n: int
The primary group parameter, such as order or degree. The
precise meaning of n changes from subclass to subclass.
"""
def __init__(self, n):
self.n = n
def __call__(self, value):
"""Create an element of this group."""
return Element(self, value)
def __str__(self):
"""Return a string in the form symbol then group parameter."""
return f"{self.symbol}{self.n}"
def __repr__(self):
"""Return the canonical string representation of the element."""
return f"{type(self).__name__}({self.n!r})"
class CyclicGroup(Group):
"""A cyclic group represented by integer addition modulo n."""
symbol = "C"
def _validate(self, value):
"""Ensure that value is an allowed element value in this group."""
if not (isinstance(value, Integral) and 0 <= value < self.n):
raise ValueError("Element value must be an integer"
f" in the range [0, {self.n})")
def operation(self, a, b):
"""Perform the group operation on two values.
The group operation is addition modulo n.
"""
return (a + b) % self.n
class GeneralLinearGroup(Group):
"""The general linear group represented by n x n matrices."""
symbol = "G"
def _validate(self, value):
"""Ensure that value is an allowed element value in this group."""
value = np.asarray(value)
if not (value.shape == (self.n, self.n)):
raise ValueError("Element value must be a "
f"{self.n} x {self.n}"
"square array.")
def operation(self, a, b):
"""Perform the group operation on two values.
The group operation is matrix multiplication.
"""
return a @ b