diff options
Diffstat (limited to 'macros/luatex/latex/luacas/tex/algebra/field.lua')
-rw-r--r-- | macros/luatex/latex/luacas/tex/algebra/field.lua | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/macros/luatex/latex/luacas/tex/algebra/field.lua b/macros/luatex/latex/luacas/tex/algebra/field.lua new file mode 100644 index 0000000000..c845e94c55 --- /dev/null +++ b/macros/luatex/latex/luacas/tex/algebra/field.lua @@ -0,0 +1,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)
\ No newline at end of file |