Пример #1
0
def _decompose_QPE(cmd):
    """ Decompose the Quantum Phase Estimation gate. """
    eng = cmd.engine

    # Ancillas is the first qubit/qureg. System-qubit is the second qubit/qureg
    qpe_ancillas = cmd.qubits[0]
    system_qubits = cmd.qubits[1]

    # Hadamard on the ancillas
    Tensor(H) | qpe_ancillas

    # The Unitary Operator
    U = cmd.gate.unitary

    # Control U on the system_qubits
    if (callable(U)):
        # If U is a function
        for i in range(len(qpe_ancillas)):
            with Control(eng, qpe_ancillas[i]):
                U(system_qubits, time=2**i)
    else:
        for i in range(len(qpe_ancillas)):
            ipower = int(2**i)
            with Loop(eng, ipower):
                with Control(eng, qpe_ancillas[i]):
                    U | system_qubits

    # Inverse QFT on the ancillas
    get_inverse(QFT) | qpe_ancillas
def _decompose_parity_measurement(cmd):
    ancilla = cmd.engine.allocate_qubit()
    for pos, action in cmd.gate._bases:
        qureg = Qureg([cmd.qubits[0][pos]])
        if action == "X":
            H | cmd.qubits[0][pos]
            with Control(cmd.engine, qureg):
                X | ancilla
            H | cmd.qubits[0][pos]

        elif action == "Y":
            H | cmd.qubits[0][pos]
            S | cmd.qubits[0][pos]
            with Control(cmd.engine, qureg):
                X | ancilla
            get_inverse(S) | cmd.qubits[0][pos]
            H | cmd.qubits[0][pos]
        elif action == "Z":
            with Control(cmd.engine, qureg):
                X | ancilla

    # if there is a minus sign
    if (cmd.gate._is_inverted):
        X | ancilla

    # at last measure the parity:
    Measure | ancilla
Пример #3
0
def _decompose_QPE(cmd):  # pylint: disable=invalid-name
    """Decompose the Quantum Phase Estimation gate."""
    eng = cmd.engine

    # Ancillas is the first qubit/qureg. System-qubit is the second qubit/qureg
    qpe_ancillas = cmd.qubits[0]
    system_qubits = cmd.qubits[1]

    # Hadamard on the ancillas
    Tensor(H) | qpe_ancillas

    # The Unitary Operator
    unitary = cmd.gate.unitary

    # Control U on the system_qubits
    if callable(unitary):
        # If U is a function
        for i, ancilla in enumerate(qpe_ancillas):
            with Control(eng, ancilla):
                unitary(system_qubits, time=2**i)
    else:
        for i, ancilla in enumerate(qpe_ancillas):
            ipower = int(2**i)
            with Loop(eng, ipower):
                with Control(eng, ancilla):
                    unitary | system_qubits

    # Inverse QFT on the ancillas
    get_inverse(QFT) | qpe_ancillas
Пример #4
0
def observe(agent_memory, qureg, reverse=False):
    assert len(agent_memory) >= len(qureg), 'Invalid observe. Observed system is larger than what memory ' \
                                            'of the agent can hold.'
    if reverse:
        get_inverse(Add) | (qureg, agent_memory)
    else:
        Add | (qureg, agent_memory)
Пример #5
0
def test_s_gate():
	gate = _gates.SGate()
	assert str(gate) == "S"
	assert np.array_equal(gate.matrix, np.matrix([[1, 0], [0, 1j]]))
	assert isinstance(_gates.S, _gates.SGate)
	assert type(_gates.Sdag) == type(get_inverse(gate))
	assert type(_gates.Sdagger) == type(get_inverse(gate))
