Skip to content

Commit

Permalink
[feature/SPO_apply] Adding getters for SummedPauliOp functions and ot…
Browse files Browse the repository at this point in the history
…her small changes
  • Loading branch information
jamesETsmith committed Nov 5, 2024
1 parent 8e4b999 commit f1d0045
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 45 deletions.
5 changes: 0 additions & 5 deletions fast_pauli/cpp/include/__pauli_helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,6 @@ std::vector<PauliString> calcutate_pauli_strings(size_t const n_qubits, size_t c
size_t n_pauli_strings = nontrivial_paulis.size() * idx_combos.size();
std::vector<PauliString> result(n_pauli_strings);

// fmt::println("n_qubits = {} weight = {} n_nontrivial_paulis = {} n_combos = {}", n_qubits, weight,
// nontrivial_paulis.size(), idx_combos.size());

// Iterate through all the nontrivial paulis and all the combinations
for (size_t i = 0; i < nontrivial_paulis.size(); ++i)
{
Expand Down Expand Up @@ -152,8 +149,6 @@ std::vector<PauliString> calculate_pauli_strings_max_weight(size_t n_qubits, siz
auto ps = calcutate_pauli_strings(n_qubits, i);
result.insert(result.end(), ps.begin(), ps.end());
}

// fmt::println("n_qubits = {} weight = {} n_pauli_strings = {}", n_qubits, weight, result.size());
return result;
}

Expand Down
52 changes: 12 additions & 40 deletions fast_pauli/cpp/include/__summed_pauli_op.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ namespace fast_pauli
{

/**
* @brief A class representing a sum of Pauli operators \f$ A = \sum_k A_k = \sum_i h_{ik} \mathcal{\hat{P}}_i \f$.
* @brief A class representing a sum of Pauli operators \f$ A = \sum_k A_k = \sum_{ik} h_{ik} \mathcal{\hat{P}}_i \f$.
* Where \f$ \mathcal{\hat{P}}_i \f$ are Pauli strings and \f$ h_{ik} \f$ are complex-valued coefficients.
*
*/
Expand All @@ -44,11 +44,6 @@ template <std::floating_point T> struct SummedPauliOp
std::vector<std::complex<T>> coeffs_raw;
Tensor<2> coeffs; // (n_pauli_strings, n_operators)

// TODO dangerous
size_t _dim;
size_t _n_operators;
size_t _n_qubits;

void __check_ctor_inputs(std::vector<fast_pauli::PauliString> const &pauli_strings, Tensor<2> const coeffs)
{
// Check the PauliStrings to make sure they're all the same size
Expand Down Expand Up @@ -90,10 +85,8 @@ template <std::floating_point T> struct SummedPauliOp
{
// TODO add more checks
size_t const n_pauli_strings = pauli_strings.size();
_dim = pauli_strings[0].dim();
_n_qubits = pauli_strings[0].n_qubits();
_n_operators = coeffs_raw.size() / n_pauli_strings;
coeffs = Tensor<2>(this->coeffs_raw.data(), n_pauli_strings, _n_operators);
size_t const n_operators = coeffs_raw.size() / n_pauli_strings;
coeffs = Tensor<2>(this->coeffs_raw.data(), n_pauli_strings, n_operators);

this->__check_ctor_inputs(pauli_strings, coeffs);
}
Expand All @@ -113,11 +106,6 @@ template <std::floating_point T> struct SummedPauliOp
//
this->__check_ctor_inputs(pauli_strings, coeffs);

//
_dim = pauli_strings[0].dim();
_n_qubits = pauli_strings[0].n_qubits();
_n_operators = coeffs.extent(1);

// Copy over the coeffs so our std::mdspan points at the memory owned by
// this object
coeffs_raw = std::vector<std::complex<T>>(coeffs.size());
Expand Down Expand Up @@ -148,11 +136,6 @@ template <std::floating_point T> struct SummedPauliOp

this->__check_ctor_inputs(this->pauli_strings, coeffs);

//
_dim = this->pauli_strings.front().dim();
_n_qubits = this->pauli_strings.front().n_qubits();
_n_operators = coeffs.extent(1);

// Copy over the coeffs so our std::mdspan points at the memory owned by
// this object
coeffs_raw = std::vector<std::complex<T>>(coeffs.size());
Expand All @@ -171,7 +154,7 @@ template <std::floating_point T> struct SummedPauliOp
*/
size_t dim() const noexcept
{
return _dim;
return pauli_strings.size() ? pauli_strings[0].dim() : 0;
}

/**
Expand All @@ -181,7 +164,7 @@ template <std::floating_point T> struct SummedPauliOp
*/
size_t n_qubits() const noexcept
{
return _n_qubits;
return pauli_strings.size() ? pauli_strings[0].n_qubits() : 0;
}

/**
Expand All @@ -191,7 +174,7 @@ template <std::floating_point T> struct SummedPauliOp
*/
size_t n_operators() const noexcept
{
return _n_operators;
return coeffs.extent(1);
}

/**
Expand Down Expand Up @@ -222,7 +205,7 @@ template <std::floating_point T> struct SummedPauliOp
[](fast_pauli::PauliString const &ps) { return static_cast<size_t>(ps.weight); });

std::vector<PauliString> pauli_strings_sq =
fast_pauli::calculate_pauli_strings_max_weight(_n_qubits, std::min(_n_qubits, 2UL * weight));
fast_pauli::calculate_pauli_strings_max_weight(n_qubits(), std::min(n_qubits(), 2UL * weight));

std::unordered_map<fast_pauli::PauliString, size_t> sq_idx_map;
for (size_t i = 0; i < pauli_strings_sq.size(); ++i)
Expand Down Expand Up @@ -262,16 +245,16 @@ template <std::floating_point T> struct SummedPauliOp
}

// Part 4: Contract the T_aij tensor with the coeffs to get the new coeffs
std::vector<std::complex<T>> coeffs_sq_raw(pauli_strings_sq.size() * _n_operators);
Tensor<2> coeffs_sq(coeffs_sq_raw.data(), pauli_strings_sq.size(), _n_operators);
std::vector<std::complex<T>> coeffs_sq_raw(pauli_strings_sq.size() * n_operators());
Tensor<2> coeffs_sq(coeffs_sq_raw.data(), pauli_strings_sq.size(), n_operators());

size_t i, j;
std::complex<T> phase;

#pragma omp parallel for schedule(dynamic) collapse(2) private(i, j, phase)
for (size_t a = 0; a < pauli_strings_sq.size(); ++a)
{
for (size_t k = 0; k < _n_operators; ++k)
for (size_t k = 0; k < n_operators(); ++k)
{
for (size_t x = 0; x < t_aij[a].size(); ++x)
{
Expand Down Expand Up @@ -593,26 +576,15 @@ template <std::floating_point T> struct SummedPauliOp
pauli_strings[j].expectation_value(expectation_vals_j, states);
}

// einsum("jk,jt->kt", coeffs, expectation_vals)
std::vector<std::complex<T>> coeffs_T_raw(n_ops * n_pauli_strings());
std::mdspan coeffs_T(coeffs_T_raw.data(), n_ops, n_pauli_strings());

#pragma omp for schedule(static) collapse(2)
for (size_t k = 0; k < n_ops; ++k)
{
for (size_t j = 0; j < n_pauli_strings(); ++j)
{
coeffs_T(k, j) = coeffs(j, k);
}
}

#pragma omp for collapse(2) schedule(static)
for (size_t k = 0; k < n_ops; ++k)
{
for (size_t t = 0; t < n_data; ++t)
{
for (size_t j = 0; j < n_pauli_strings(); ++j)
{
// Could be better about memory access patterns here, but I don't think the transposes are
// worth it
expectation_vals_out(k, t) += coeffs(j, k) * expectation_vals(j, t);
}
}
Expand Down

0 comments on commit f1d0045

Please sign in to comment.