def _resample_expectations_with_beta(results, prior_counts=1): """ Resample expectation values by constructing a beta distribution and sampling from it. Used by :py:func:`estimate_variance`. :param results: A list of ExperimentResults :param prior_counts: Number of "counts" to add to alpha and beta for the beta distribution from which we sample. :return: A new list of ``results`` where each ExperimentResult's ``expectation`` field contained a re-sampled expectation value """ resampled_results = [] for result in results: # reconstruct the raw counts of observations from the pauli observable mean num_plus = ((result.expectation + 1) / 2) * result.total_counts num_minus = result.total_counts - num_plus # We resample this data assuming it was from a beta distribution, # with additive smoothing alpha = num_plus + prior_counts beta = num_minus + prior_counts # transform bit bias back to pauli expectation value resampled_expect = 2 * np.random.beta(alpha, beta) - 1 resampled_results += [ExperimentResult( setting=result.setting, expectation=resampled_expect, std_err=result.std_err, total_counts=result.total_counts, )] return resampled_results
def test_R_operator_fixed_point_1_qubit(): # Check fixed point of operator. See Eq. 5 in Řeháček et al., PRA 75, 042108 (2007). qubits = [Q0] id_result = ExperimentResult(setting=ID_SETTING, expectation=1, total_counts=1) zplus_result = ExperimentResult(setting=Z_SETTING, expectation=1, total_counts=1) xplus_result = ExperimentResult(setting=X_SETTING, expectation=1, total_counts=1) z_results = [id_result, zplus_result] x_results = [id_result, xplus_result] def test_trace(rho, results): return _R(rho, results, qubits) @ rho @ _R(rho, results, qubits) np.testing.assert_allclose(test_trace(PROJ_ZERO, z_results), PROJ_ZERO, atol=1e-12) np.testing.assert_allclose(test_trace(PROJ_PLUS, x_results), PROJ_PLUS, atol=1e-12)
def test_survival_statistics(): # setup p0 = 0.98 # p(q0 = 0) p1 = 0.5 # p(q1 = 0) p_joint = p0 * p1 + (1 - p0) * (1 - p1) expectations = [2 * p0 - 1, 2 * p1 - 1, 2 * p_joint - 1] variances = np.asarray( [p0 * (1 - p0), p1 * (1 - p1), p_joint * (1 - p_joint)]) * 2**2 n = 10000 qubits = (0, 1) settings = [ ExperimentSetting(zeros_state(qubits), op) for op in all_traceless_pauli_z_terms(qubits) ] results = (ExperimentResult(setting, exp, n, std_err=np.sqrt(v / n)) for setting, exp, v in zip(settings, expectations, variances)) stats = get_stats_by_qubit_group([qubits], [results])[qubits] exps = stats['expectation'][0] errs = stats['std_err'][0] np.testing.assert_allclose(exps, expectations) np.testing.assert_allclose(errs, np.sqrt(variances / n)) survival_prob, survival_var = z_obs_stats_to_survival_statistics( exps, errs, n) np.testing.assert_allclose(survival_prob, p0 * p1) np.testing.assert_allclose(np.sqrt(survival_var), .004999, rtol=1e-4)
def test_survival_statistics_3(): # p0 is probability qubit 0 is 0 # p1 is probability qubit 1 is 0 for p0, p1 in zip([1.0, .99, .99], [1.0, 1.0, .99]): # setup p_joint = p0 * p1 + (1 - p0) * (1 - p1) expectations = [2 * p0 - 1, 2 * p1 - 1, 2 * p_joint - 1] variances = np.asarray( [p0 * (1 - p0), p1 * (1 - p1), p_joint * (1 - p_joint)]) * 2**2 n = 100 qubits = (0, 1) settings = [ ExperimentSetting(zeros_state(qubits), op) for op in all_traceless_pauli_z_terms(qubits) ] results = (ExperimentResult(setting, exp, n, std_err=np.sqrt( v / n)) for setting, exp, v in zip(settings, expectations, variances)) stats = get_stats_by_qubit_group([qubits], [results])[qubits] exps = stats['expectation'][0] errs = stats['std_err'][0] np.testing.assert_allclose(exps, expectations) np.testing.assert_allclose(errs, np.sqrt(variances / n)) survival_prob, survival_var = z_obs_stats_to_survival_statistics( exps, errs, n) assert survival_prob == p0 * p1
def test_survival_statistics_2(): # p0 is probability qubit 0 is 0 for p0 in [1.0, .99]: exp = 2 * p0 - 1 variance = p0 * (1 - p0) * 2**2 n = 100 qubits = (0, ) setting = [ ExperimentSetting(zeros_state(qubits), op) for op in all_traceless_pauli_z_terms(qubits) ][0] results = (ExperimentResult(setting, exp, n, std_err=np.sqrt(variance / n)), ) stats = get_stats_by_qubit_group([qubits], [results])[qubits] exps = stats['expectation'][0] errs = stats['std_err'][0] np.testing.assert_allclose(exps, [exp]) np.testing.assert_allclose(errs, [np.sqrt(variance / n)]) survival_prob, survival_var = z_obs_stats_to_survival_statistics( exps, errs) assert survival_prob == p0
def test_R_operator_fixed_point_2_qubit(): # Check fixed point of operator. See Eq. 5 in Řeháček et al., PRA 75, 042108 (2007). qubits = [0, 1] id_setting = ExperimentSetting(in_state=zeros_state(qubits), observable=sI(qubits[0])*sI( qubits[1])) zz_setting = ExperimentSetting(in_state=zeros_state(qubits), observable=sZ(qubits[0])*sI( qubits[1])) id_result = ExperimentResult(setting=id_setting, expectation=1, total_counts=1) zzplus_result = ExperimentResult(setting=zz_setting, expectation=1, total_counts=1) zz_results = [id_result, zzplus_result] # Z basis test r = _R(P00, zz_results, qubits) actual = r @ P00 @ r np.testing.assert_allclose(actual, P00, atol=1e-12)
def test_R_operator_with_hand_calc_example_1_qubit(): # This example was worked out by hand rho = ID / 2 obs_freqs = [3, 7] my_by_hand_calc_ans_Z = ((3 / 0.5) * PROJ_ZERO + (7 / 0.5) * PROJ_ONE) / sum(obs_freqs) my_by_hand_calc_ans_X = ((3 / 0.5) * PROJ_PLUS + (7 / 0.5) * PROJ_MINUS) / sum(obs_freqs) qubits = [Q0] exp = (obs_freqs[0] - obs_freqs[1]) / sum(obs_freqs) zplus_result = ExperimentResult(setting=Z_SETTING, expectation=exp, total_counts=sum(obs_freqs)) xplus_result = ExperimentResult(setting=X_SETTING, expectation=exp, total_counts=sum(obs_freqs)) z_results = [zplus_result] x_results = [xplus_result] # Z basis test np.testing.assert_allclose(_R(rho, z_results, qubits), my_by_hand_calc_ans_Z, atol=1e-12) # X basis test np.testing.assert_allclose(_R(rho, x_results, qubits), my_by_hand_calc_ans_X, atol=1e-12)
def wfn_estimate_observables(n_qubits, tomo_expt: ObservablesExperiment): if len(tomo_expt.program.defined_gates) > 0: raise pytest.skip("Can't do wfn on defined gates yet") wfn = NumpyWavefunctionSimulator(n_qubits) for settings in tomo_expt: for setting in settings: prog = Program() for oneq_state in setting.in_state.states: prog += _one_q_state_prep(oneq_state) prog += tomo_expt.program yield ExperimentResult( setting=setting, expectation=wfn.reset().do_program(prog).expectation(setting.observable), std_err=0., total_counts=1, # don't set to zero unless you want nans )