blob: c845e94c55efbe8feb231ac9b77364262d9135a1 (
plain)
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
|
--- @class Field
--- Interface for an element of a field.
Field = {}
__Field = {}
----------------------
-- Required methods --
----------------------
--- @return Field
function Field:div(b)
return self:mul(b:inv())
end
--- @return Field
function Field:inv()
error("Called unimplemented method: inv()")
end
----------------------------
-- Instance functionality --
----------------------------
--- Field exponentiation based on the definition. Specific rings may implement more efficient methods.
--- @return Field
function Field:pow(n)
local base = self
if(n < Integer.zero()) then
n = -n
base = base:inv()
end
local k = Integer.zero()
local b = self.getring().one()
while k < n do
b = b.mul(base)
k = k + Integer.one()
end
return b
end
--------------------------
-- Instance metamethods --
--------------------------
__FieldOperations = Copy(__EuclideanOperations)
__FieldOperations.__div = function(a, b)
if not b.getring and not b:isconstant() then
return BinaryOperation.DIVEXP({a, b})
end
if(b == b:zero()) then
error("Arithmetic Error: Cannot divide by zero.")
end
local aring, bring = a:getring(), b:getring()
local oring = Ring.resultantring(aring, bring)
if not oring then
error("Attempted to divide two elements of incompatable rings")
end
return a:inring(oring):div(b:inring(oring))
end
-----------------
-- Inheritance --
-----------------
__Field.__index = EuclideanDomain
Field = setmetatable(Field, __Field)
|