Esempio n. 1
0
 def __init__(self, L, O, V):
     super(BorderBasis, self).__init__(L, L.as_polys(V))
     self.O = O
     self.dO = L.border(O)
     self.V = V
     self._quotient_basis = [L.monom(o) for o in O]
     self.Q = BorderBasedUniverse(L.ring, O)
Esempio n. 2
0
class BorderBasis(Basis):
    """
    A border basis.
    """

    def __init__(self, L, O, V):
        super(BorderBasis, self).__init__(L, L.as_polys(V))
        self.O = O
        self.dO = L.border(O)
        self.V = V
        self._quotient_basis = [L.monom(o) for o in O]
        self.Q = BorderBasedUniverse(L.ring, O)

    def find_basis_nearest_lt(self, t):
        """
        Find the basis element with the nearest leading term
        """
        # Find the index closest to t
        closest, dist = None, maxint
        for t_ in self.dO:
            d = tuple_diff(t, t_)
            if any(idx < 0 for idx in d): continue
            dist_ = sum(d)
            if dist_ < dist:
                closest, dist = t_, dist_
        assert closest is not None

        return self._generators[self.dO.index(closest)]

    def find_basis_with_lt(self, t):
        """
        Find the basis element with leading term
        """
        idx = self.dO.index(t)
        return self._generators[idx]

    @property
    def quotient_basis(self):
        return self._quotient_basis

    def mod(self, f):
        """
        Compute the mod
        """
        while True:
            if f.LM in self.O:
                return f
            else:
                # Find the nearest element on the border, and eliminate
                b = self.find_basis_nearest_lt(f.LM)
                f -= f.LC/b.LC * self.L.monom(tuple_diff(f.LM, b.LM)) * b

    def formal_multiplication_matrices(self):
        """
        With border bases, we know that the formal multiplication
        matrices essentially only invoke terms on the border, so we can
        compute this super efficiently.
        """
        d = len(self.Q)
        Vs = [np.zeros((d,d)) for _ in xrange(self.L.nsymbols)]
        for i, V in enumerate(Vs):
            for j, b in enumerate(self.O):
                t = tuple_incr(b, i)
                if t in self.O:
                    V[j, self.Q.index(t)] = 1
                else:
                    b_ = self.find_basis_with_lt(t)
                    for t, c in b_.terms()[1:]:
                        V[j, self.Q.index(t)] = -c
        return Vs