Beispiel #1
0
 def test_two_qubit_pulse_optimal_none_no_raise(self):
     """Verify pulse optimal decomposition when pulse_optimize==None doesn't
     raise when pulse optimal decomposition unknown."""
     # this assumes iswawp pulse optimal decomposition doesn't exist
     backend = FakeVigo()
     conf = backend.configuration()
     conf.basis_gates = [gate if gate != "cx" else "iswap" for gate in conf.basis_gates]
     qr = QuantumRegister(2)
     coupling_map = CouplingMap([[0, 1], [1, 2], [1, 3], [3, 4]])
     triv_layout_pass = TrivialLayout(coupling_map)
     qc = QuantumCircuit(qr)
     qc.unitary(random_unitary(4, seed=12), [0, 1])
     unisynth_pass = UnitarySynthesis(
         basis_gates=conf.basis_gates,
         coupling_map=coupling_map,
         backend_props=backend.properties(),
         pulse_optimize=None,
         natural_direction=True,
     )
     pm = PassManager([triv_layout_pass, unisynth_pass])
     try:
         qc_out = pm.run(qc)
     except QiskitError:
         self.fail("pulse_optimize=None raised exception unexpectedly")
     if isinstance(qc_out, QuantumCircuit):
         num_ops = qc_out.count_ops()
     else:
         num_ops = qc_out[0].count_ops()
     self.assertIn("sx", num_ops)
     self.assertLessEqual(num_ops["sx"], 14)
Beispiel #2
0
    def test_two_qubit_synthesis_to_directional_cx_from_gate_errors(self):
        """Verify two qubit unitaries are synthesized to match basis gates."""
        # TODO: should make check more explicit e.g. explicitly set gate
        # direction in test instead of using specific fake backend
        backend = FakeVigo()
        conf = backend.configuration()
        qr = QuantumRegister(2)
        coupling_map = CouplingMap(conf.coupling_map)
        triv_layout_pass = TrivialLayout(coupling_map)
        qc = QuantumCircuit(qr)
        qc.unitary(random_unitary(4, seed=12), [0, 1])
        unisynth_pass = UnitarySynthesis(
            basis_gates=conf.basis_gates,
            coupling_map=None,
            backend_props=backend.properties(),
            pulse_optimize=True,
            natural_direction=False,
        )
        pm = PassManager([triv_layout_pass, unisynth_pass])
        qc_out = pm.run(qc)

        unisynth_pass_nat = UnitarySynthesis(
            basis_gates=conf.basis_gates,
            coupling_map=None,
            backend_props=backend.properties(),
            pulse_optimize=True,
            natural_direction=True,
        )

        pm_nat = PassManager([triv_layout_pass, unisynth_pass_nat])
        qc_out_nat = pm_nat.run(qc)
        self.assertEqual(Operator(qc), Operator(qc_out))
        self.assertEqual(Operator(qc), Operator(qc_out_nat))
Beispiel #3
0
 def test_two_qubit_natural_direction_true_duration_fallback(self):
     """Verify not attempting pulse optimal decomposition when pulse_optimize==False."""
     # this assumes iswawp pulse optimal decomposition doesn't exist
     backend = FakeVigo()
     conf = backend.configuration()
     # conf.basis_gates = [gate if gate != "cx" else "iswap" for gate in conf.basis_gates]
     qr = QuantumRegister(2)
     coupling_map = CouplingMap([[0, 1], [1, 0], [1, 2], [1, 3], [3, 4]])
     triv_layout_pass = TrivialLayout(coupling_map)
     qc = QuantumCircuit(qr)
     qc.unitary(random_unitary(4, seed=12), [0, 1])
     unisynth_pass = UnitarySynthesis(
         basis_gates=conf.basis_gates,
         coupling_map=coupling_map,
         backend_props=backend.properties(),
         pulse_optimize=True,
         natural_direction=True,
     )
     pm = PassManager([triv_layout_pass, unisynth_pass])
     qc_out = pm.run(qc)
     self.assertTrue(
         all(
             # pylint: disable=no-member
             ([qr[0], qr[1]] == qlist
              for _, qlist, _ in qc_out.get_instructions("cx"))))
