예제 #1
0
 def testSeries(self):
     self.assertEqual(
         parse_circuit_strings('a(2) <<  b(2)'),
         SeriesProduct(CircuitSymbol('a', 2), CircuitSymbol('b', 2)))
     self.assertEqual(
         parse_circuit_strings('a(5) <<  b(5) << c(5)'),
         SeriesProduct(CircuitSymbol('a', 5), CircuitSymbol('b', 5),
                       CircuitSymbol('c', 5)))
예제 #2
0
 def testConcatenation(self):
     self.assertEqual(
         parse_circuit_strings('a(1) +  b(2)'),
         Concatenation(CircuitSymbol('a', 1), CircuitSymbol('b', 2)))
     self.assertEqual(
         parse_circuit_strings('a(1) +  b(2) + c(3)'),
         Concatenation(CircuitSymbol('a', 1), CircuitSymbol('b', 2),
                       CircuitSymbol('c', 3)))
예제 #3
0
 def testNested(self):
     self.assertEqual(
         parse_circuit_strings('a(2) <<  (b(1) + c(1))'),
         SeriesProduct(
             CircuitSymbol('a', 2),
             Concatenation(CircuitSymbol('b', 1), CircuitSymbol('c', 1))))
     self.assertEqual(
         parse_circuit_strings('a(2) +  (b(1) << c(1))'),
         Concatenation(
             CircuitSymbol('a', 2),
             SeriesProduct(CircuitSymbol('b', 1), CircuitSymbol('c', 1))))
     self.assertEqual(
         parse_circuit_strings('[a(2) +  (b(1) << c(1))]_(2->0)'),
         Feedback(
             Concatenation(
                 CircuitSymbol('a', 2),
                 SeriesProduct(CircuitSymbol('b', 1),
                               CircuitSymbol('c', 1))), 2, 0))
예제 #4
0
 def testFeedback(self):
     self.assertEqual(parse_circuit_strings('[M(5)]_(3->4)'),
                      Feedback(CircuitSymbol('M', 5), 3, 4))
예제 #5
0
 def testCIdentity(self):
     self.assertEqual(parse_circuit_strings('cid(1)'), CIdentity)
     self.assertEqual(parse_circuit_strings('cid(5)'), cid(5))
예제 #6
0
 def testSymbol(self):
     self.assertEqual(parse_circuit_strings('a(2)'), CircuitSymbol('a', 2))
     self.assertEqual(parse_circuit_strings('a(5)'), CircuitSymbol('a', 5))
     self.assertEqual(parse_circuit_strings('a_longer_string(5)'),
                      CircuitSymbol('a_longer_string', 5))
예제 #7
0
 def testCPermutation(self):
     self.assertEqual(parse_circuit_strings('P_sigma(0,2,1)'),
                      CPermutation((0, 2, 1)))
     self.assertEqual(parse_circuit_strings('P_sigma(0,2,1,4,3)'),
                      CPermutation((0, 2, 1, 4, 3)))
