def __init__(self, **options): # inherit from the base class Group.__init__(self, **options) # process the options if any self.fg = options.get("fg", self.fg) self.bg = options.get("bg", self.bg) self.height = options.get("height", self.height) self.width = options.get("width", self.width) self.angle = options.get("angle", self.angle) # make the laser laser = Group() laser.append( Path(P(0, 0), P(0, self.height), P(self.width, self.height), P(self.width, 0), closed=1, fg=self.fg, bg=self.bg)) # rotate if necessary laser.rotate(self.angle, p=laser.bbox().c) self.append(laser)
def __init__(self, **options): # inherit from base class Group.__init__(self, **options) # process the options if any self.width = options.get("width", self.width) self.height = options.get("height", self.height) self.angle = options.get("angle", self.angle) self.fg = options.get("fg", self.fg) self.bg = options.get("bg", self.bg) # now make the phase shifter ps = Path( P(0, 0), P(self.width / 2.0, self.height), P(self.width, 0), closed=1, fg=self.fg, bg=self.bg, ) # rotate if necessary if self.angle != 0: ps.rotate(self.angle, p=ps.bbox().c) self.append(ps)
def __init__(self, **options): # inherit from the base class Group.__init__(self, **options) # process the options if any self.fg = options.get("fg", self.fg) self.bg = options.get("bg", self.bg) self.height = options.get("height", self.height) self.thickness = options.get("thickness", self.thickness) self.angle = options.get("angle", self.angle) # make the beam splitter bs = Group() bs.append( Path(P(0, 0), P(0, self.height), P(self.thickness, self.height), P(self.thickness, 0), closed=1, fg=self.fg, bg=self.bg)) # rotate if necessary bs.rotate(self.angle, p=bs.bbox().c) self.append(bs)
def SWAP(**options): """ Swap gate """ x = Group(Path(P(-.1, .1), P(.1, -.1)), Path(P(-.1, -.1), P(.1, .1))) options['controlobj'] = options.get('controlobj', x) return Gate(x, **options)
def __init__(self, **options): # inherit from the base class Group.__init__(self, **options) # process the options if any self.fg = options.get("fg", self.fg) self.bg = options.get("bg", self.bg) self.height = options.get("height", self.height) self.width = options.get("width", self.width) self.angle = options.get("angle", self.angle) # make the free space fs = Group() fs.append( Path(P(0, 0), P(0, self.height), P(self.width, self.height), P(self.width, 0), closed=1, fg=self.fg, bg=self.bg, dash=Dash())) # rotate if necessary fs.rotate(self.angle, p=fs.bbox().c) self.append(fs)
def NOT(**options): """ NOT gate """ r = .2 return Gate( Group(Circle(r=r), Path(P(0, r), P(0, -r)), Path(P(-r, 0), P(r, 0))), **options)
def set(self, y, e, w): """ Set the east, west and y postions of the QWire """ path = Path(P(w, y), P(e, y), fg=self.fg, linewidth=self.linewidth, dash=self.dash) self.append(path) return self
def __init__(self, **options): # initialise the base class Gate.__init__(self, **options) # process the options if any self.height = options.get("height", self.height) self.width = options.get("width", self.width) self.angle = options.get("angle", self.angle) self.pinLength = options.get("pinLength", self.pinLength) self.fg = options.get("fg", self.fg) self.bg = options.get("bg", self.bg) # now draw the gate buff = 0 pl = self.pinLength pinEdgeDist = 0.1*self.height bodyHeight = self.height bodyWidth = self.width - 2.0*pl rad = 0.1 gateBody = Group( Path( P(pl, buff+0), P(pl, buff+bodyHeight), P(pl+0.707106781*bodyWidth, buff+bodyHeight/2.), P(pl, buff+0) ) ) gatePinIn1 = Path( P(0, bodyHeight-pinEdgeDist), P(pl, bodyHeight-pinEdgeDist)) gatePinIn2 = Path( P(0, pinEdgeDist), P(pl, pinEdgeDist)) gatePinOut = Group( Circle(w=gateBody.e, r=rad), Path( gateBody.e+P(2.*rad, 0), gateBody.e+P(2.*rad+pl, 0)) ) # collect the objects together obj = Group(gateBody, gatePinIn1, gatePinIn2, gatePinOut) # apply the colours obj.apply(fg=self.fg, bg=self.bg) # rotate if necessary if self.angle != 0.0: obj.rotate(self.angle, p=obj.c) # now set the object to myself self.append(obj)
def __init__(self, **options): # initialise the base class Gate.__init__(self, **options) # process the options if any self.height = options.get("height", self.height) self.width = options.get("width", self.width) self.angle = options.get("angle", self.angle) self.pinLength = options.get("pinLength", self.pinLength) self.fg = options.get("fg", self.fg) self.bg = options.get("bg", self.bg) # now draw the gate pl = self.pinLength pinEdgeDist = 0.1*self.height pinBackDist = -0.08*self.width bodyHeight = self.height bodyWidth = self.width - 2.0*pl rad = 0.1 gateBody = Group( Path( P(-pinBackDist, -pinEdgeDist), C(90, 225), P(1.25*bodyWidth, bodyHeight/2.0), C(-45, 90), P(-pinBackDist, bodyHeight+pinEdgeDist), C(140, 40), closed=1, ) ) gatePinIn1 = Path( P(0, bodyHeight-pinEdgeDist), P(pl, bodyHeight-pinEdgeDist)) gatePinIn2 = Path( P(0, pinEdgeDist), P(pl, pinEdgeDist)) gatePinOut = Group( Circle(w=gateBody.e, r=rad), Path( gateBody.e+P(0.2, 0), gateBody.e+P(pl+0.2, 0)), ) # collect the objects together obj = Group(gateBody, gatePinIn1, gatePinIn2, gatePinOut) # apply the colours obj.apply(fg=self.fg, bg=self.bg) # rotate if necessary if self.angle != 0.0: obj.rotate(self.angle, p=obj.c) # nwo set the object to myself self.append(obj)
def __init__(self, **options): Group.__init__(self, **options) p = Group() self.fg = options.get("fg", self.fg) self.bg = options.get("bg", self.bg) if self.width > self.height: p.append( Path(P(0, 0), P(0, self.height), P(self.width - self.height / 2.0, self.height), C(90, 0), P(self.width, self.height / 2.0), C(180, 90), P(self.width - self.height / 2.0, 0), fg=self.fg, bg=self.bg, closed=1)) else: p.append( Path(P(0, 0), P(0, self.height), C(90, 0), P(self.width, self.height / 2.0), C(180, 90), closed=1)) # rotate if necessary self.angle = options.get("angle", self.angle) p.rotate(self.angle, p=p.bbox().c) self.append(p)
def Detector(e=P(0, 0), height=1.0, label=None): """ Detector @param height: height of detector @type height: float @param label: detector label @type label: string """ if label is not None: return Group(Path(e - P(0, height / 2.0), e + P(0, height / 2.0)), Circle(c=e, r=height / 2.0, start=0, end=180), label) else: return Group(Path(e - P(0, height / 2.0), e + P(0, height / 2.0)), Circle(c=e, r=height / 2.0, start=0, end=180))
def __init__(self, tobj, **options): Group.__init__(self, **options) # XXX should we take a copy??? self.targetobj = tobj.copy() if self.controlobj is None: self.controlobj = Dot(r=self.dot_r) # fix up target and control points if type(self.target) in (type(()), type([])): pass elif isinstance(self.target, P): self.target = [self.target] elif self.target is None: self.target = [P(0, 0)] else: raise ValueError, "don't understand target structure for Gate" if type(self.control) in (type(()), type([])): pass elif isinstance(self.control, P): self.control = [self.control] elif self.control is None: self.control = [] else: raise ValueError, "don't understand control structure for Gate" self._make()
def CZGate(c=P(0, 0), controlDist=1.0, direction="up", side=0.5): """ Controlled Z gate @param controlDist: distance to the control @type controlDist: float @param direction: in which direction is the control? up/down @type direction: string @param side: length of the box side @type side: float """ if direction is "up": return Group( Circle(c=c + P(0, controlDist), r=0.065, bg=Color("black")), Path(c + P(0, side / 2.), c + P(0, controlDist)), Rectangle(width=side, height=side, c=c, bg=Color("white")), TeX(r'Z', c=c)) elif direction is "down": return Group( Circle(c=c - P(0, controlDist), r=0.65, bg=Color("black")), Path(c - P(0, side / 2.), c - P(0, controlDist)), Rectangle(width=side, height=side, c=c, bg=Color("white")), TeX(r'Z', c=c))
def ZGate(c=P(0, 0), side=0.5): """ Z gate @param side: length of the box side @type side: float """ return Group(Rectangle(width=side, height=side, c=c, bg=Color("white")), TeX(r'Z', c=c))
def Cnot(c=P(0, 0), targetDist=1.0, direction="up"): """ Controlled NOT gate @param targetDist: distance to the target rail @type targetDist: float @param direction: in which direction is the target rail? up/down @type direction: string """ if direction is "up": return Group(Circle(r=0.06, bg=Color("black"), c=c), Circle(r=0.2, c=c + P(0, targetDist)), Path(c, c + P(0, targetDist + 0.2))) elif direction is "down": return Group(Circle(r=0.06, bg=Color("black"), c=c), Circle(r=0.2, c=c + P(0, -targetDist)), Path(c, c + P(0, -targetDist - 0.2)))
def __init__(self, **options): # inherit from the base class Group.__init__(self, **options) # process the options if any self.fg = options.get("fg", self.fg) self.bg = options.get("bg", self.bg) self.height = options.get("height", self.height) self.thickness = options.get("thickness", self.thickness) self.angle = options.get("angle", self.angle) self.type = options.get("type", self.type) # determine what type of lens to make if self.type == "convex": leftCurveAngle = -30 rightCurveAngle = -30 elif self.type == "concave": leftCurveAngle = 30 rightCurveAngle = 30 else: print "Unknown lens type, defaulting to concave" leftCurveAngle = 30 rightCurveAngle = 30 # make the lens lens = Group() lens.append( Path( P(0, 0), C(leftCurveAngle, 180 - leftCurveAngle), P(0, self.height), P(self.thickness, self.height), C(-180 + rightCurveAngle, -rightCurveAngle), P(self.thickness, 0), closed=1, fg=self.fg, bg=self.bg, )) # rotate if necessary lens.rotate(self.angle, p=lens.bbox().c) self.append(lens)
def __init__(self, **options): # intitialise base class Group.__init__(self, **options) self.length = 3.0 self.width = 1.0 self.angle = 0.0 self.pinLength = 0.5 self.fg = Color(0) self.bg = Color(1) # process the options if any self.length = options.get("length", self.length) self.width = options.get("width", self.width) self.angle = options.get("angle", self.angle) self.pinLength = options.get("pinLength", self.pinLength) self.fg = options.get("fg", self.fg) self.bg = options.get("bg", self.bg) pinIn = Group( Path( P(0, 0), P(self.pinLength, 0) ) ) resistor = Rectangle(w=pinIn.e, width=self.length, height=self.width) pinOut = Path( resistor.e, resistor.e+P(self.pinLength, 0)) # collect the objects together obj = Group(pinIn, pinOut, resistor) # apply the colours obj.apply(fg=self.fg, bg=self.bg) # rotate if necessary if self.angle != 0.0: obj.rotate(self.angle, p=obj.c) # return object to myself self.append(obj)
def setgate(self, gate, target, control=None): """ Set the gate in the assembly """ # if it already an instance this will have no effect # otherwise create an instance gate = apply(gate) # XXX multi target qubits gate.settarget(P(0, -target)) if isinstance(control, (IntType, FloatType)): gate.setcontrol(P(0, -control)) elif isinstance(control, (TupleType, ListType)): tmp = [] for cc in control: tmp.append(P(0, -cc)) apply(gate.setcontrol, tmp) return gate
def __init__(self, obj, **options): bbox = obj.bbox() pad = .1 r = max(bbox.width + 2 * pad, bbox.height + 2 * pad) / 2.0 self.width = 2.0 * r self.height = 2.0 * r self.bg = options.get('bg', Color(1)) if options.has_key('bg'): del options['bg'] apply(Group.__init__, (self, ), options) apply(Area.__init__, (self, ), options) obj.c = P(r, r) self.append( Circle(r=r, bg=self.bg, c=P(r, r)), obj, )
def cbox(obj, x, yt, yc): ''' @param obj: the object to put a box around @type obj: object @param x: x position of line and centre of box @type x: float @param yt: y position of target @type yt: float @param yc: y position of control @type yc: float @return: a controlled box ''' g = Group( Path(P(x, yt), P(x, yc)), Boxed(obj, c=P(x, yt), bg=Color(1)), Dot(P(x, yc)), ) return g
def __init__(self, **args): Group.__init__(self, **args) h = self.height w = self.width self.append(Rectangle(width=1.8 * h, height=h, bg=self.bg)) p = Path(P(.1, .1), C(0, 0), P(w - .1, .1), P(w - .2, .1), C(0, 0), P(.2, .1), closed=1, bg=self.mcolor, fg=None) self.append( p, Path(P(w / 2., .1), U(self.angle, h * .9)), )
def detector(**options): ''' @return: a D shaped detector ''' r = 0.3 c = 0.65 * r path = [ P(0, -r), P(0, r), C(P(c, r), P(r, c)), P(r, 0), C(P(r, -c), P(c, -r)), P(0, -r) ] options['bg'] = options.get('bg', Color(.8)) options['closed'] = 1 p = apply(Path, path, options) a = Area(width=r, height=2 * r, e=P(0, 0)) return Group(a, p)
def __init__(self, object=None, **options): if object is not None: # use the object's boundingbox when width and height not supplied bb = object.bbox() w = bb.width + 2 * self.pad h = bb.height + 2 * self.pad self.width = options.get("width", max(w, self.width)) self.height = options.get("height", max(h, self.height)) Group.__init__(self, **options) if self.width > self.height: p = Path(P(0, 0), P(0, self.height), P(self.width - self.height / 2., self.height), C(90, 0), P(self.width, self.height / 2.), C(180, 90), P(self.width - self.height / 2., 0), closed=1) else: p = Path(P(0, 0), P(0, self.height), C(90, 0), P(self.width, self.height / 2.), C(180, 90), closed=1) p(bg=options.get("bg", self.bg), fg=options.get("fg", self.fg)) self.append(p) if object is not None: # object looks better if it's slightly off centre # since one side is curved. pad/3 is about right object.c = P(self.width / 2. - self.pad / 3., self.height / 2.) self.append(object)
def __init__(self, **options): # intitialise base class Group.__init__(self, **options) self.sep = 0.25 self.width = 1.0 self.angle = 0.0 self.pinLength = 0.5 self.fg = Color(0) self.bg = Color(1) # process the options if any self.sep = options.get("sep", self.sep) self.width = options.get("width", self.width) self.angle = options.get("angle", self.angle) self.pinLength = options.get("pinLength", self.pinLength) self.fg = options.get("fg", self.fg) self.bg = options.get("bg", self.bg) pinIn = Group( Path( P(0, 0), P(self.pinLength, 0), ) ) cap = Group( Path(pinIn.e+P(0, -self.width/2.0), pinIn.e+P(0, self.width/2.0)), Path(pinIn.e+P(self.sep, -self.width/2.0), pinIn.e+P(self.sep, self.width/2.0)), ) pinOut = Path( cap.e, cap.e+P(self.pinLength, 0)) # group the objects together obj = Group(pinIn, pinOut, cap) # apply the colours obj.apply(fg=self.fg, bg=self.bg) # rotate if necessary if self.angle != 0.0: obj.rotate(self.angle, p=obj.c) # set the object to myself self.append(obj)
def background(self): ''' Return background for poster ''' area = self.area() signature = Text( 'Created with PyScript. http://pyscript.sourceforge.net', size=14, fg=Color(1)) signature.se = area.se + P(-.5, .5) return Group( Rectangle(width=area.width, height=area.height, fg=None, bg=self.bg), signature, )
def __init__(self, obj, **options): bbox = obj.bbox() pad = .1 w = bbox.width + 2 * pad h = bbox.height + 2 * pad self.width = w self.height = h self.bg = options.get('bg', Color(1)) if options.has_key('bg'): del options['bg'] apply(Group.__init__, (self, ), options) apply(Area.__init__, (self, ), options) obj.c = P(w / 2., h / 2.) self.append( Rectangle(width=w, height=h, bg=self.bg), obj, )
def __init__(self, **options): # inherit from the base class Group.__init__(self, **options) # process the options if any self.fg = options.get("fg", self.fg) self.bg = options.get("bg", self.bg) self.length = options.get("length", self.length) self.thickness = options.get("thickness", self.thickness) self.angle = options.get("angle", self.thickness) self.flicks = options.get("flicks", self.flicks) # make the mirror itself mirror = Group() mirror.append( Path(P(0, 0), P(0, self.length), P(self.thickness, self.length), P(self.thickness, 0), closed=1, fg=self.fg, bg=self.bg)) if self.flicks: # make the flicks on the back of the mirror flickLen = 0.15 flicksObj = Group() for i in range(10): flicksObj.append( Path(P((i + 1.0) * self.length / 10.0, self.thickness), P(i * self.length / 10.0, self.thickness + flickLen), fg=self.fg, bg=self.bg)) mirror.append(flicksObj) # rotate the mirror if necessary if self.angle != 0.0: mirror.rotate(self.angle, p=mirror.bbox().c) # make the mirror the current object self.append(mirror)
def Rail(w=P(0, 0), length=1.0, labelIn=None, labelOut=None, buff=0.05): """ A Rail of a quantum circuit diagram @param length: length of the rail @type length: float @param labelIn: input label @type labelIn: string @param labelOut: output label @type labelOut: string @param buff: buffer of space between the end of the rail and the label @type buff: float """ if labelIn is not None and labelOut is not None: return Group(Path(w + P(0, 0), w + P(length, 0)), TeX(labelIn, e=w - P(buff, 0)), TeX(labelOut, w=w + P(buff + length, 0))) elif labelIn is not None and labelOut is None: return Group(Path(w + P(0, 0), w + P(length, 0)), TeX(labelIn, e=w - P(buff, 0))) elif labelIn is None and labelOut is not None: return Group(Path(w + P(0, 0), w + P(length, 0)), TeX(labelOut, w=w + P(buff + length, 0))) else: return Group(Path(w + P(0, 0), w + P(length, 0)))
def __init__(self, *gates, **options): self.starthang = options.get('hang', self.hang) self.endhang = options.get('hang', self.hang) Group.__init__(self, **options) sequence = list(gates) # parse the list ... wires = [] named = {} basetime = 0 while len(sequence) > 0: # the gate ... gate = sequence.pop(0) # the target ... t = sequence.pop(0) wires.append(t) # optional controls ... if len(sequence) > 0 and \ isinstance(sequence[0], (IntType, FloatType)): c = sequence.pop(0) wires.append(c) elif len(sequence) > 0 and \ isinstance(sequence[0], (TupleType, ListType)): c = sequence.pop(0) wires.extend(c) else: c = None g = self.setgate(gate, t, c) # optional time label ... if len(sequence) > 0 and isinstance(sequence[0], StringType): l = sequence.pop(0) if named.has_key(l): # group already exists named[l].append(g) else: # create new named group G = named[l] = Group(g) self.append(G) else: self.append(g) L = 0 for ii in self: L += ii.width + self.gatespacing L -= self.gatespacing # XXX add distribute's options Distribute(self, p1=P(0, 0), p2=P(L, 0)) self.recalc_size() # XXX should check wires are ints # add wires ... x0 = self.w.x - self.starthang x1 = self.e.x + self.endhang if len(self.wires) == 0: for w in range(-min(wires), -max(wires) - 1, -1): wire = QWire().set(w * self.wirespacing, x0, x1) self.insert(0, wire) self.wires.append(wire) print self.wires else: #w=-int(min(wires)) w = -1 wirestmp = [] for wire in self.wires: # if it already an instance this will have no effect # otherwise create an instance wire = apply(wire, ()) wire.set(w * self.wirespacing, x0, x1) self.insert(0, wire) wirestmp.append(wire) w -= 1 self.wires = wirestmp
def BS(sw=P(0, 0), label=None, h=1.0): """ Beam splitter; displayed as a line possibly more useful in linear optics quantum computation diagrams @param sw: location of the south-west corner of the object @type sw: L{P} object @param label: beam splitter label @type label: string @param h: beam splitter height @type h: float """ buff = P(0, 0.1) b = Path(sw - buff, sw + P(0, h) + buff, sw + P(h, h) + buff, sw + P(h, 0) - buff, sw - buff, fg=None, bg=Color("white")) p1 = Path(sw, sw + P(h, h)) p2 = Path(sw + P(0, h), sw + P(h, 0)) p3 = Path(sw + P(h / 4, h / 2), sw + P(h, 0) + P(-h / 4, h / 2), linewidth=1) if label is not None: label['w'] = sw + P(h, 0) + P(-h / 4, h / 2) return Group(b, p1, p2, p3, label) else: return Group(b, p1, p2, p3)