Beispiel #4
0
 def test_two_qubit_pulse_optimal_none_optimal(self):
     """Verify pulse optimal decomposition when pulse_optimize==None."""
     # this assumes iswawp pulse optimal decomposition doesn't exist
     backend = FakeVigo()
     conf = backend.configuration()
     qr = QuantumRegister(2)
     coupling_map = CouplingMap([[0, 1], [1, 2], [1, 3], [3, 4]])
     triv_layout_pass = TrivialLayout(coupling_map)
     qc = QuantumCircuit(qr)
     qc.unitary(random_unitary(4, seed=12), [0, 1])
     unisynth_pass = UnitarySynthesis(
         basis_gates=conf.basis_gates,
         coupling_map=coupling_map,
         backend_props=backend.properties(),
         pulse_optimize=None,
         natural_direction=True,
     )
     pm = PassManager([triv_layout_pass, unisynth_pass])
     qc_out = pm.run(qc)
     if isinstance(qc_out, QuantumCircuit):
         num_ops = qc_out.count_ops()  # pylint: disable=no-member
     else:
         num_ops = qc_out[0].count_ops()
     self.assertIn("sx", num_ops)
     self.assertLessEqual(num_ops["sx"], 12)
class DatasetGenerator:
    def __init__(self, shots=1000):
        """
        Initialize this class
        :param shots: number of times to measure each circuit
        """
        self.shots = shots
        self.observations = []
        self.features = []
        self.labels = []
        self.dataset = QuantumNoiseDataset()

        # Device Model
        self.device_backend = FakeVigo()
        self.coupling_map = self.device_backend.configuration().coupling_map
        self.simulator = Aer.get_backend('qasm simulator')

    def add_observation(self, circuit, noise_model):
        """
        Add a new data point - (feature, label) -to the dataset. Blocking method (until counts are calculated)
        :param circuit:
        :param noise_model:
        :return: none
        """
        feature = (circuit, noise_model)
        label = self.get_counts(circuit, noise_model)
        self.dataset.add_data_point(feature, label)

    def get_counts(self, circuit, noise_model):
        """
        Simulate a circuit with a noise_model and return measurement counts
        :param circuit:
        :param noise_model:
        :return: measurement counts (dict)
        """
        result = execute(circuit, self.simulator, noise_model=noise_model, coupling_map=self.coupling_map,
                         basis_gates=noise_model.basis_gates, shots=self.shots).result()
        counts = result.get_counts()
        return counts

    def get_dataset(self):
        """
        :return: the dataset (QuantumNoiseDataset)
        """
        return self.dataset

    def __repr__(self):
        return "I am a dataset generator for quantum noise estimation"

    def mock_dataset(self):
        """
        Generate a mock dataset
        :return: the dataset (QuantumNoiseDataset)
        """
        raise NotImplementedError
Beispiel #6
0
def main():
    # Parse all command line arguments
    args = parser.parse_args()
    shots = args.shots
    seed = args.seed
    basis = args.bell
    logfile = args.logfile
    verbose = args.verbose

    # Define the logger
    logger = logging.getLogger('task2')
    if logfile:
        logger.addHandler(logging.FileHandler(logfile))
    if verbose:
        logger.addHandler(logging.StreamHandler())
    logger.setLevel(logging.DEBUG)

    np.random.seed(seed=seed)

    # Get the noise model
    device_backend = FakeVigo()
    noise_model = NoiseModel.from_backend(device_backend)
    coupling_map = device_backend.configuration().coupling_map
    basis_gates = noise_model.basis_gates

    backend = Aer.get_backend('qasm_simulator')
    statevector_backend = Aer.get_backend('statevector_simulator')

    circuit = build_circuit(measure=basis)
    circuit_for_counts = build_circuit(measure='computational')
    unmeasured_circuit = build_circuit(measure=None)

    # qiskit's COBYLA can't take args to pass to the objective function, so we freeze them with functools.partial
    optimizer = COBYLA(maxiter=1000, tol=1e-8, disp=True)

    for nshots in shots:
        logger.debug('====================================================================================')
        logger.debug(f'\nShots per iteration: {nshots}')
        logger.debug(circuit)

        partial_objective_function = partial(objective_function, circuit=circuit, shots=nshots, backend=backend, bell_basis=(basis == 'bell'),
                                            noise_model=noise_model, coupling_map=coupling_map, basis_gates=basis_gates)
        ret = optimizer.optimize(num_vars=2, objective_function=partial_objective_function, 
                                initial_point=np.random.rand(len(circuit.parameters))*4*np.pi - 2*np.pi)


        params = ret[0]
        logger.debug(f'\nParameters:\n{params}')
        logger.debug(f'\nStatevector:\n{execute_circuit(unmeasured_circuit, params, statevector_backend).result().get_statevector()}')
        logger.debug(f'\nSimulated results:\n{execute_circuit(circuit_for_counts, params, backend, nshots, noise_model, coupling_map, basis_gates).result().get_counts()}')
        logger.debug('====================================================================================\n')

    sys.exit(ExitStatus.success)