예제 #8
0
def draw_circuit_canvas(circuit,
                        hunit=HUNIT,
                        vunit=VUNIT,
                        rhmargin=RHMARGIN,
                        rvmargin=RVMARGIN,
                        rpermutation_length=RPLENGTH,
                        draw_boxes=True,
                        permutation_arrows=False):
    """
    Generate a PyX graphical representation of a circuit expression object.

    :param circuit: The circuit expression
    :type circuit: ca.Circuit
    :param hunit: The horizontal length unit, default = ``HUNIT``
    :type hunit: float
    :param vunit: The vertical length unit, default = ``VUNIT``
    :type vunit: float
    :param rhmargin: relative horizontal margin, default = ``RHMARGIN``
    :type rhmargin: float
    :param rvmargin: relative vertical margin, default = ``RVMARGIN``
    :type rvmargin: float
    :param rpermutation_length: the relative length of a permutation circuit, default = ``RPLENGTH``
    :type rpermutation_length: float
    :param draw_boxes: Whether to draw indicator boxes to denote subexpressions (Concatenation, SeriesProduct, etc.), default = ``True``
    :type draw_boxes: bool
    :param permutation_arrows: Whether to draw arrows within the permutation visualization, default = ``False``
    :type permutation_arrows: bool
    :return: A PyX canvas object that can be further manipulated or printed to an output image.
    :rtype: pyx.canvas.canvas
    """

    if isinstance(circuit, str):
        try:
            parsed = parse_circuit_strings.parse_circuit_strings(circuit)
            if not isinstance(parsed, ca.Circuit):
                if len(parsed) > 1:
                    raise NotImplementedError(
                        'Can currently only process a single expression.')
                circuit = parsed[0]
            else:
                circuit = parsed
        except parse_circuit_strings.ParseCircuitStringError as e:
            raise ValueError('Could not parse {}'.format(circuit))

    if not isinstance(circuit, ca.Circuit):
        raise ValueError()

    nc = circuit.cdim
    c = pyx.canvas.canvas()

    if circuit is ca.CIdentity:
        # simply create a line going through
        c.stroke(pyx.path.line(0, vunit / 2, hunit, vunit / 2))
        return c, (1, 1), (.5, ), (.5, )

    elif isinstance(
            circuit,
        (ca.CircuitSymbol, ca.SeriesInverse, ca.SLH, Component, SubComponent)):
        # draw box
        b = pyx.path.rect(rhmargin * hunit, rvmargin * vunit,
                          hunit - 2 * rhmargin * hunit,
                          nc * vunit - 2 * rvmargin * vunit)
        c.stroke(b)

        texstr = "${}$".format(circuit.tex(
        ) if not isinstance(circuit, ca.SLH) else r"{{\rm SLH}}_{{{}}}".
                               format(circuit.space.tex()))

        # draw symbol name
        c.text(hunit / 2., nc * vunit / 2., texstr,
               [pyx.text.halign.boxcenter, pyx.text.valign.middle])

        # draw connectors at half-unit positions
        connector_positions = tuple((.5 + k) for k in range(nc))
        for y in connector_positions:
            c.stroke(pyx.path.line(0, y * vunit, rhmargin * hunit, y * vunit),
                     [pyx.deco.earrow()])
            c.stroke(
                pyx.path.line(hunit * (1 - rhmargin), y * vunit, hunit,
                              y * vunit))

        return c, (1, nc), connector_positions, connector_positions

    elif isinstance(circuit, ca.CPermutation):
        permutation = circuit.permutation

        connector_positions = tuple((k + 0.5) for k in range(nc))
        target_positions = [
            connector_positions[permutation[k]] for k in range(nc)
        ]

        # draw curves
        for y1, y2 in zip(connector_positions, target_positions):
            if permutation_arrows:
                c.stroke(
                    _curve(0,
                           y1,
                           rpermutation_length,
                           y2,
                           hunit=hunit,
                           vunit=vunit), [pyx.deco.earrow()])
            else:
                c.stroke(
                    _curve(0,
                           y1,
                           rpermutation_length,
                           y2,
                           hunit=hunit,
                           vunit=vunit))

        if draw_boxes:
            b = pyx.path.rect(.5 * rhmargin * hunit, .5 * rvmargin * vunit,
                              rpermutation_length * hunit - rhmargin * hunit,
                              nc * vunit - rvmargin * vunit)
            c.stroke(b, [
                pyx.style.linewidth.thin, pyx.style.linestyle.dashed,
                pyx.color.rgb.green
            ])

        return c, (rpermutation_length,
                   nc), connector_positions, connector_positions

    elif isinstance(circuit, ca.SeriesProduct):
        assert len(circuit.operands) > 1

        # generate graphics of operad subsystems
        sub_graphics = [
            draw_circuit_canvas(op,
                                hunit=hunit,
                                vunit=vunit,
                                rhmargin=rhmargin,
                                rvmargin=rvmargin,
                                rpermutation_length=rpermutation_length,
                                draw_boxes=draw_boxes,
                                permutation_arrows=permutation_arrows)
            for op in reversed(circuit.operands)
        ]

        # set up first one
        previous_csub, previous_dims, previous_c_in, previous_c_out = sub_graphics[
            0]
        hoffset = 0
        c.insert(previous_csub)
        hoffset += previous_dims[0]

        max_height = previous_dims[1]

        # this will later become the full series in-port coordinate tuple
        first_c_in = previous_c_in

        # now add all other operand subsystems
        for csub, dims, c_in, c_out in sub_graphics[1:]:
            assert dims[1] >= 0

            max_height = max(dims[1], max_height)

            if previous_c_out != c_in:  # vertical port locations don't agree, map signals correspondingly

                x1 = hoffset
                x2 = hoffset + rpermutation_length

                # draw connection curves
                for y1, y2 in zip(previous_c_out, c_in):
                    c.stroke(_curve(x1, y1, x2, y2, hunit=hunit, vunit=vunit))

                hoffset += rpermutation_length

            previous_c_in, previous_c_out = c_in, c_out

            # now insert current system
            c.insert(csub, [pyx.trafo.translate(hunit * hoffset, 0)])
            hoffset += dims[0]
        if draw_boxes:
            b = pyx.path.rect(.5 * rhmargin * hunit, .5 * rvmargin * vunit,
                              hoffset * hunit - 1. * rhmargin * hunit,
                              max_height * vunit + rvmargin * vunit)
            c.stroke(b, [
                pyx.style.linewidth.thin, pyx.style.linestyle.dashed,
                pyx.color.rgb.red
            ])

        return c, (hoffset, max_height), first_c_in, c_out

    elif isinstance(circuit, ca.Concatenation):

        voffset = 0
        total_cin, total_cout = (), ()
        widths = []  # stores the component width for each channel(!)

        # generate all operand subsystem graphics and stack them vertically
        for op in circuit.operands:
            csub, dims, c_in, c_out = draw_circuit_canvas(
                op,
                hunit=hunit,
                vunit=vunit,
                rhmargin=rhmargin,
                rvmargin=rvmargin,
                rpermutation_length=rpermutation_length,
                draw_boxes=draw_boxes,
                permutation_arrows=permutation_arrows)

            # add appropriatly offsets to vertical port coordinates
            total_cin += tuple(y + voffset for y in c_in)
            total_cout += tuple(y + voffset for y in c_out)

            c.insert(csub, [pyx.trafo.translate(0, vunit * voffset)])

            # keep track of width in all channel for this subsystem
            widths += [dims[0]] * op.cdim

            voffset += dims[1]

        max_width = max(widths)

        if max_width > min(
                widths
        ):  # components differ in width => we must extend the narrow component output lines

            for x, y in zip(widths, total_cout):
                if x == max_width:
                    continue

                ax, ax_to = x * hunit, max_width * hunit
                ay = y * vunit
                c.stroke(pyx.path.line(ax, ay, ax_to, ay))

        if draw_boxes:
            b = pyx.path.rect(.5 * rhmargin * hunit, .5 * rvmargin * vunit,
                              max_width * hunit - 1. * rhmargin * hunit,
                              voffset * vunit - rvmargin * vunit)
            c.stroke(b, [
                pyx.style.linewidth.thin, pyx.style.linestyle.dashed,
                pyx.color.rgb.blue
            ])

        return c, (max_width, voffset), total_cin, total_cout

    elif isinstance(circuit, ca.Feedback):

        # generate and insert graphics of subsystem
        csub, dims, c_in, c_out = draw_circuit_canvas(
            circuit.operand,
            hunit=hunit,
            vunit=vunit,
            rhmargin=rhmargin,
            rvmargin=rvmargin,
            rpermutation_length=rpermutation_length,
            draw_boxes=draw_boxes,
            permutation_arrows=permutation_arrows)

        c.insert(csub, [pyx.trafo.translate(hunit * .5 * rhmargin, 0)])
        width, height = dims

        # create feedback loop
        fb_out, fb_in = circuit.out_in_pair
        out_coords = (width + .5 * rhmargin) * hunit, c_out[fb_out] * vunit
        in_coords = .5 * rhmargin * hunit, c_in[fb_in] * vunit
        upper_y = (height) * vunit
        feedback_line = pyx.path.path(pyx.path.moveto(*out_coords),
                                      pyx.path.lineto(out_coords[0], upper_y),
                                      pyx.path.lineto(in_coords[0], upper_y),
                                      pyx.path.lineto(*in_coords))
        c.stroke(feedback_line)

        # remove feedback port coordinates
        new_c_in = c_in[:fb_in] + c_in[fb_in + 1:]
        new_c_out = c_out[:fb_out] + c_out[fb_out + 1:]

        # extend port connectors a little bit outward,
        # such that the feedback loop is not at the edge anymore
        for y in new_c_in:
            c.stroke(
                pyx.path.line(0, y * vunit, .5 * rhmargin * hunit, y * vunit))

        for y in new_c_out:
            c.stroke(
                pyx.path.line((width + .5 * rhmargin) * hunit, y * vunit,
                              (width + rhmargin) * hunit, y * vunit))

        return c, (width + rhmargin, height + rvmargin), new_c_in, new_c_out

    raise Exception('Visualization not implemented for type %s' %
                    type(circuit))