Пример #6
0
def run_phase_estimation(eng, U, state, m, n):
    """
    Phase estimation algorithm on unitary U. 

    Args:
        eng (MainEngine): Main compiler engine to run the phase_estimation algorithm
        U (np.matrix): the unitary that is to be estimated
        state (qureg): the input state, which has the form |psi> otimes |0>.
                        State is composed of two parts: 
                            1. The first n qubits are the input state |psi>, which is commonly
                               chosen to be the eigenstate of U
                            2. The last n qubits are initialized to |0>, which is used to 
                               store the binary digits of the estimated phase
        m (int): number of qubits for input state psi
        n (int): number of qubits used to store the phase to given precision
    """
    # The beginning index for the phase qubits will have an offset
    OFFSET = m
    # Phase 1. performs the controlled U^{2^j} operations
    for k in range(n):
        H | state[OFFSET + k]

        with Control(eng, state[OFFSET + k]):
            # number of loops required to perfrom the controlled U^{2^j} operation
            num = int(math.pow(2, k))
            # use the buildin loop
            with Loop(eng, num):
                U | state[:OFFSET]

    # Phase 2. performs the inverse QFT operation
    # Step 2.1 swap the qubits
    for k in range(int(math.floor(n / 2))):
        Swap | (state[OFFSET + k], state[OFFSET + n - k - 1])
    # Step 2.2 perfrom the original inverse QFT
    get_inverse(QFT) | state[OFFSET:]
Пример #7
0
def test_t_gate():
	gate = _gates.TGate()
	assert str(gate) == "T"
	assert np.array_equal(gate.matrix, 
	                np.matrix([[1, 0], [0, cmath.exp(1j * cmath.pi / 4)]]))
	assert isinstance(_gates.T, _gates.TGate)
	assert type(_gates.Tdag) == type(get_inverse(gate))
	assert type(_gates.Tdagger) == type(get_inverse(gate))
Пример #8
0
def test_body():
    drawer = _drawer.CircuitDrawer()
    eng = MainEngine(drawer, [])
    old_tolatex = _drawer.to_latex
    _drawer.to_latex = lambda x: x

    qubit1 = eng.allocate_qubit()
    qubit2 = eng.allocate_qubit()
    qubit3 = eng.allocate_qubit()
    H | qubit1
    H | qubit2
    CNOT | (qubit1, qubit2)
    X | qubit2
    Measure | qubit2
    CNOT | (qubit2, qubit1)
    Z | qubit2
    C(Z) | (qubit1, qubit2)
    C(Swap) | (qubit1, qubit2, qubit3)
    SqrtX | qubit1
    SqrtSwap | (qubit1, qubit2)
    get_inverse(SqrtX) | qubit1
    C(SqrtSwap) | (qubit1, qubit2, qubit3)
    get_inverse(SqrtSwap) | (qubit1, qubit2)
    C(Swap) | (qubit3, qubit1, qubit2)
    C(SqrtSwap) | (qubit3, qubit1, qubit2)

    del qubit1
    eng.flush()

    circuit_lines = drawer.get_latex()
    _drawer.to_latex = old_tolatex

    settings = _to_latex.get_default_settings()
    settings['gates']['AllocateQubitGate']['draw_id'] = True
    code = _to_latex._body(circuit_lines, settings)

    # swap draws 2 nodes + 2 lines each, so is sqrtswap gate, csqrtswap,
    # inv(sqrt_swap), and cswap.
    assert code.count("swapstyle") == 36
    # CZ is two phases plus 2 from CNOTs + 2 from cswap + 2 from csqrtswap
    assert code.count("phase") == 8
    assert code.count("{{{}}}".format(str(H))) == 2  # 2 hadamard gates
    assert code.count("{$\Ket{0}") == 3  # 3 qubits allocated
    # 1 cnot, 1 not gate, 3 SqrtSwap, 1 inv(SqrtSwap)
    assert code.count("xstyle") == 7
    assert code.count("measure") == 1  # 1 measurement
    assert code.count("{{{}}}".format(str(Z))) == 1  # 1 Z gate
    assert code.count("{red}") == 3
Пример #9
0
def high_level_gates(eng, cmd):
    g = cmd.gate
    if g == QFT or get_inverse(g) == QFT or g == Swap:
        return True
    if isinstance(g, BasicMathGate):
        return False
    return eng.next_engine.is_available(cmd)
Пример #10
0
    def perform_simulation(self):
        for gate in reversed(self._gates):
            self._simulator.apply_operation(gates.get_inverse(gate))

        for bases, qubits, parity in self._simulator.return_stabilizers():
            cmd = projqube.projectq.ops.ParityMeasurementGate(bases, parity).generate_command(qubits)
            self.send([cmd])