Beispiel #7
0
    def __init__(self):
        self.py = Parameter("θ_y")
        self.px = Parameter("θ_x")
        self.ansatz = self.make_ansatz()
        self.backend = Aer.get_backend("qasm_simulator")

        # Get noise model
        vigo_backend = FakeVigo()
        self.noise_model = NoiseModel.from_backend(vigo_backend)
        self.coupling_map = vigo_backend.configuration().coupling_map
        self.basis_gates = self.noise_model.basis_gates

        # Extra arrays for debugging
        self.cost_history = []
Beispiel #8
0
    def test_two_qubit_synthesis_to_directional_cx_from_coupling_map_natural_false(self):
        """Verify natural cx direction is used when specified in coupling map
        when natural_direction is None."""
        # TODO: should make check more explicit e.g. explicitly set gate
        # direction in test instead of using specific fake backend
        backend = FakeVigo()
        conf = backend.configuration()
        qr = QuantumRegister(2)
        coupling_map = CouplingMap([[0, 1], [1, 2], [1, 3], [3, 4]])
        triv_layout_pass = TrivialLayout(coupling_map)
        qc = QuantumCircuit(qr)
        qc.unitary(random_unitary(4, seed=12), [0, 1])
        unisynth_pass = UnitarySynthesis(
            basis_gates=conf.basis_gates,
            coupling_map=coupling_map,
            backend_props=backend.properties(),
            pulse_optimize=True,
            natural_direction=False,
        )
        pm = PassManager([triv_layout_pass, unisynth_pass])
        qc_out = pm.run(qc)

        unisynth_pass_nat = UnitarySynthesis(
            basis_gates=conf.basis_gates,
            coupling_map=coupling_map,
            backend_props=backend.properties(),
            pulse_optimize=True,
            natural_direction=False,
        )

        pm_nat = PassManager([triv_layout_pass, unisynth_pass_nat])
        qc_out_nat = pm_nat.run(qc)
        # the decomposer defaults to the [1, 0] direction but the coupling
        # map specifies a [0, 1] direction. Check that this is respected.
        self.assertTrue(
            all(
                # pylint: disable=no-member
                ([qr[1], qr[0]] == qlist for _, qlist, _ in qc_out.get_instructions("cx"))
            )
        )
        self.assertTrue(
            all(
                # pylint: disable=no-member
                ([qr[1], qr[0]] == qlist for _, qlist, _ in qc_out_nat.get_instructions("cx"))
            )
        )
        self.assertEqual(Operator(qc), Operator(qc_out))
        self.assertEqual(Operator(qc), Operator(qc_out_nat))
Beispiel #9
0
 def test_two_qubit_pulse_optimal_true_raises(self):
     """Verify raises if pulse optimal==True but cx is not in the backend basis."""
     backend = FakeVigo()
     conf = backend.configuration()
     # this assumes iswawp pulse optimal decomposition doesn't exist
     conf.basis_gates = [gate if gate != "cx" else "iswap" for gate in conf.basis_gates]
     qr = QuantumRegister(2)
     coupling_map = CouplingMap([[0, 1], [1, 2], [1, 3], [3, 4]])
     triv_layout_pass = TrivialLayout(coupling_map)
     qc = QuantumCircuit(qr)
     qc.unitary(random_unitary(4, seed=12), [0, 1])
     unisynth_pass = UnitarySynthesis(
         basis_gates=conf.basis_gates,
         coupling_map=coupling_map,
         backend_props=backend.properties(),
         pulse_optimize=True,
         natural_direction=True,
     )
     pm = PassManager([triv_layout_pass, unisynth_pass])
     with self.assertRaises(QiskitError):
         pm.run(qc)
