| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- DIV_POINT = 1
- DIV_FUNC = 2
- class Divisor:
- def __init__(self, field):
- self.field = field
- self._div = []
- def __call__(self, Px, Py, Pz=1):
- K = self.field
- # Convert to base field
- Px, Py, Pz = K(Px), K(Py), K(Pz)
- # Normalize coordinates
- if Pz > 0:
- Px /= Pz
- Py /= Pz
- Pz = 1
- P = (Px, Py, Pz)
- D = Divisor(K)
- D._div += [(DIV_POINT, 1, P)]
- return D
- def div(self, f):
- K = self.field
- D = Divisor(K)
- D._div += [(DIV_FUNC, 1, f)]
- return D
- def _clean(self):
- self._div = [(type_id, self._deg_obj(P), P)
- for type_id, P in self._objs()]
- self._div = [(type_id, n, P) for type_id, n, P in self._div if n != 0]
- def _deg_obj(self, P):
- return sum(n for type_id, n, Q in self._div if P == Q)
- def _objs(self):
- return set((type_id, P) for type_id, _, P in self._div)
- def __add__(self, other):
- K = self.field
- D = Divisor(K)
- D._div = self._div[:] + other._div[:]
- D._clean()
- return D
- def __sub__(self, other):
- K = self.field
- D = self + -1*other
- return D
- def __mul__(self, n):
- K = self.field
- D = Divisor(K)
- D._div = [(type_id, n*m, P) for type_id, m, P in self._div]
- return D
- __rmul__ = __mul__
- def __repr__(self):
- out = ""
- if not self._div:
- out += "0"
- for i, (type_id, n, obj) in enumerate(self._div):
- assert n != 0
- if i > 0:
- if n > 0:
- out += " + "
- else:
- out += " - "
- else:
- if n < 0:
- out += "-"
- assert type_id in (DIV_POINT, DIV_FUNC)
- if abs(n) > 1:
- out += f"{abs(n)}"
- if type_id == DIV_POINT:
- out += self._format_point(obj)
- elif type_id == DIV_FUNC:
- out += f" div({obj})"
- return out
- def _format_point(self, P):
- Px, Py, Pz = P
- assert Pz in (0, 1)
- if Pz == 0:
- return f"[∞]"
- return f"[({Px}, {Py})]"
- def deg(self):
- return sum(n for _, n, _ in self._div)
- def supp(self):
- return set(P for _, _, P in self._div)
- K.<x, y> = GF(47)[]
- D = Divisor(K)
- D = 4*D(2, 3) + D(2, 4) + 2*D(0, 1, 0) + 4*D.div(x^2 + y)
- E = 6*D(4, 2) - 6*D(6, 3) + 6*D(6, 3)
- #D -= 4*D.div(x^2 + y)
- #E -= 6*D(4, 2)
- print(f"D = {D}")
- print(f"E = {E}")
- print(f"D + E = {D + E}")
- print(f"6E = {6*E}")
- print(f"deg(D) = {D.deg()}")
- print(f"supp(D) = {D.supp()}")
- print(f"deg(E) = {E.deg()}")
- print(f"supp(E) = {E.supp()}")
|