Пример #11
0
def quanutm_phase_estimation(eng):

    All(H) | phase_reg

    with Control(eng, phase_reg[0]):
        run_qnn(eng)

    with Control(eng, phase_reg[1]):
        with Loop(eng, 2):
            run_qnn(eng)

    with Control(eng, phase_reg[2]):
        with Loop(eng, 4):
            run_qnn(eng)

    Swap | (phase_reg[0], phase_reg[2])

    get_inverse(QFT) | phase_reg
    def _all_decomps_for(self, cmd):
        key = cmd.gate.__class__.__name__
        inv_key = get_inverse(cmd.gate).__class__.__name__
        ds = self.decomposition_rule_set.decompositions

        forward = ds[key] if key in ds else []
        backward = [d.get_inverse_decomposition()
                    for d in ds[inv_key]] if inv_key in ds else []

        return [d for d in forward + backward if d.check(cmd)]
Пример #13
0
def high_level_gates(eng, cmd):  # pylint: disable=unused-argument
    """Remove any MathGates."""
    gate = cmd.gate
    if eng.next_engine.is_available(cmd):
        return True
    if gate == QFT or get_inverse(gate) == QFT or gate == Swap:
        return True
    if isinstance(gate, BasicMathGate):
        return False
    return True
Пример #14
0
def high_level_gates(eng, cmd):
    """
    Remove any MathGates.
    """
    g = cmd.gate
    if g == QFT or get_inverse(g) == QFT or g == Swap:
        return True
    elif isinstance(g, BasicMathGate):
        return False
    return True
Пример #15
0
def high_level_gates(eng, cmd):
    g = cmd.gate
    if g == QFT or get_inverse(g) == QFT or g == Swap:
        return True
    if isinstance(g, BasicMathGate):
        return False # False - http://projectq.readthedocs.io/en/latest/examples.html#shor-s-algorithm-for-factoring
        if isinstance(g, AddConstant):
            return True
        elif isinstance(g, AddConstantModN):
            return True
        return False
    return eng.next_engine.is_available(cmd)
def GetHighLevelGates(eng, cmd):
    g = cmd.gate
    if g == QFT or get_inverse(g) == QFT or g == Swap:
        return True
    if isinstance(g, BasicMathGate):
        return False
        if isinstance(g, AddConstant):
            return True
        elif isinstance(g, AddConstantModN):
            return True
        return False
    return eng.next_engine.is_available(cmd)
Пример #17
0
def test_high_level_gate_set():
    mod_list = projectq.setups.ibm16.get_engine_list()
    saving_engine = DummyEngine(save_commands=True)
    mod_list = mod_list[:6] + [saving_engine] + mod_list[6:]
    eng = MainEngine(DummyEngine(), engine_list=mod_list)
    qureg = eng.allocate_qureg(3)
    AddConstant(3) | qureg
    QFT | qureg
    eng.flush()
    received_gates = [cmd.gate for cmd in saving_engine.received_commands]
    assert sum([1 for g in received_gates if g == QFT]) == 1
    assert get_inverse(QFT) not in received_gates
    assert AddConstant(3) not in received_gates
Пример #18
0
def high_level_gates(eng, cmd):
    """Filter high-level gates."""
    g = cmd.gate
    if g == QFT or get_inverse(g) == QFT or g == Swap:
        return True
    if isinstance(g, BasicMathGate):
        return False
        if isinstance(g, AddConstant):
            return True
        elif isinstance(g, AddConstantModN):
            return True
        return False
    return eng.next_engine.is_available(cmd)
