示例#1
0
def test_qc_joint_calibration(forest):
    # noise model with 95% symmetrized readout fidelity per qubit
    noise_model = asymmetric_ro_model([0, 1], 0.945, 0.955)
    qc = get_qc("2q-qvm")
    qc.qam.noise_model = noise_model

    # |01> state program
    p = Program()
    p += RESET()
    p += X(0)
    p.wrap_in_numshots_loop(10000)

    # ZZ experiment
    sz = ExperimentSetting(
        in_state=sZ(0) * sZ(1), out_operator=sZ(0) * sZ(1), additional_expectations=[[0], [1]]
    )
    e = Experiment(settings=[sz], program=p)

    results = qc.experiment(e)

    # ZZ expectation value for state |01> with 95% RO fid on both qubits is about -0.81
    assert np.isclose(results[0].expectation, -0.81, atol=0.01)
    assert results[0].total_counts == 40000
    # Z0 expectation value for state |01> with 95% RO fid on both qubits is about -0.9
    assert np.isclose(results[0].additional_results[0].expectation, -0.9, atol=0.01)
    assert results[0].additional_results[1].total_counts == 40000
    # Z1 expectation value for state |01> with 95% RO fid on both qubits is about 0.9
    assert np.isclose(results[0].additional_results[1].expectation, 0.9, atol=0.01)
    assert results[0].additional_results[1].total_counts == 40000
示例#2
0
def test_qc_expectation_on_qvm(client_configuration: QCSClientConfiguration, dummy_compiler: DummyCompiler):
    # regression test for https://github.com/rigetti/forest-tutorials/issues/2
    qc = QuantumComputer(name="testy!", qam=QVM(client_configuration=client_configuration), compiler=dummy_compiler)

    p = Program()
    theta = p.declare("theta", "REAL")
    p += RESET()
    p += RY(theta, 0)
    p.wrap_in_numshots_loop(10000)

    sx = ExperimentSetting(in_state=_pauli_to_product_state(sZ(0)), out_operator=sX(0))
    e = Experiment(settings=[sx], program=p)

    thetas = [-np.pi / 2, 0.0, np.pi / 2]
    results = []

    # Verify that multiple calls to qc.experiment with the same experiment backed by a QVM that
    # requires_exectutable does not raise an exception.
    for theta in thetas:
        results.append(qc.experiment(e, memory_map={"theta": [theta]}))

    assert np.isclose(results[0][0].expectation, -1.0, atol=0.01)
    assert np.isclose(results[0][0].std_err, 0)
    assert results[0][0].total_counts == 20000

    # bounds on atol and std_err here are a little loose to try and avoid test flakiness.
    assert np.isclose(results[1][0].expectation, 0.0, atol=0.1)
    assert results[1][0].std_err < 0.01
    assert results[1][0].total_counts == 20000

    assert np.isclose(results[2][0].expectation, 1.0, atol=0.01)
    assert np.isclose(results[2][0].std_err, 0)
    assert results[2][0].total_counts == 20000
示例#3
0
def test_qc_joint_expectation(forest):
    device = NxDevice(nx.complete_graph(2))
    qc = QuantumComputer(
        name="testy!", qam=QVM(connection=forest), device=device, compiler=DummyCompiler()
    )

    # |01> state program
    p = Program()
    p += RESET()
    p += X(0)
    p.wrap_in_numshots_loop(10)

    # ZZ experiment
    sz = ExperimentSetting(
        in_state=sZ(0) * sZ(1), out_operator=sZ(0) * sZ(1), additional_expectations=[[0], [1]]
    )
    e = Experiment(settings=[sz], program=p)

    results = qc.experiment(e)

    # ZZ expectation value for state |01> is -1
    assert np.isclose(results[0].expectation, -1)
    assert np.isclose(results[0].std_err, 0)
    assert results[0].total_counts == 40
    # Z0 expectation value for state |01> is -1
    assert np.isclose(results[0].additional_results[0].expectation, -1)
    assert results[0].additional_results[1].total_counts == 40
    # Z1 expectation value for state |01> is 1
    assert np.isclose(results[0].additional_results[1].expectation, 1)
    assert results[0].additional_results[1].total_counts == 40