Beispiel #10
0
 def test_two_qubit_natural_direction_true_gate_length_raises(self):
     """Verify not attempting pulse optimal decomposition when pulse_optimize==False."""
     # this assumes iswawp pulse optimal decomposition doesn't exist
     backend = FakeVigo()
     conf = backend.configuration()
     for _, nduv in backend.properties()._gates["cx"].items():
         nduv["gate_length"] = (4e-7, nduv["gate_length"][1])
         nduv["gate_error"] = (7e-3, nduv["gate_error"][1])
     qr = QuantumRegister(2)
     coupling_map = CouplingMap([[0, 1], [1, 0], [1, 2], [1, 3], [3, 4]])
     triv_layout_pass = TrivialLayout(coupling_map)
     qc = QuantumCircuit(qr)
     qc.unitary(random_unitary(4, seed=12), [0, 1])
     unisynth_pass = UnitarySynthesis(
         basis_gates=conf.basis_gates,
         backend_props=backend.properties(),
         pulse_optimize=True,
         natural_direction=True,
     )
     pm = PassManager([triv_layout_pass, unisynth_pass])
     with self.assertRaises(TranspilerError):
         pm.run(qc)
Beispiel #11
0
class DatasetGenerator:
    def __init__(self, shots=1000, L=3):
        """
        Initialize a new DatasetGenerator.
        This object provides an interface to generate synthetic quantum-noisy datasets.
        The user must prescribe the circuits and noise models.
        Some presets are available.
        :param shots: number of times to measure each circuit, default: 1000
        :param L: maximum circuit length
        """

        # Simulator Variables
        self.device_backend = FakeVigo()
        self.coupling_map = self.device_backend.configuration().coupling_map
        self.simulator = Aer.get_backend('qasm_simulator')

        self.shots = shots
        self.L = L
        self.dataset = self.emptyDataset()

        """self.observations = []
        self.features = []
        self.labels = []"""



    def add_observation(self, circuit, noise_model):
        """
        Add a new data point - (feature, label) - to the dataset.
        :param circuit: circuit, len(circuit) <= self.L
        :param noise_model:
        :return: none
        """

        assert len(circuit) <= self.L

        feature = (circuit, noise_model)
        label = self.get_counts(circuit, noise_model)
        self.dataset.add_data_point(feature, label)

    def get_dataset(self):
        """
        :return: the dataset (DataFrame)
        """
        return self.dataset

    def get_counts(self, circuit, noise_model):
        """
        Simulate a circuit with a noise_model and return measurement counts
        :param circuit:
        :param noise_model:
        :return: measurement counts (dict {'0':C0, '1':C1})
        """
        result = execute(circuit, self.simulator, noise_model=noise_model, coupling_map=self.coupling_map,
                         basis_gates=noise_model.basis_gates, shots=self.shots).result()
        counts = result.get_counts()
        return counts

    def emptyDataset(self):
        """
        Generate an empty Dataset.
        Column format:
        Gate_1
        NM_1
        ...
        ...
        Expected Value
        :return: df: DataFrame
        """

        column_names = []
        for i in range(self.L):
            column_names.append("Gate_{}_theta".format(i))
            column_names.append("Gate_{}_phi".format(i))
            column_names.append("Gate_{}_lambda".format(i))
            column_names.append("NM_{}".format(i))
        column_names.append("ExpectedValue")
        df = pd.DataFrame(dtype='float64', columns=column_names)
        df.loc[0] = pd.Series(dtype='float64')
        df.loc[1] = pd.Series(dtype='float64')
        df.loc[2] = pd.Series(dtype='float64')
        return df

    def __repr__(self):
        return "I am a dataset generator for quantum noise estimation"