Пример #19
0
    def _process_command(self, cmd):
        """
        Check whether a command cmd can be handled by further engines and,
        if not, replace it using the decomposition rules loaded with the setup
        (e.g., setups.default).

        Args:
            cmd (Command): Command to process.

        Raises:
            Exception if no replacement is available in the loaded setup.
        """
        if self.is_available(cmd):
            self.send([cmd])
        else:
            # check for decomposition rules
            decomp_list = []
            potential_decomps = []
            inv_list = []

            # check for forward rules
            cls = cmd.gate.__class__.__name__
            try:
                potential_decomps = [
                    d for d in self.decompositionRuleSet.decompositions[cls]
                ]
            except KeyError:
                pass
            # check for rules implementing the inverse gate
            # and run them in reverse
            inv_cls = get_inverse(cmd.gate).__class__.__name__
            try:
                potential_decomps += [
                    d.get_inverse_decomposition()
                    for d in self.decompositionRuleSet.decompositions[inv_cls]
                ]
            except KeyError:
                pass
            # throw out the ones which don't recognize the command
            for d in potential_decomps:
                if d.check(cmd):
                    decomp_list.append(d)

            if len(decomp_list) == 0:
                raise NoGateDecompositionError("\nNo replacement found for "
                                               + str(cmd) + "!")

            # use decomposition chooser to determine the best decomposition
            chosen_decomp = self._decomp_chooser(cmd, decomp_list)

            # the decomposed command must have the same tags
            # (plus the ones it gets from meta-statements inside the
            # decomposition rule).
            # --> use a CommandModifier with a ForwarderEngine to achieve this.
            old_tags = cmd.tags[:]

            def cmd_mod_fun(cmd):  # Adds the tags
                cmd.tags = old_tags[:] + cmd.tags
                cmd.engine = self.main_engine
                return cmd
            # the CommandModifier calls cmd_mod_fun for each command
            # --> commands get the right tags.
            cmod_eng = CommandModifier(cmd_mod_fun)
            cmod_eng.next_engine = self  # send modified commands back here
            cmod_eng.main_engine = self.main_engine
            # forward everything to cmod_eng using the ForwarderEngine
            # which behaves just like MainEngine
            # (--> meta functions still work)
            forwarder_eng = ForwarderEngine(cmod_eng)
            cmd.engine = forwarder_eng  # send gates directly to forwarder
            # (and not to main engine, which would screw up the ordering).

            chosen_decomp.decompose(cmd)  # run the decomposition