예제 #9
0
def draw_circuit_canvas(circuit, hunit = HUNIT, vunit = VUNIT, rhmargin = RHMARGIN, rvmargin = RVMARGIN, rpermutation_length = RPLENGTH, draw_boxes = True, permutation_arrows = False):
    """
    Generate a PyX graphical representation of a circuit expression object.

    :param circuit: The circuit expression
    :type circuit: ca.Circuit
    :param hunit: The horizontal length unit, default = ``HUNIT``
    :type hunit: float
    :param vunit: The vertical length unit, default = ``VUNIT``
    :type vunit: float
    :param rhmargin: relative horizontal margin, default = ``RHMARGIN``
    :type rhmargin: float
    :param rvmargin: relative vertical margin, default = ``RVMARGIN``
    :type rvmargin: float
    :param rpermutation_length: the relative length of a permutation circuit, default = ``RPLENGTH``
    :type rpermutation_length: float
    :param draw_boxes: Whether to draw indicator boxes to denote subexpressions (Concatenation, SeriesProduct, etc.), default = ``True``
    :type draw_boxes: bool
    :param permutation_arrows: Whether to draw arrows within the permutation visualization, default = ``False``
    :type permutation_arrows: bool
    :return: A PyX canvas object that can be further manipulated or printed to an output image.
    :rtype: pyx.canvas.canvas
    """

    if isinstance(circuit, str):
        try:
            parsed = parse_circuit_strings.parse_circuit_strings(circuit)
            if not isinstance(parsed, ca.Circuit):
                if len(parsed) > 1:
                    raise NotImplementedError('Can currently only process a single expression.')
                circuit = parsed[0]
            else:
                circuit = parsed
        except parse_circuit_strings.ParseCircuitStringError as e:
            raise ValueError('Could not parse {}'.format(circuit))


    if not isinstance(circuit, ca.Circuit):
        raise ValueError()
    
    nc = circuit.cdim
    c = pyx.canvas.canvas()
    
    
    if circuit is ca.CIdentity:
        # simply create a line going through
        c.stroke(pyx.path.line(0, vunit/2, hunit, vunit/2))
        return c, (1, 1), (.5,), (.5,)
    
    elif isinstance(circuit, (ca.CircuitSymbol, ca.SeriesInverse, ca.SLH, Component, SubComponent)):
        # draw box
        b = pyx.path.rect(rhmargin * hunit, rvmargin * vunit, hunit - 2 * rhmargin * hunit, nc * vunit - 2 * rvmargin * vunit)
        c.stroke(b)
        
        texstr = "${}$".format(circuit.tex() if not isinstance(circuit, ca.SLH) else r"{{\rm SLH}}_{{{}}}".format(circuit.space.tex()))

        # draw symbol name
        c.text(hunit/2., nc * vunit/2., texstr , [pyx.text.halign.boxcenter, pyx.text.valign.middle])
        
        # draw connectors at half-unit positions
        connector_positions = tuple((.5 + k) for k in range(nc))
        for y in connector_positions:
            c.stroke(pyx.path.line(0, y * vunit, rhmargin * hunit, y * vunit), [pyx.deco.earrow()])
            c.stroke(pyx.path.line(hunit * (1 - rhmargin), y * vunit, hunit, y * vunit))
        
        return c, (1, nc), connector_positions, connector_positions
    
    elif isinstance(circuit, ca.CPermutation):
        permutation = circuit.permutation
        
        connector_positions = tuple((k + 0.5) for k in range(nc))
        target_positions = [connector_positions[permutation[k]] for k in range(nc)]
        
        # draw curves
        for y1, y2 in zip(connector_positions, target_positions):
            if permutation_arrows:
                c.stroke(_curve(0, y1, rpermutation_length, y2, hunit = hunit, vunit = vunit), [pyx.deco.earrow()])
            else:
                c.stroke(_curve(0, y1, rpermutation_length, y2, hunit = hunit, vunit = vunit))
         
        if draw_boxes:
            b = pyx.path.rect(.5* rhmargin * hunit, .5* rvmargin * vunit, rpermutation_length * hunit -  rhmargin * hunit, nc * vunit -  rvmargin * vunit)
            c.stroke(b, [pyx.style.linewidth.thin, pyx.style.linestyle.dashed, pyx.color.rgb.green])
            
        
        return c, (rpermutation_length, nc), connector_positions, connector_positions
    
    elif isinstance(circuit, ca.SeriesProduct):
        assert len(circuit.operands) > 1
        
        # generate graphics of operad subsystems
        sub_graphics = [draw_circuit_canvas(op, hunit = hunit,
                                        vunit = vunit, rhmargin = rhmargin,
                                        rvmargin = rvmargin,
                                        rpermutation_length = rpermutation_length,
                                        draw_boxes = draw_boxes,
                                        permutation_arrows = permutation_arrows) for op in reversed(circuit.operands)]
        
        # set up first one
        previous_csub, previous_dims, previous_c_in, previous_c_out = sub_graphics[0]
        hoffset = 0
        c.insert(previous_csub)
        hoffset += previous_dims[0]
        
        max_height = previous_dims[1]
        
        # this will later become the full series in-port coordinate tuple
        first_c_in = previous_c_in
        
        # now add all other operand subsystems
        for csub, dims, c_in, c_out in sub_graphics[1:]:
            assert dims[1] >= 0
            
            max_height = max(dims[1], max_height)
            
            if previous_c_out != c_in: # vertical port locations don't agree, map signals correspondingly
                
                x1 = hoffset
                x2 = hoffset + rpermutation_length
                
                # draw connection curves
                for y1, y2 in zip(previous_c_out, c_in):
                    c.stroke(_curve(x1, y1, x2, y2, hunit = hunit, vunit = vunit))
                
                hoffset += rpermutation_length
            
            previous_c_in, previous_c_out = c_in, c_out
            
            # now insert current system
            c.insert(csub, [pyx.trafo.translate(hunit * hoffset, 0)])
            hoffset += dims[0]
        if draw_boxes:
            b = pyx.path.rect(.5 * rhmargin * hunit, .5 * rvmargin * vunit, hoffset * hunit - 1. * rhmargin * hunit, max_height * vunit +  rvmargin * vunit)
            c.stroke(b, [pyx.style.linewidth.thin, pyx.style.linestyle.dashed, pyx.color.rgb.red])
        
        
        return c, (hoffset, max_height), first_c_in, c_out
    
    elif isinstance(circuit, ca.Concatenation):
        
        voffset = 0
        total_cin, total_cout = (), ()
        widths = [] # stores the component width for each channel(!)
        
        # generate all operand subsystem graphics and stack them vertically
        for op in circuit.operands:
            csub, dims, c_in, c_out = draw_circuit_canvas(op, hunit = hunit,
                                                    vunit = vunit, rhmargin = rhmargin,
                                                    rvmargin = rvmargin,
                                                    rpermutation_length = rpermutation_length,
                                                    draw_boxes = draw_boxes,
                                                    permutation_arrows = permutation_arrows)
            
            # add appropriatly offsets to vertical port coordinates
            total_cin += tuple(y + voffset for y in c_in)
            total_cout += tuple(y + voffset for y in c_out)
            
            
            c.insert(csub, [pyx.trafo.translate(0, vunit * voffset)])
            
            # keep track of width in all channel for this subsystem
            widths += [dims[0]] * op.cdim
            
            voffset += dims[1]
        
        max_width = max(widths)
        
        if max_width > min(widths): # components differ in width => we must extend the narrow component output lines
            
            for x,y in zip(widths, total_cout):
                if x == max_width:
                    continue
                
                
                ax, ax_to = x * hunit, max_width * hunit
                ay = y * vunit
                c.stroke(pyx.path.line(ax, ay, ax_to, ay))
                
        if draw_boxes:
            b = pyx.path.rect(.5 * rhmargin * hunit, .5 * rvmargin * vunit, max_width * hunit - 1. * rhmargin * hunit, voffset * vunit -  rvmargin * vunit)
            c.stroke(b, [pyx.style.linewidth.thin, pyx.style.linestyle.dashed, pyx.color.rgb.blue])
        
        return c, (max_width, voffset), total_cin, total_cout
    
    elif isinstance(circuit, ca.Feedback):
        
        # generate and insert graphics of subsystem
        csub, dims, c_in, c_out = draw_circuit_canvas(circuit.operand, hunit = hunit,
                                                vunit = vunit, rhmargin = rhmargin,
                                                rvmargin = rvmargin,
                                                rpermutation_length = rpermutation_length,
                                                draw_boxes = draw_boxes,
                                                permutation_arrows = permutation_arrows)
        
        c.insert(csub, [pyx.trafo.translate(hunit * .5 * rhmargin, 0)])
        width, height = dims
        
        # create feedback loop
        fb_out, fb_in = circuit.out_in_pair
        out_coords = (width + .5 * rhmargin) * hunit, c_out[fb_out] * vunit
        in_coords = .5 * rhmargin * hunit, c_in[fb_in] * vunit
        upper_y = (height) * vunit
        feedback_line = pyx.path.path(pyx.path.moveto(*out_coords), pyx.path.lineto(out_coords[0], upper_y),
                                        pyx.path.lineto(in_coords[0], upper_y), pyx.path.lineto(*in_coords))
        c.stroke(feedback_line)
        
        # remove feedback port coordinates
        new_c_in = c_in[:fb_in] + c_in[fb_in + 1 :]
        new_c_out = c_out[:fb_out] + c_out[fb_out + 1 :]
        
        # extend port connectors a little bit outward,
        # such that the feedback loop is not at the edge anymore
        for y in new_c_in:
            c.stroke(pyx.path.line(0, y * vunit, .5 * rhmargin * hunit, y * vunit))
        
        for y in new_c_out:
            c.stroke(pyx.path.line((width + .5 * rhmargin) * hunit, y * vunit, (width + rhmargin) * hunit, y * vunit))
        
        return c, (width + rhmargin, height + rvmargin), new_c_in, new_c_out
    
    raise Exception('Visualization not implemented for type %s' % type(circuit))
