def test_circuit_equivalence(self):

        # set the size of the register
        n_qubits = 3

        projQ_backend = ProjectqQuantumSimulator(register_size=n_qubits,
                                                 seed=234,
                                                 backend=Simulator)
        qiskit_backend = QiskitQuantumSimulator(
            register_size=n_qubits,
            seed=234,
            simulator_backend=Aer.get_backend('statevector_simulator'))

        circuit = [
            ["STATE_PREPARATION", 0, 0],
            ['X', 0, 0],
            ['H', 0, 2],
            ["CONTROL", 0, 2],
            ["Y", 0, 1],
            ["T", 0, 0],
            ["SX", 0, 1],
            ["T", 0, 2],
            ["S", 0, 2],
            ["CONTROL", 0, 1],
            ["Z", 0, 2],
            ["T", 0, 2],
            ["INVS", 0, 2],
            ['RZ', 672, 1],
            ['SQRT_X', 0, 0],
            ["CONTROL", 0, 2],
            ["X", 0, 0],
            ["H", 0, 2],
            ["PIXY", 458, 1],
        ]

        for commands in circuit:

            hal_cmd = command_creator(*commands)

            projQ_backend.accept_command(hal_cmd)
            qiskit_backend.accept_command(hal_cmd)

        # compare wavefunction at the end of the circuit (before measuring)
        psi_projq = np.array(projQ_backend._engine.backend.cheat()[1])
        psi_qiskit = execute(qiskit_backend._circuit,
                             backend=qiskit_backend._simulator_backend).result(
                             ).get_statevector(qiskit_backend._circuit)

        # send measure command to projQ backend (will complain if not flushed)
        projQ_backend.accept_command(command_creator(*['STATE_MEASURE', 0, 0]))

        # compare fidelities, i.e. are the final states equivalent?
        fidelity = np.abs(np.sum(psi_qiskit.conj() @ psi_projq))**2

        self.assertTrue(np.isclose(fidelity, 1.))