Пример #20
0
    def to_tikz(  # pylint: disable=too-many-branches,too-many-locals,too-many-statements
            self,
            line,
            circuit,
            end=None,
            draw_gates_in_parallel=True):
        """
        Generate the TikZ code for one line of the circuit up to a certain gate.

        It modifies the circuit to include only the gates which have not been drawn. It automatically switches to other
        lines if the gates on those lines have to be drawn earlier.

        Args:
            line (int): Line to generate the TikZ code for.
            circuit (list<list<CircuitItem>>): The circuit to draw.
            end (int): Gate index to stop at (for recursion).
            draw_gates_in_parallel (bool): True or False for how to place gates

        Returns:
            tikz_code (string): TikZ code representing the current qubit line and, if it was necessary to draw other
                lines, those lines as well.
        """
        if end is None:
            end = len(circuit[line])

        tikz_code = []

        cmds = circuit[line]
        for i in range(0, end):
            gate = cmds[i].gate
            lines = cmds[i].lines
            ctrl_lines = cmds[i].ctrl_lines

            all_lines = lines + ctrl_lines
            all_lines.remove(line)  # remove current line
            for _line in all_lines:
                gate_idx = 0
                while not circuit[_line][gate_idx] == cmds[i]:
                    gate_idx += 1

                tikz_code.append(self.to_tikz(_line, circuit, gate_idx))

                # we are taking care of gate 0 (the current one)
                circuit[_line] = circuit[_line][1:]

            all_lines = lines + ctrl_lines
            pos = max([
                self.pos[ll] for ll in range(min(all_lines),
                                             max(all_lines) + 1)
            ])
            for _line in range(min(all_lines), max(all_lines) + 1):
                self.pos[_line] = pos + self._gate_pre_offset(gate)

            connections = ""
            for _line in all_lines:
                connections += self._line(self.op_count[_line] - 1,
                                          self.op_count[_line],
                                          line=_line)
            add_str = ""
            if gate == X:
                # draw NOT-gate with controls
                add_str = self._x_gate(lines, ctrl_lines)
                # and make the target qubit quantum if one of the controls is
                if not self.is_quantum[lines[0]]:
                    if sum([self.is_quantum[i] for i in ctrl_lines]) > 0:
                        self.is_quantum[lines[0]] = True
            elif gate == Z and len(ctrl_lines) > 0:
                add_str = self._cz_gate(lines + ctrl_lines)
            elif gate == Swap:
                add_str = self._swap_gate(lines, ctrl_lines)
            elif gate == SqrtSwap:
                add_str = self._sqrtswap_gate(lines,
                                              ctrl_lines,
                                              daggered=False)
            elif gate == get_inverse(SqrtSwap):
                add_str = self._sqrtswap_gate(lines, ctrl_lines, daggered=True)
            elif gate == Measure:
                # draw measurement gate
                for _line in lines:
                    op = self._op(_line)
                    width = self._gate_width(Measure)
                    height = self._gate_height(Measure)
                    shift0 = 0.07 * height
                    shift1 = 0.36 * height
                    shift2 = 0.1 * width
                    add_str += ("\n\\node[measure,edgestyle] ({op}) at ({pos}"
                                ",-{line}) {{}};\n\\draw[edgestyle] ([yshift="
                                "-{shift1}cm,xshift={shift2}cm]{op}.west) to "
                                "[out=60,in=180] ([yshift={shift0}cm]{op}."
                                "center) to [out=0, in=120] ([yshift=-{shift1}"
                                "cm,xshift=-{shift2}cm]{op}.east);\n"
                                "\\draw[edgestyle] ([yshift=-{shift1}cm]{op}."
                                "center) to ([yshift=-{shift2}cm,xshift=-"
                                "{shift1}cm]{op}.north east);").format(
                                    op=op,
                                    pos=self.pos[_line],
                                    line=_line,
                                    shift0=shift0,
                                    shift1=shift1,
                                    shift2=shift2,
                                )
                    self.op_count[_line] += 1
                    self.pos[_line] += self._gate_width(
                        gate) + self._gate_offset(gate)
                    self.is_quantum[_line] = False
            elif gate == Allocate:
                # draw 'begin line'
                add_str = "\n\\node[none] ({}) at ({},-{}) {{$\\Ket{{0}}{}$}};"
                id_str = ""
                if self.settings['gates']['AllocateQubitGate']['draw_id']:
                    id_str = "^{{\\textcolor{{red}}{{{}}}}}".format(cmds[i].id)
                xpos = self.pos[line]
                try:
                    if self.settings['gates']['AllocateQubitGate'][
                            'allocate_at_zero']:
                        self.pos[line] -= self._gate_pre_offset(gate)
                        xpos = self._gate_pre_offset(gate)
                except KeyError:
                    pass
                self.pos[line] = max(
                    xpos + self._gate_offset(gate) + self._gate_width(gate),
                    self.pos[line],
                )
                add_str = add_str.format(self._op(line), xpos, line, id_str)
                self.op_count[line] += 1
                self.is_quantum[line] = self.settings['lines']['init_quantum']
            elif gate == Deallocate:
                # draw 'end of line'
                op = self._op(line)
                add_str = "\n\\node[none] ({}) at ({},-{}) {{}};"
                add_str = add_str.format(op, self.pos[line], line)
                yshift = str(self._gate_height(gate)) + "cm]"
                add_str += (
                    "\n\\draw ([yshift={yshift}{op}.center) edge [edgestyle] ([yshift=-{yshift}{op}.center);"
                ).format(op=op, yshift=yshift)
                self.op_count[line] += 1
                self.pos[line] += self._gate_width(gate) + self._gate_offset(
                    gate)
            else:
                # regular gate must draw the lines it does not act upon
                # if it spans multiple qubits
                add_str = self._regular_gate(gate, lines, ctrl_lines)
                for _line in lines:
                    self.is_quantum[_line] = True

            tikz_code.append(add_str)
            if not gate == Allocate:
                tikz_code.append(connections)

            if not draw_gates_in_parallel:
                for _line in range(len(self.pos)):
                    if _line != line:
                        self.pos[_line] = self.pos[line]

        circuit[line] = circuit[line][end:]
        return "".join(tikz_code)
