def test_permutation_generator(): perms = generate_permutations(4) assert len(perms) == 2 # N/2 circuits assert perms[0] == [0, 1, 2, 3] assert perms[1] == [1, 3, 0, 2] perms = generate_permutations(6) assert len(perms) == 3 # N/2 circuits assert perms[0] == [0, 1, 2, 3, 4, 5] assert perms[1] == [1, 3, 0, 5, 2, 4] assert perms[2] == [3, 5, 1, 4, 0, 2] perms = generate_permutations(4, no_truncation=True) assert len(perms) == 5 assert perms[1] == [1, 0, 3, 2] assert perms[3] == [3, 1, 2, 0]
def resample_opdm(opdm: np.ndarray, var_dict: Dict) -> np.ndarray: # testpragma: no cover """ Resample an 1-RDM assuming Gaussian statistics :param opdm: mean-values :param var_dict: dictionary of covariances indexed by circuit and permutation :param fixed_trace_psd_projection: Boolean for if fixed trace positive projection should be applied :return: """ num_qubits = opdm.shape[0] qubit_permutations = ccu.generate_permutations(num_qubits) new_opdm = np.zeros_like(opdm) for circuit_idx, permutation in enumerate(qubit_permutations): e_real_pairs = [ permutation[idx:idx + 2] for idx in np.arange(0, num_qubits - 1, 2) ] o_real_pairs = [ permutation[idx:idx + 2] for idx in np.arange(1, num_qubits - 1, 2) ] # get all the even and odd pairs even_means = [opdm[pp[0], pp[1]] for pp in e_real_pairs] opdm_terms = np.random.multivariate_normal( mean=even_means, cov=var_dict['xy_even'][circuit_idx]) for idx, (pp0, pp1) in enumerate(e_real_pairs): new_opdm[pp0, pp1] = opdm_terms[idx] new_opdm[pp1, pp0] = opdm_terms[idx] odd_means = [opdm[pp[0], pp[1]] for pp in o_real_pairs] opdm_terms = np.random.multivariate_normal( mean=odd_means, cov=var_dict['xy_odd'][circuit_idx]) for idx, (pp0, pp1) in enumerate(o_real_pairs): new_opdm[pp0, pp1] = opdm_terms[idx] new_opdm[pp1, pp0] = opdm_terms[idx] if circuit_idx == 0: # resample_diagonal_terms opdm_diagonal = np.random.multivariate_normal( mean=np.diagonal(opdm), cov=var_dict['z'][circuit_idx]) # because fill_diagonal documentat seems out of date. new_opdm[np.diag_indices_from(new_opdm)] = opdm_diagonal return new_opdm
def calculate_data(self, parameters): if len(parameters.shape) == 2: # testpragma: no cover u = parameters else: u = sp.linalg.expm(rhf_params_to_matrix(parameters, len(self.qubits), occ=self.occ, virt=self.virt ) ) circuits = ccc.generate_circuits_from_params_or_u( self.qubits, u, self.num_electrons, occ=self.occ, virt=self.virt, clean_ryxxy=self.clean_xxyy ) circuits_dict = ccc.circuits_with_measurements( self.qubits, circuits, clean_xxyy=self.clean_xxyy ) # Take data data_dict = {'z': {}, 'xy_even': {}, 'xy_odd': {}, 'qubits': [f'({q.row}, {q.col})' for q in self.qubits], 'qubit_permutations': ccu.generate_permutations( len(self.qubits)), 'circuits': circuits, 'circuits_with_measurement': circuits_dict} for measure_type in circuits_dict.keys(): circuits = circuits_dict[measure_type] for circuit_index in circuits.keys(): circuit = circuits[circuit_index] if self.verbose: # testpragma: no cover print(circuit.to_text_diagram(transpose=True)) data = self.sampler.run(circuit, repetitions=self.num_samples) if self.post_selection: # PostSelect the data good_indices = \ np.where(np.sum(np.array(data.data), axis=1) == self.num_electrons)[0] good_data = data.data[data.data.index.isin(good_indices)] data_dict[measure_type][circuit_index] = good_data else: # testpragma: no cover data_dict[measure_type][circuit_index] = data.data return data_dict
def covariance_construction_from_opdm( opdm: np.ndarray, num_samples: int): # testpragma: no cover """ Covariance generation from the opdm is from a Gaussian state :param opdm: 1-RDM :param num_samples: number of samples to estimate the 1-RDM :return: dictionary of covariances """ num_qubits = opdm.shape[0] qubit_permutations = ccu.generate_permutations(num_qubits) variance_dict = {'xy_even': {}, 'xy_odd': {}, 'z': {}} def cov_func(i, j, p, q): return opdm[i, q] * kdelta(j, p) - opdm[i, q] * opdm[p, j] for circuit_idx, permutation in enumerate(qubit_permutations): e_real_pairs = [ permutation[idx:idx + 2] for idx in np.arange(0, num_qubits - 1, 2) ] o_real_pairs = [ permutation[idx:idx + 2] for idx in np.arange(1, num_qubits - 1, 2) ] even_cov_mat = np.zeros((len(e_real_pairs), len(e_real_pairs)), dtype=float) for ridx, (i, j) in enumerate(e_real_pairs): for cidx, (p, q) in enumerate(e_real_pairs): # 0.25 comes from the fact that we estimate 0.5 (i^ j + j^ i) even_cov_mat[ridx, cidx] = 0.25 * ( cov_func(i, j, p, q) + cov_func(i, j, q, p) + cov_func(j, i, p, q) + cov_func(j, i, q, p)) w, _ = np.linalg.eigh(even_cov_mat) if not np.alltrue(w >= 0): raise ValueError( "covariance matrix for xy_even:{} not postiive semidefinite". format(circuit_idx)) variance_dict['xy_even'][circuit_idx] = even_cov_mat / num_samples odd_cov_mat = np.zeros((len(o_real_pairs), len(o_real_pairs)), dtype=float) for ridx, (i, j) in enumerate(o_real_pairs): for cidx, (p, q) in enumerate(o_real_pairs): odd_cov_mat[ridx, cidx] = 0.25 * ( cov_func(i, j, p, q) + cov_func(i, j, q, p) + cov_func(j, i, p, q) + cov_func(j, i, q, p)) w, _ = np.linalg.eigh(odd_cov_mat) if not np.alltrue(w >= 0): raise ValueError( "covariance matrix for xy_odd:{} not postiive semidefinite". format(circuit_idx)) variance_dict['xy_odd'][circuit_idx] = odd_cov_mat / num_samples if circuit_idx == 0: z_cov_mat = np.zeros((num_qubits, num_qubits), dtype=float) for ridx, i in enumerate(range(num_qubits)): for cidx, p in enumerate(range(num_qubits)): z_cov_mat[ridx, cidx] = cov_func(i, i, p, p) w, _ = np.linalg.eigh(z_cov_mat) if not np.alltrue(w >= -1.0E-15): raise ValueError( "covariance matrix for z:{} not postiive semidefinite". format(circuit_idx)) variance_dict['z'][circuit_idx] = z_cov_mat / num_samples return variance_dict