示例#4
0
def test_qc_joint_expectation(client_configuration: QCSClientConfiguration, dummy_compiler: DummyCompiler):
    qc = QuantumComputer(name="testy!", qam=QVM(client_configuration=client_configuration), compiler=dummy_compiler)

    # |01> state program
    p = Program()
    p += RESET()
    p += X(0)
    p.wrap_in_numshots_loop(10)

    # ZZ experiment
    sz = ExperimentSetting(
        in_state=_pauli_to_product_state(sZ(0) * sZ(1)), out_operator=sZ(0) * sZ(1), additional_expectations=[[0], [1]]
    )
    e = Experiment(settings=[sz], program=p)

    results = qc.experiment(e)

    # ZZ expectation value for state |01> is -1
    assert np.isclose(results[0].expectation, -1)
    assert np.isclose(results[0].std_err, 0)
    assert results[0].total_counts == 40
    # Z0 expectation value for state |01> is -1
    assert np.isclose(results[0].additional_results[0].expectation, -1)
    assert results[0].additional_results[1].total_counts == 40
    # Z1 expectation value for state |01> is 1
    assert np.isclose(results[0].additional_results[1].expectation, 1)
    assert results[0].additional_results[1].total_counts == 40
示例#5
0
def test_qc_expectation(client_configuration: QCSClientConfiguration, dummy_compiler: DummyCompiler):
    qc = QuantumComputer(name="testy!", qam=QVM(client_configuration=client_configuration), compiler=dummy_compiler)

    # bell state program
    p = Program()
    p += RESET()
    p += H(0)
    p += CNOT(0, 1)
    p.wrap_in_numshots_loop(10)

    # XX, YY, ZZ experiment
    sx = ExperimentSetting(in_state=_pauli_to_product_state(sZ(0) * sZ(1)), out_operator=sX(0) * sX(1))
    sy = ExperimentSetting(in_state=_pauli_to_product_state(sZ(0) * sZ(1)), out_operator=sY(0) * sY(1))
    sz = ExperimentSetting(in_state=_pauli_to_product_state(sZ(0) * sZ(1)), out_operator=sZ(0) * sZ(1))

    e = Experiment(settings=[sx, sy, sz], program=p)

    results = qc.experiment(e)

    # XX expectation value for bell state |00> + |11> is 1
    assert np.isclose(results[0].expectation, 1)
    assert np.isclose(results[0].std_err, 0)
    assert results[0].total_counts == 40

    # YY expectation value for bell state |00> + |11> is -1
    assert np.isclose(results[1].expectation, -1)
    assert np.isclose(results[1].std_err, 0)
    assert results[1].total_counts == 40

    # ZZ expectation value for bell state |00> + |11> is 1
    assert np.isclose(results[2].expectation, 1)
    assert np.isclose(results[2].std_err, 0)
    assert results[2].total_counts == 40
示例#6
0
def test_build_symmetrization_memory_maps():
    p = Program()
    s = ExperimentSetting(in_state=_pauli_to_product_state(sZ(0) * sZ(1)),
                          out_operator=sZ(0) * sZ(1))
    e = Experiment(settings=[s], program=p)
    memory_maps = [
        {
            "symmetrization": [0.0, 0.0]
        },
        {
            "symmetrization": [0.0, np.pi]
        },
        {
            "symmetrization": [np.pi, 0.0]
        },
        {
            "symmetrization": [np.pi, np.pi]
        },
    ]
    assert e.build_symmetrization_memory_maps([0, 1]) == memory_maps
示例#7
0
def test_tomo_experiment():
    expts = [
        ExperimentSetting(TensorProductState(), sX(0) * sY(1)),
        ExperimentSetting(plusZ(0), sZ(0)),
    ]

    suite = Experiment(settings=expts, program=Program(X(0), Y(1)))
    assert len(suite) == 2
    for e1, e2 in zip(expts, suite):
        # experiment suite puts in groups of length 1
        assert len(e2) == 1
        e2 = e2[0]
        assert e1 == e2
    prog_str = str(suite).splitlines()[3:5]
    assert prog_str == EXPERIMENT_REPR.splitlines()[4:6]