Пример #21
0
    def _process_command(self, cmd):
        """
        Check whether a command cmd can be handled by further engines and,
        if not, replace it using the decomposition rules loaded with the setup
        (e.g., setups.default).

        Args:
            cmd (Command): Command to process.

        Raises:
            Exception if no replacement is available in the loaded setup.
        """
        if self.is_available(cmd):
            self.send([cmd])
        else:
            # check for decomposition rules
            decomp_list = []
            potential_decomps = []

            # First check for a decomposition rules of the gate class, then
            # the gate class of the inverse gate. If nothing is found, do the
            # same for the first parent class, etc.
            gate_mro = type(cmd.gate).mro()[:-1]
            # If gate does not have an inverse it's parent classes are
            # DaggeredGate, BasicGate, object. Hence don't check the last two
            inverse_mro = type(get_inverse(cmd.gate)).mro()[:-2]
            rules = self.decompositionRuleSet.decompositions
            for level in range(max(len(gate_mro), len(inverse_mro))):
                # Check for forward rules
                if level < len(gate_mro):
                    class_name = gate_mro[level].__name__
                    try:
                        potential_decomps = [d for d in rules[class_name]]
                    except KeyError:
                        pass
                    # throw out the ones which don't recognize the command
                    for d in potential_decomps:
                        if d.check(cmd):
                            decomp_list.append(d)
                    if len(decomp_list) != 0:
                        break
                # Check for rules implementing the inverse gate
                # and run them in reverse
                if level < len(inverse_mro):
                    inv_class_name = inverse_mro[level].__name__
                    try:
                        potential_decomps += [
                            d.get_inverse_decomposition()
                            for d in rules[inv_class_name]
                        ]
                    except KeyError:
                        pass
                    # throw out the ones which don't recognize the command
                    for d in potential_decomps:
                        if d.check(cmd):
                            decomp_list.append(d)
                    if len(decomp_list) != 0:
                        break

            if len(decomp_list) == 0:
                raise NoGateDecompositionError("\nNo replacement found for " +
                                               str(cmd) + "!")

            # use decomposition chooser to determine the best decomposition
            chosen_decomp = self._decomp_chooser(cmd, decomp_list)

            # the decomposed command must have the same tags
            # (plus the ones it gets from meta-statements inside the
            # decomposition rule).
            # --> use a CommandModifier with a ForwarderEngine to achieve this.
            old_tags = cmd.tags[:]

            def cmd_mod_fun(cmd):  # Adds the tags
                cmd.tags = old_tags[:] + cmd.tags
                cmd.engine = self.main_engine
                return cmd

            # the CommandModifier calls cmd_mod_fun for each command
            # --> commands get the right tags.
            cmod_eng = CommandModifier(cmd_mod_fun)
            cmod_eng.next_engine = self  # send modified commands back here
            cmod_eng.main_engine = self.main_engine
            # forward everything to cmod_eng using the ForwarderEngine
            # which behaves just like MainEngine
            # (--> meta functions still work)
            forwarder_eng = ForwarderEngine(cmod_eng)
            cmd.engine = forwarder_eng  # send gates directly to forwarder
            # (and not to main engine, which would screw up the ordering).

            chosen_decomp.decompose(cmd)  # run the decomposition
Пример #22
0
Z = ZGate()


class SGate(BasicGate):
    """ S gate class """
    @property
    def matrix(self):
        return np.matrix([[1, 0], [0, 1j]])

    def __str__(self):
        return "S"


S = SGate()
Sdag = Sdagger = get_inverse(S)


class TGate(BasicGate):
    """ T gate class """
    @property
    def matrix(self):
        return np.matrix([[1, 0], [0, cmath.exp(1j * cmath.pi / 4)]])

    def __str__(self):
        return "T"


T = TGate()
Tdag = Tdagger = get_inverse(T)
     dataset1[i]=func(i,n)  
 dataset=[x.real for x in dataset1]
 
 '''
     Quantum
 '''
 #the QFT misses a swap operation
 for i in range(int(n/2)):
      Swap | (Qubits[i],Qubits[n-i-1])
 QFT | Qubits[0:n]
  
 #Control rotation
 Control_Rotation(eng,Qubits,dataset,n)
 
 #inverse QFT
 get_inverse(QFT) | Qubits[0:n]
 for i in range(int(n/2)):
      Swap | (Qubits[i],Qubits[n-i-1]) 
      
 #Get the quantum output and store in classical numpy. Named Quantum     
 qstate=qutoclass(eng,Qubits, n, 1)
 #nomalized
 qsum=math.sqrt(sum(abs(x)**2 for x in qstate))
 qstate=qstate/qsum
 All(Measure) | Qubits    
 '''
     Classical
 '''
 #classical method to get the circulent matrix, and solve the problem in classical, named Circulent
 F=np.zeros((2**n,2**n))*(0+0j)
 for i in range(2**n):