Beispiel #12
0
c.rx(pi/2, qreg_q[1])
c.rx(pi/2, qreg_q[0])
c.ry(pi/2, qreg_q[1])
c.cx(qreg_q[0], qreg_q[1])
c.rx(pi/2, qreg_q[0])
c.ry(pi/2, qreg_q[1])
c.cx(qreg_q[0], qreg_q[1])
c.rx(pi/2, qreg_q[0])
c.ry(pi/2, qreg_q[1])
c.cx(qreg_q[0], qreg_q[1])
c.measure(qreg_q[0], creg_c[0])
c.measure(qreg_q[1], creg_c[1])

# Get the basis gates for the noise model
device_backend = FakeVigo()
coupling_map = device_backend.configuration().coupling_map

# Get the basis gates for the noise model
noise_model = NoiseModel.from_backend(device_backend)
basis_gates = noise_model.basis_gates

# Select the QasmSimulator from the Aer provider
simulator = Aer.get_backend('qasm_simulator')

###NOTE: I attempted to pass a variable to the shot count, but it gave an error each attempt, so 1000 shots were set.
# Execute noisy simulation and get counts
result_noise = execute(c, simulator,
                       noise_model=noise_model,
                       coupling_map=coupling_map,
                       basis_gates=basis_gates, shots=1000).result()
counts_noise = result_noise.get_counts(c)
Beispiel #13
0
def main():
    # Noise

    device_backend = FakeVigo()
    coupling_map = device_backend.configuration().coupling_map
    simulator = Aer.get_backend('qasm_simulator')

    noise_model = NoiseModel()
    basis_gates = noise_model.basis_gates
    error = amplitude_damping_error(0.5)
    # error = depolarizing_error(0.5, 1)
    noise_model.add_all_qubit_quantum_error(error, ['id', 'u1', 'u2', 'u3'])

    # Circuit
    circ = QuantumCircuit(1, 1)
    circ.h(0)
    circ.measure([0], [0])
    print("*" * 25 + " Circuit " + "*" * 25)
    print(circ.draw())

    model1 = {'name': 'noisy', 'model': noise_model}
    model2 = {'name': 'ideal', 'model': None}
    noise_models = [model1, model2]
    print()
    print("*" * 25 + " Noise Models " + "*" * 25)
    pprint(noise_models)

    # Execution
    Dataset = [(run_circuit(circ, simulator, nm['model'], coupling_map,
                            basis_gates), nm) for nm in noise_models]

    # Data Prep
    for counts, nm in Dataset:
        counts.setdefault('0', 0)
        counts.setdefault('1', 0)

    X = [[x[1] for x in sorted(counts.items())] for counts, nm in Dataset]
    Y_raw = [nm['name'] for counts, nm in Dataset]
    zeros = [x[0] for x in X]
    le = preprocessing.LabelEncoder()
    le.fit(Y_raw)
    Y = le.transform(Y_raw)
    print()
    print("*" * 25 + " Dataset " + "*" * 25)
    print("Features: ", X)
    print("Labels: ", Y_raw)
    print("Encoded Labels: ", Y)

    # Training Classifier
    clf = RandomForestClassifier(random_state=0)
    clf.fit(X, Y)

    print()
    print("*" * 25 + " Predictions " + "*" * 25)

    # Predict labels on original data
    print("Prediction on training set: ",
          list(le.inverse_transform(clf.predict(X))))

    # Predict labels on new data
    Xtest = []
    Ytest = []
    for i in range(max(0, min(zeros) - 50), min(max(zeros) + 51, 1001)):
        feature = [[i, 1000 - i]]
        prediction = list(le.inverse_transform(clf.predict(feature)))
        # print("Prediction on {}: {}".format(feature, prediction))
        Xtest.append(i)
        Ytest.append(prediction[0])

    # Plot Diagrams

    fig = plt.figure()
    plt.scatter(Xtest, Ytest, label="test set")
    plt.scatter(zeros, Y_raw, label="training set")
    plt.xlabel("Feature = Count of '0' measurements")
    plt.ylabel("Predicted Label")
    plt.legend()
    # fig.axes.append(circ.draw(output='mpl').axes[0])
    plt.show()