示例#8
0
def test_experiment_deser(tmpdir):
    expts = [
        [
            ExperimentSetting(TensorProductState(), sX(0) * sI(1)),
            ExperimentSetting(TensorProductState(), sI(0) * sX(1)),
        ],
        [
            ExperimentSetting(TensorProductState(), sZ(0) * sI(1)),
            ExperimentSetting(TensorProductState(), sI(0) * sZ(1)),
        ],
    ]

    suite = Experiment(settings=expts, program=Program(X(0), Y(1)))
    to_json(f"{tmpdir}/suite.json", suite)
    suite2 = read_json(f"{tmpdir}/suite.json")
    assert suite == suite2
def test_for_negative_probabilities():
    # trivial program to do state tomography on
    prog = Program(I(0))

    # make an Experiment
    expt_settings = [
        ExperimentSetting(zeros_state([0]), pt)
        for pt in [sI(0), sX(0), sY(0), sZ(0)]
    ]
    experiment_1q = Experiment(settings=expt_settings, program=prog)

    # make a quantum computer object
    device = NxDevice(nx.complete_graph(1))
    qc_density = QuantumComputer(
        name="testy!",
        qam=PyQVM(n_qubits=1,
                  quantum_simulator_type=ReferenceDensitySimulator),
        device=device,
        compiler=DummyCompiler(),
    )

    # initialize with a pure state
    initial_density = np.array([[1.0, 0.0], [0.0, 0.0]])
    qc_density.qam.wf_simulator.density = initial_density

    try:
        list(
            measure_observables(qc=qc_density,
                                tomo_experiment=experiment_1q,
                                n_shots=3000))
    except ValueError as e:
        # the error is from np.random.choice by way of self.rs.choice in ReferenceDensitySimulator
        assert str(e) != "probabilities are not non-negative"

    # initialize with a mixed state
    initial_density = np.array([[0.9, 0.0], [0.0, 0.1]])
    qc_density.qam.wf_simulator.density = initial_density

    try:
        list(
            measure_observables(qc=qc_density,
                                tomo_experiment=experiment_1q,
                                n_shots=3000))
    except ValueError as e:
        assert str(e) != "probabilities are not non-negative"
示例#10
0
def test_tomo_experiment_pre_grouped():
    expts = [
        [
            ExperimentSetting(TensorProductState(), sX(0) * sI(1)),
            ExperimentSetting(TensorProductState(), sI(0) * sX(1)),
        ],
        [
            ExperimentSetting(TensorProductState(), sZ(0) * sI(1)),
            ExperimentSetting(TensorProductState(), sI(0) * sZ(1)),
        ],
    ]

    suite = Experiment(settings=expts, program=Program(X(0), Y(1)))
    assert len(suite) == 2  # number of groups
    for es1, es2 in zip(expts, suite):
        for e1, e2 in zip(es1, es2):
            assert e1 == e2
    prog_str = str(suite).splitlines()[3:5]
    assert prog_str == EXPERIMENT_REPR.splitlines()[4:6]
示例#11
0
def test_qc_expectation_larger_lattice(forest):
    device = NxDevice(nx.complete_graph(4))
    qc = QuantumComputer(name="testy!",
                         qam=QVM(connection=forest),
                         device=device,
                         compiler=DummyCompiler())

    q0 = 2
    q1 = 3

    # bell state program
    p = Program()
    p += RESET()
    p += H(q0)
    p += CNOT(q0, q1)
    p.wrap_in_numshots_loop(10)

    # XX, YY, ZZ experiment
    sx = ExperimentSetting(in_state=sZ(q0) * sZ(q1),
                           out_operator=sX(q0) * sX(q1))
    sy = ExperimentSetting(in_state=sZ(q0) * sZ(q1),
                           out_operator=sY(q0) * sY(q1))
    sz = ExperimentSetting(in_state=sZ(q0) * sZ(q1),
                           out_operator=sZ(q0) * sZ(q1))

    e = Experiment(settings=[sx, sy, sz], program=p)

    results = qc.experiment(e)

    # XX expectation value for bell state |00> + |11> is 1
    assert np.isclose(results[0].expectation, 1)
    assert np.isclose(results[0].std_err, 0)
    assert results[0].total_counts == 40

    # YY expectation value for bell state |00> + |11> is -1
    assert np.isclose(results[1].expectation, -1)
    assert np.isclose(results[1].std_err, 0)
    assert results[1].total_counts == 40

    # ZZ expectation value for bell state |00> + |11> is 1
    assert np.isclose(results[2].expectation, 1)
    assert np.isclose(results[2].std_err, 0)
    assert results[2].total_counts == 40