Пример #24
0
input()
print("It will take your opponents move and compare them.")
input()
print("But first you'll have to sign in...\n")

# prepare qubits
qubits = eng.allocate_qureg(5)

# referee decides things in the X basis, so we prepare it in the |+> state
H | qubits[2]

# implement human move
if (humanMove == "s"):
	S | qubits[2]
else:
	get_inverse(S) | qubits[2]

# opponent qubit is prepared in state |+> to randomly decide the move to make
H | qubits[opponent]

# to implement the quantum move, first do an S in all cases
S | qubits[2]
# then use a controlled-Z to make it into a Sdg if that's what the quantum player chooses
H | qubits[2]
CNOT | (qubits[opponent], qubits[2])
H | qubits[2]

# quantum player wins if the moves where different, which would leave referee in the |+> state
# human player wins if the moves were the same
# we measure in the X basis to see
H | qubits[2]
Пример #25
0
def zoo_profile():
    """Generate and display the zoo of quantum gates."""
    # create a main compiler engine with a drawing backend
    drawing_engine = CircuitDrawer()
    locations = {0: 1, 1: 2, 2: 0, 3: 3}
    drawing_engine.set_qubit_locations(locations)
    main_eng = MainEngine(drawing_engine)
    qureg = main_eng.allocate_qureg(4)

    # define a zoo of gates
    te_gate = TimeEvolution(0.5, 0.1 * QubitOperator('X0 Y2'))

    def add(x, y):
        return x, y + 1

    zoo = [
        (X, 3),
        (Y, 2),
        (Z, 0),
        (Rx(0.5), 2),
        (Ry(0.5), 1),
        (Rz(0.5), 1),
        (Ph(0.5), 0),
        (S, 3),
        (T, 2),
        (H, 1),
        (Toffoli, (0, 1, 2)),
        (Barrier, None),
        (Swap, (0, 3)),
        (SqrtSwap, (0, 1)),
        (get_inverse(SqrtSwap), (2, 3)),
        (SqrtX, 2),
        (C(get_inverse(SqrtX)), (0, 2)),
        (C(Ry(0.5)), (2, 3)),
        (CNOT, (2, 1)),
        (Entangle, None),
        (te_gate, None),
        (QFT, None),
        (Tensor(H), None),
        (BasicMathGate(add), (2, 3)),
        (All(Measure), None),
    ]

    # apply them
    for gate, pos in zoo:
        if pos is None:
            gate | qureg
        elif isinstance(pos, tuple):
            gate | tuple(qureg[i] for i in pos)
        else:
            gate | qureg[pos]

    main_eng.flush()

    # generate latex code to draw the circuit
    s = drawing_engine.get_latex()
    prefix = 'zoo'
    with open('{}.tex'.format(prefix), 'w') as f:
        f.write(s)

    # compile latex source code and open pdf file
    os.system('pdflatex {}.tex'.format(prefix))
    openfile('{}.pdf'.format(prefix))
Пример #26
0
    H | qubits[3]
    CNOT | (qubits[3], qubits[2])
    X | qubits[3]
    bobs[2] = 1
    T | qubits[2]
if (ship == "f"):  # f means 3 and 4
    H | qubits[3]
    CNOT | (qubits[3], qubits[4])
    X | qubits[3]
    bobs[3] = 1
    T | qubits[3]

# apply the bombs
# whether or not a bomb is applied corresponds to the two measurment choices for CHSH (in x-y plane)
if (bobs[bomb1] == 1):
    get_inverse(S) | qubits[bomb1]
else:
    S | qubits[bomb1]
if (bobs[bomb2] == 1):
    get_inverse(S) | qubits[bomb2]
else:
    S | qubits[bomb2]

# measure all in X basis
H | qubits[0]
Measure | qubits[0]
H | qubits[1]
Measure | qubits[1]
H | qubits[2]
Measure | qubits[2]
H | qubits[3]
Пример #27
0
def high_level_gates(eng, cmd):
    g = cmd.gate
    if g == QFT or get_inverse(g) == QFT or g == Swap:
        return True
    return eng.next_engine.is_available(cmd)