def run_gate_circuits(noise_model, gate_list, n_qubits):
    """Implements a test circuit for each gate in gate_list which is executed
    using the given noise_model

        Parameters
        ----------
        noise_model : NoiseModel    
            the noise model to apply to all test circuits 
        gate_list : List[string]
            list of HAL strings strings corresponding to one gate each
            these are the gates that will be checked for noise
        n_qubits : int
            number of qubits for the test circuit (1 or 2)

        Returns
        -------
        List[bool]
            for each test gate assigns true if there is noise on the test gate, 
            false if there is no noise, i.e. all zeros measured

        Raises
        ------
        ValueError
            No test circuit defined for a given gatestring in gate_list
    """

    # re-define gates with custom labels so that they are executed without noise
    H_perfect = HGate(label='h_perfect')
    S_perfect = SGate(label='s_perfect')

    circuit_errors = []  # list to append results to

    for gate in gate_list:

        q_sim = QiskitQuantumSimulator(register_size=n_qubits,
                                       seed=343,
                                       noise_model=noise_model)

        q_sim.accept_command(command_creator(*["STATE_PREPARATION", 0, 0]))

        if gate in ['H', 'RX', 'RY', 'SX', 'SY', 'X', 'Y']:
            q_sim.accept_command(command_creator(*[gate, 512, 0]))
            q_sim.accept_command(command_creator(*[gate, 512, 0]))

        elif gate in ['Z', 'R', 'RZ']:
            q_sim._circuit.append(H_perfect, [0])
            q_sim.accept_command(command_creator(*[gate, 512, 0]))
            q_sim.accept_command(command_creator(*[gate, 512, 0]))
            q_sim._circuit.append(H_perfect, [0])

        elif gate in ['PIZX']:
            q_sim._circuit.append(H_perfect, [0])
            q_sim.accept_command(command_creator(*[gate, 0, 0]))
            q_sim._circuit.append(S_perfect, [0])
            q_sim._circuit.append(S_perfect, [0])
            q_sim._circuit.append(H_perfect, [0])

        elif gate in ['PIYZ']:
            q_sim._circuit.append(H_perfect, [0])
            q_sim._circuit.append(S_perfect, [0])
            q_sim.accept_command(command_creator(*[gate, 0, 0]))
            q_sim._circuit.append(S_perfect, [0])
            q_sim._circuit.append(H_perfect, [0])

        elif gate in ['PIXY']:
            q_sim._circuit.append(H_perfect, [0])
            q_sim.accept_command(command_creator(*[gate, 0, 0]))
            q_sim._circuit.append(H_perfect, [0])

        elif gate in ['S', 'INVS']:
            q_sim._circuit.append(H_perfect, [0])
            for _ in range(4):
                q_sim.accept_command(command_creator(*[gate, 0, 0]))
            q_sim._circuit.append(H_perfect, [0])

        elif gate in ['SQRT_X']:
            for _ in range(4):
                q_sim.accept_command(command_creator(*[gate, 0, 0]))

        elif gate in ['T']:
            q_sim._circuit.append(H_perfect, [0])
            for _ in range(8):
                q_sim.accept_command(command_creator(*[gate, 0, 0]))
            q_sim._circuit.append(H_perfect, [0])

        elif gate in ['CX']:
            q_sim._circuit.append(H_perfect, [0])
            q_sim.accept_command(command_creator(*['CONTROL', 0, 0]))
            q_sim.accept_command(command_creator(*['X', 0, 1]))
            q_sim.accept_command(command_creator(*['CONTROL', 0, 0]))
            q_sim.accept_command(command_creator(*['X', 0, 1]))
            q_sim._circuit.append(H_perfect, [0])

        elif gate in ['CY']:
            q_sim._circuit.append(H_perfect, [0])
            q_sim.accept_command(command_creator(*['CONTROL', 0, 0]))
            q_sim.accept_command(command_creator(*['Y', 0, 1]))
            q_sim.accept_command(command_creator(*['CONTROL', 0, 0]))
            q_sim.accept_command(command_creator(*['Y', 0, 1]))
            q_sim._circuit.append(H_perfect, [0])

        elif gate in ['CZ']:
            q_sim._circuit.append(H_perfect, [0])
            q_sim._circuit.append(H_perfect, [1])
            q_sim.accept_command(command_creator(*['CONTROL', 0, 0]))
            q_sim.accept_command(command_creator(*['Z', 0, 1]))
            q_sim.accept_command(command_creator(*['CONTROL', 0, 0]))
            q_sim.accept_command(command_creator(*['Z', 0, 1]))
            q_sim._circuit.append(H_perfect, [0])
            q_sim._circuit.append(H_perfect, [1])

        else:
            raise ValueError('test circuit not defined for this gate')

        q_sim._circuit.measure_all()

        job = execute(q_sim._circuit,
                      backend=q_sim._simulator_backend,
                      optimization_level=0,
                      basis_gates=q_sim._noise_model.basis_gates,
                      noise_model=q_sim._noise_model,
                      seed_simulator=243,
                      shots=100)

        result_dict = job.result().get_counts()

        if n_qubits == 1:
            if result_dict['0'] < 100:
                circuit_errors.append(True)
            else:
                circuit_errors.append(False)

        if n_qubits == 2:
            if result_dict['00'] < 100:
                circuit_errors.append(True)
            else:
                circuit_errors.append(False)

    return circuit_errors
 def test_target_is_control_index_error(self):
     with self.assertRaises(ValueError):
         self.sim.accept_command(command_creator("STATE_PREPARATION"))
         self.sim.accept_command(command_creator("CONTROL", qubit=0))
         self.sim.accept_command(command_creator("RX", qubit=0))
 def test_too_many_controls_error(self):
     with self.assertRaises(ValueError):
         self.sim.accept_command(command_creator("STATE_PREPARATION"))
         self.sim.accept_command(command_creator("CONTROL", qubit=0))
         self.sim.accept_command(command_creator("CONTROL", qubit=1))
 def test_register_size_error(self):
     with self.assertRaises(ValueError):
         cmd = command_creator("X", qubit=2)
         self.sim.accept_command(cmd)