示例#12
0
def test_qc_calibration_1q(forest):
    # noise model with 95% symmetrized readout fidelity per qubit
    noise_model = asymmetric_ro_model([0], 0.945, 0.955)
    qc = get_qc("1q-qvm")
    qc.qam.noise_model = noise_model

    # bell state program (doesn't matter)
    p = Program()
    p += RESET()
    p += H(0)
    p += CNOT(0, 1)
    p.wrap_in_numshots_loop(10000)

    # Z experiment
    sz = ExperimentSetting(in_state=sZ(0), out_operator=sZ(0))
    e = Experiment(settings=[sz], program=p)

    results = qc.calibrate(e)

    # Z expectation value should just be 1 - 2 * readout_error
    np.isclose(results[0].expectation, 0.9, atol=0.01)
    assert results[0].total_counts == 20000
示例#13
0
def test_qc_calibration_2q(client_configuration: QCSClientConfiguration):
    # noise model with 95% symmetrized readout fidelity per qubit
    noise_model = asymmetric_ro_model([0, 1], 0.945, 0.955)
    qc = get_qc("2q-qvm", client_configuration=client_configuration)
    qc.qam.noise_model = noise_model

    # bell state program (doesn't matter)
    p = Program()
    p += RESET()
    p += H(0)
    p += CNOT(0, 1)
    p.wrap_in_numshots_loop(10000)

    # ZZ experiment
    sz = ExperimentSetting(in_state=_pauli_to_product_state(sZ(0) * sZ(1)), out_operator=sZ(0) * sZ(1))
    e = Experiment(settings=[sz], program=p)

    results = qc.calibrate(e)

    # ZZ expectation should just be (1 - 2 * readout_error_q0) * (1 - 2 * readout_error_q1)
    np.isclose(results[0].expectation, 0.81, atol=0.01)
    assert results[0].total_counts == 40000
示例#14
0
    def compile_tomo_expts(self, pauli_list=None):
        """
        This method compiles the tomography experiment circuits
        and prepares them for simulation.
        Every time the circuits are adjusted,
        re-compiling the tomography experiments
        is required to affect the outcome.
        """
        # use Forest's sorting algo from the Tomography suite
        # to group Pauli measurements together
        settings = []
        if pauli_list is None:
            pauli_list = self.pauli_list

        for term in pauli_list:
            # skip an identity operator,
            if len(term.operations_as_set()) > 0:
                # initial state and term pair.
                settings.append(ExperimentSetting(
                        TensorProductState(),
                        term))
        # group_experiments cannot be directly run
        # because there may be experiment with multiple settings.
        # so here we just use group_experiments to sort out the settings,
        # then reset the experiments with additional measurements.
        experiments = Experiment(settings, Program())
        suite = group_experiments(experiments)
        # we just need the grouped settings.
        grouped_pauil_terms = []
        for setting in suite:
            group = []
            for i, term in enumerate(setting):
                pauil_term = term.out_operator.copy()
                # Coefficients to be multiplied.
                pauil_term.coefficient = complex(1.)
                if i == 0:
                    group.append(pauil_term)
                elif len(pauil_term) > len(group[0]):
                    group.insert(0, pauil_term)
                else:
                    group.append(pauil_term)
            # make sure the longest pauil_term contains all the small
            # pauil_terms. Otherwise, we prepare a bigger one.
            bigger_pauli = group[0]
            if len(group) > 1:
                for term in group[1:]:
                    for iq, op in term.operations_as_set():
                        if op != group[0][iq]:
                            assert(group[0][iq] == "I"), \
                                    (f"{term} and {group[0]}"
                                    " not compatible!")
                            if bigger_pauli is group[0]:
                                bigger_pauli == group[0].copy()
                            bigger_pauli *= PauliTerm(op, iq)
                if bigger_pauli is not group[0]:
                    print(f"new pauli_term generated: {bigger_pauli}")
                    group.insert(0, bigger_pauli)
            grouped_pauil_terms.append(group)
        # group settings with additional_expectations.
        grouped_settings = []
        for pauil_terms in grouped_pauil_terms:
            additional = None
            if len(pauil_terms) > 1:
                additional = []
                for term in pauil_terms[1:]:
                    additional.append(term.get_qubits())
            grouped_settings.append(
                    ExperimentSetting(TensorProductState(),
                            pauil_terms[0],
                            additional_expectations=additional))

        # get the uccsd program
        prog = Program()
        prog += RESET()
        prog += self.ref_state + self.ansatz
        prog.wrap_in_numshots_loop(shots=self.shotN)
        self.experiment_list = Experiment(grouped_settings, prog)
        print('Number of tomography experiments: ',
                len(self.experiment_list))
        # calibration expreimental results.
        self.calibrations = self.qc.calibrate(self.experiment_list)
