コード例 #1
0
ファイル: Group.py プロジェクト: rwbogl/Abstract-Algebra
    def generate(self, elems):
        """
        Returns the subgroup of self generated by GroupElems elems

        If any of the items aren't already GroupElems, we will try to convert
        them to GroupElems before continuing.

        elems must be iterable
        """

        elems = Set(g if isinstance(g, GroupElem) else GroupElem(g, self) \
                    for g in elems)

        if not elems <= self.group_elems:
            raise ValueError("elems must be a subset of self.group_elems")
        if len(elems) == 0:
            raise ValueError("elems must have at least one element")

        oldG = elems
        while True:
            newG = oldG | Set(a * b for a in oldG for b in oldG)
            if oldG == newG: break
            else: oldG = newG
        oldG = Set(g.elem for g in oldG)

        return Group(oldG, self.bin_op.new_domains(oldG * oldG, oldG))
コード例 #2
0
ファイル: Group.py プロジェクト: rwbogl/Abstract-Algebra
    def __div__(self, other):
        """ Returns the quotient group self / other """
        if not other.is_normal_subgroup(self):
            raise ValueError("other must be a normal subgroup of self")
        G = Set(Set(self.bin_op((g, h)) for h in other.Set) for g in self.Set)

        def multiply_cosets(x):
            h = x[0].pick()
            return Set(self.bin_op((h, g)) for g in x[1])

        return Group(G, Function(G * G, G, multiply_cosets))
コード例 #3
0
ファイル: Group.py プロジェクト: rwbogl/Abstract-Algebra
    def subgroups(self):
        """Returns the Set of self's subgroups"""

        old_sgs = Set([self.generate([self.e])])
        while True:
            new_sgs = old_sgs | Set(self.generate(list(sg.group_elems) + [g]) \
                                     for sg in old_sgs for g in self \
                                     if g not in sg.group_elems)
            if new_sgs == old_sgs: break
            else: old_sgs = new_sgs

        return old_sgs
コード例 #4
0
    def test_basics(self):
        s = Set([0, 1, 2, 3])
        t = Set([1, 2, 3, 4])
        f = Function(s, t, lambda x: x + 1)
        str(f)
        for x in range(4):
            self.assertEquals(f(x), x + 1)
        self.assertEquals(f, f)

        with self.assertRaises(TypeError):
            Function([0, 1, 2, 3], t, lambda x: x + 1)
        with self.assertRaises(TypeError):
            Function(s, [1, 2, 3, 4], lambda x: x + 1)
        with self.assertRaises(TypeError):
            Function(s, t, lambda x: x + 2)
コード例 #5
0
ファイル: Group.py プロジェクト: rwbogl/Abstract-Algebra
def Dn(n):
    """Returns the dihedral group of order 2n """
    G = Set("%s%d" % (l, x) for l in "RS" for x in range(n))

    def multiply_symmetries(x):
        l1, l2 = x[0][0], x[1][0]
        x1, x2 = int(x[0][1:]), int(x[1][1:])
        if l1 == "R":
            if l2 == "R":
                return "R%d" % ((x1 + x2) % n)
            else:
                return "S%d" % ((x1 + x2) % n)
        else:
            if l2 == "R":
                return "S%d" % ((x1 - x2) % n)
            else:
                return "R%d" % ((x1 - x2) % n)

    return Group(G, Function(G * G, G, multiply_symmetries))
コード例 #6
0
ファイル: Group.py プロジェクト: rwbogl/Abstract-Algebra
    def __init__(self, G, bin_op):
        """Create a group, checking group axioms"""

        # Test types
        if not isinstance(G, Set): raise TypeError("G must be a set")
        if not isinstance(bin_op, Function):
            raise TypeError("bin_op must be a function")
        if bin_op.codomain != G:
            raise TypeError("binary operation must have codomain equal to G")
        if bin_op.domain != G * G:
            raise TypeError("binary operation must have domain equal to G * G")

        # Test associativity
        if not all(bin_op((a, bin_op((b, c)))) == \
                   bin_op((bin_op((a, b)), c)) \
                   for a in G for b in G for c in G):
            raise ValueError("binary operation is not associative")

        # Find the identity
        found_id = False
        e = None
        for a in G:
            if all(bin_op((a, b)) == b for b in G):
                e = a
                found_id = True
                break
        if not found_id:
            raise ValueError("G doesn't have an identity")

        # Test for inverses
        for a in G:
            if not any(bin_op((a, b)) == e for b in G):
                raise ValueError("G doesn't have inverses")

        # At this point, we've verified that we have a Group.
        # Now determine if the Group is abelian:
        self.abelian = all(bin_op((a, b)) == bin_op((b, a)) \
                           for a in G for b in G)

        self.Set = G
        self.group_elems = Set(GroupElem(g, self) for g in G)
        self.e = GroupElem(e, self)
        self.bin_op = bin_op
