示例#1
0
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]
示例#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
示例#4
0
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