示例#15
0
def test_tomo_experiment_empty():
    suite = Experiment([], program=Program(X(0)))
    assert len(suite) == 0
    assert str(suite.program) == "X 0\n"
示例#16
0
def test_generate_experiment_program():
    # simplest example
    p = Program()
    s = ExperimentSetting(in_state=_pauli_to_product_state(sZ(0)),
                          out_operator=sZ(0))
    e = Experiment(settings=[s], program=p, symmetrization=0)
    exp = e.generate_experiment_program()
    test_exp = Program()
    ro = test_exp.declare("ro", "BIT")
    test_exp += MEASURE(0, ro[0])
    assert exp.out() == test_exp.out()
    assert exp.num_shots == 1

    # 2Q exhaustive symmetrization
    p = Program()
    s = ExperimentSetting(in_state=_pauli_to_product_state(sZ(0) * sZ(1)),
                          out_operator=sZ(0) * sZ(1))
    e = Experiment(settings=[s], program=p)
    exp = e.generate_experiment_program()
    test_exp = Program()
    test_exp += parameterized_readout_symmetrization([0, 1])
    ro = test_exp.declare("ro", "BIT", 2)
    test_exp += MEASURE(0, ro[0])
    test_exp += MEASURE(1, ro[1])
    assert exp.out() == test_exp.out()
    assert exp.num_shots == 1

    # add shots
    p = Program()
    p.wrap_in_numshots_loop(1000)
    s = ExperimentSetting(in_state=_pauli_to_product_state(sZ(0)),
                          out_operator=sZ(0))
    e = Experiment(settings=[s], program=p, symmetrization=0)
    exp = e.generate_experiment_program()
    test_exp = Program()
    ro = test_exp.declare("ro", "BIT")
    test_exp += MEASURE(0, ro[0])
    assert exp.out() == test_exp.out()
    assert exp.num_shots == 1000

    # active reset
    p = Program()
    p += RESET()
    s = ExperimentSetting(in_state=_pauli_to_product_state(sZ(0)),
                          out_operator=sZ(0))
    e = Experiment(settings=[s], program=p, symmetrization=0)
    exp = e.generate_experiment_program()
    test_exp = Program()
    test_exp += RESET()
    ro = test_exp.declare("ro", "BIT")
    test_exp += MEASURE(0, ro[0])
    assert exp.out() == test_exp.out()
    assert exp.num_shots == 1

    # state preparation and measurement
    p = Program()
    s = ExperimentSetting(in_state=_pauli_to_product_state(sY(0)),
                          out_operator=sX(0))
    e = Experiment(settings=[s], program=p, symmetrization=0)
    exp = e.generate_experiment_program()
    test_exp = Program()
    test_exp += parameterized_single_qubit_state_preparation([0])
    test_exp += parameterized_single_qubit_measurement_basis([0])
    ro = test_exp.declare("ro", "BIT")
    test_exp += MEASURE(0, ro[0])
    assert exp.out() == test_exp.out()
    assert exp.num_shots == 1

    # multi-qubit state preparation and measurement
    p = Program()
    s = ExperimentSetting(in_state=_pauli_to_product_state(sZ(0) * sY(1)),
                          out_operator=sZ(0) * sX(1))
    e = Experiment(settings=[s], program=p, symmetrization=0)
    exp = e.generate_experiment_program()
    test_exp = Program()
    test_exp += parameterized_single_qubit_state_preparation([0, 1])
    test_exp += parameterized_single_qubit_measurement_basis([0, 1])
    ro = test_exp.declare("ro", "BIT", 2)
    test_exp += MEASURE(0, ro[0])
    test_exp += MEASURE(1, ro[1])
    assert exp.out() == test_exp.out()
    assert exp.num_shots == 1