コード例 #7
0
    def test_simple(self):
        s = Set([0, 1, 2, 3])
        t = Set([1, 2, 3, 4])
        u = Set([0, 1, 2, 3, 4, 5])
        f = Function(s, t, lambda x: x + 1)
        g = Function(t, u, lambda x: x + 1)
        h = g.compose(f)
        i = Function(Set([-1, 0, 1]), Set([0, 1]), lambda x: abs(x))

        self.assertEquals(f.is_surjective(), True)
        self.assertEquals(f.is_injective(), True)
        self.assertEquals(f.is_bijective(), True)
        self.assertEquals(f.image(), t)
        str(f)

        self.assertEquals(g.is_surjective(), False)
        self.assertEquals(g.is_injective(), True)
        self.assertEquals(g.is_bijective(), False)
        self.assertEquals(g.image(), Set([2, 3, 4, 5]))
        str(g)

        self.assertEquals(h.is_surjective(), False)
        self.assertEquals(h.is_injective(), True)
        self.assertEquals(h.is_bijective(), False)
        self.assertEquals(h.image(), Set([2, 3, 4, 5]))
        str(h)

        self.assertEquals(i.is_surjective(), True)
        self.assertEquals(i.is_injective(), False)
        self.assertEquals(i.is_bijective(), False)
        self.assertEquals(i.image(), Set([0, 1]))
        str(i)

        with self.assertRaises(ValueError):
            i.compose(f)
        with self.assertRaises(ValueError):
            f.compose(i)
コード例 #8
0
 def is_surjective(self):
     # Need to make self.domain into a Set, since it might not be in
     # subclasses of Function
     return self._image() == Set(self.codomain)
コード例 #9
0
 def _image(self):
     """The literal image of the function"""
     return Set(self(elem) for elem in self.domain)
コード例 #10
0
ファイル: Group.py プロジェクト: rwbogl/Abstract-Algebra
def Sn(n):
    """Returns the symmetric group of order n! """
    G = Set(g for g in itertools.permutations(range(n)))
    bin_op = Function(G * G, G, lambda x: tuple(x[0][j] for j in x[1]))
    return Group(G, bin_op)
コード例 #11
0
ファイル: Group.py プロジェクト: rwbogl/Abstract-Algebra
def Zn(n):
    """Returns the cylic group of order n"""
    G = Set(range(n))
    bin_op = Function(G * G, G, lambda x: (x[0] + x[1]) % n)
    return Group(G, bin_op)
コード例 #12
0
ファイル: Group.py プロジェクト: rwbogl/Abstract-Algebra
 def image(self):
     """Returns the image of the homomorphism as a Group object"""
     G = Set(g.elem for g in self._image())
     return Group(G, self.codomain.bin_op.new_domains(G * G, G))
コード例 #13
0
ファイル: Group.py プロジェクト: rwbogl/Abstract-Algebra
 def kernel(self):
     """Returns the kernel of the homomorphism as a Group object"""
     G = Set(g.elem for g in self.domain if self(g) == self.codomain.e)
     return Group(G, self.domain.bin_op.new_domains(G * G, G))
コード例 #14
0
ファイル: Group.py プロジェクト: rwbogl/Abstract-Algebra
 def multiply_cosets(x):
     h = x[0].pick()
     return Set(self.bin_op((h, g)) for g in x[1])
コード例 #15
0
ファイル: Group.py プロジェクト: rwbogl/Abstract-Algebra
 def is_normal_subgroup(self, other):
     """Checks if self is a normal subgroup of other"""
     return self <= other and \
            all(Set(g * h for h in self) == Set(h * g for h in self) \
                for g in other)
コード例 #16
0
 def test_identity(self):
     s = Set(["las", 3, "ksjfdlka"])
     ID = identity(s)
     str(ID)
     for item in s:
         self.assertEquals(ID(item), item)