예제 #10
0
 def testFeedback(self):
     self.assertEqual(parse_circuit_strings('[M(5)]_(3->4)'), Feedback(CircuitSymbol('M',5), 3, 4))
예제 #11
0
 def testNested(self):
     self.assertEqual(parse_circuit_strings('a(2) <<  (b(1) + c(1))'), SeriesProduct(CircuitSymbol('a',2),Concatenation(CircuitSymbol('b',1), CircuitSymbol('c',1))))
     self.assertEqual(parse_circuit_strings('a(2) +  (b(1) << c(1))'), Concatenation(CircuitSymbol('a',2),SeriesProduct(CircuitSymbol('b',1), CircuitSymbol('c',1))))
     self.assertEqual(parse_circuit_strings('[a(2) +  (b(1) << c(1))]_(2->0)'), Feedback(Concatenation(CircuitSymbol('a',2),SeriesProduct(CircuitSymbol('b',1), CircuitSymbol('c',1))),2,0))
예제 #12
0
 def testCIdentity(self):
     self.assertEqual(parse_circuit_strings('cid(1)'), CIdentity)
     self.assertEqual(parse_circuit_strings('cid(5)'), cid(5))
예제 #13
0
 def testConcatenation(self):
     self.assertEqual(parse_circuit_strings('a(1) +  b(2)'), Concatenation(CircuitSymbol('a',1),CircuitSymbol('b',2)))
     self.assertEqual(parse_circuit_strings('a(1) +  b(2) + c(3)'), Concatenation(CircuitSymbol('a',1),CircuitSymbol('b',2),CircuitSymbol('c',3)))
예제 #14
0
 def testSeries(self):
     self.assertEqual(parse_circuit_strings('a(2) <<  b(2)'), SeriesProduct(CircuitSymbol('a',2),CircuitSymbol('b',2)))
     self.assertEqual(parse_circuit_strings('a(5) <<  b(5) << c(5)'), SeriesProduct(CircuitSymbol('a',5),CircuitSymbol('b',5),CircuitSymbol('c',5)))
예제 #15
0
 def testCPermutation(self):
     self.assertEqual(parse_circuit_strings('P_sigma(0,2,1)'), CPermutation((0,2,1)))
     self.assertEqual(parse_circuit_strings('P_sigma(0,2,1,4,3)'), CPermutation((0,2,1,4,3)))
예제 #16
0
 def testSymbol(self):
     self.assertEqual(parse_circuit_strings('a(2)'), CircuitSymbol('a', 2))
     self.assertEqual(parse_circuit_strings('a(5)'), CircuitSymbol('a', 5))
     self.assertEqual(parse_circuit_strings('a_longer_string(5)'), CircuitSymbol('a_longer_string', 5))