Skip to content

Commit

Permalink
[feature/SPO_apply] Adding docs to SummedPauliOp
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesETsmith committed Oct 29, 2024
1 parent bf20dbe commit f83d39d
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 37 deletions.
71 changes: 48 additions & 23 deletions fast_pauli/cpp/include/__summed_pauli_op.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@
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$.
* Where \f$ \mathcal{\hat{P}}_i \f$ are Pauli strings and \f$ h_{ik} \f$ are complex-valued coefficients.
*
*/
template <std::floating_point T> struct SummedPauliOp
{
// Short hand for complex, dynamic extent tensor with N dimension
Expand Down Expand Up @@ -71,8 +76,11 @@ template <std::floating_point T> struct SummedPauliOp
* @brief Construct a new Summed Pauli Op object from a vector of PauliStrings
* and a blob of coefficients.
*
* @param pauli_strings
* @param coeffs_raw
* @param pauli_strings The PauliStrings that define the set of PauliStrings used by all operators (n_pauli_strings)
* @param coeffs_raw A vector of coefficients that define the weights of each PauliString in each operator.
* The coefficients here are a flattened version of \f$ h_{ik} \f$ in \f$ A_k = \sum_i h_{ik} \mathcal{\hat{P}}_i
* \f$ (n_pauli_strings * n_operators,)
*
*/
SummedPauliOp(std::vector<PauliString> const &pauli_strings, std::vector<std::complex<T>> const &coeffs_raw)
: pauli_strings(pauli_strings), coeffs_raw(coeffs_raw)
Expand All @@ -90,8 +98,11 @@ template <std::floating_point T> struct SummedPauliOp
* @brief Construct a new Summed Pauli Op object from a vector of PauliStrings
* and an std::mdspan of coefficients.
*
* @param pauli_strings
* @param coeffs
* @param pauli_strings The PauliStrings that define the set of PauliStrings used by all operators
* (n_pauli_strings,)
* @param coeffs A 2D std::mdspan of coefficients that define the weights of each
* PauliString in each operator. The coefficients here are \f$ h_{ik} \f$ in
* \f$ A_k = \sum_i h_{ik} \mathcal{\hat{P}}_i \f$. (n_pauli_strings, n_operators)
*/
SummedPauliOp(std::vector<PauliString> const &pauli_strings, Tensor<2> const coeffs) : pauli_strings(pauli_strings)
{
Expand All @@ -114,8 +125,11 @@ template <std::floating_point T> struct SummedPauliOp
* @brief Construct a new Summed Pauli Op object from a vector of strings and
* a std::mdspan of coefficients.
*
* @param pauli_strings
* @param coeffs
* @param pauli_strings A vector of strings that define the set of PauliStrings used by all operators
* (n_pauli_strings)
* @param coeffs A 2D std::mdspan of coefficients that define the weights of each
* PauliString in each operator. The coefficients here are \f$ h_{ik} \f$ in
* \f$ A_k = \sum_i h_{ik} \mathcal{\hat{P}}_i \f$. (n_pauli_strings, n_operators)
*/
SummedPauliOp(std::vector<std::string> const &pauli_strings, Tensor<2> const coeffs)
{
Expand Down Expand Up @@ -155,7 +169,7 @@ template <std::floating_point T> struct SummedPauliOp
}

/**
* @brief Return the number of operators in the SummedPauliOp
* @brief Return the number of Pauli operators in the SummedPauliOp
*
* @return s
*/
Expand All @@ -174,11 +188,25 @@ template <std::floating_point T> struct SummedPauliOp
return pauli_strings.size();
}

/**
* @brief Apply the SummedPauliOp to a set of states, mathematically
* \f$ \big(\sum_k \sum_i h_{ik} \mathcal{\hat{P}}_i \big) \ket{\psi_t} \f$
*
* @param new_states The output states after applying the SummedPauliOp (n_dim, n_states)
* @param states The input states to apply the SummedPauliOp to (n_dim, n_states)
*/
void apply(Tensor<2> new_states, Tensor<2> states) const
{
apply(std::execution::seq, new_states, states);
}

/**
* @brief \copydoc SummedPauliOp::apply(Tensor<2>, Tensor<2>) const
*
* @tparam ExecutionPolicy
* @param new_states The output states after applying the SummedPauliOp (n_dim, n_states)
* @param states The input states to apply the SummedPauliOp to (n_dim, n_states)
*/
template <execution_policy ExecutionPolicy>
void apply(ExecutionPolicy &&, Tensor<2> new_states, Tensor<2> states) const
{
Expand Down Expand Up @@ -250,13 +278,14 @@ template <std::floating_point T> struct SummedPauliOp
* \big(\sum_k x_{tk} \sum_i h_{ik} \mathcal{\hat{P}}_i \big) \ket{\psi_t}
* \f$
*
* @param new_states
* @param new_states
* @param states
* @param data
* @tparam data_dtype The floating point type of the weights \f$ x_{kt} \f$ (n_operators, n_states)
* @param new_states The output states after applying the SummedPauliOp (n_dim, n_states)
* @param states The input states to apply the SummedPauliOp to (n_dim, n_states)
* @param data A 2D std::mdspan of the weights \f$ x_{tk} \f$ in the expression above (n_operators, n_states)
*/
template <std::floating_point data_dtype>
void apply_weighted(Tensor<2> new_states, Tensor<2> states,
std::mdspan<double, std::dextents<size_t, 2>> data) const
std::mdspan<data_dtype, std::dextents<size_t, 2>> data) const
{
apply_weighted(std::execution::seq, new_states, states, data);
}
Expand All @@ -265,13 +294,10 @@ template <std::floating_point T> struct SummedPauliOp
* @brief \copydoc SummedPauliOp::apply_weighted(Tensor<2>, Tensor<2>,
* std::mdspan<double, std::dextents<size_t, 2>>) const
*
* @tparam data_dtype
* @tparam ExecutionPolicy
* @param new_states
* @param states
* @param data
* @tparam ExecutionPolicy Execution policy for parallelization
* @tparam data_dtype The floating point type of the weights \f$ x_{kt} \f$ (n_operators, n_states)
*/
template <std::floating_point data_dtype, execution_policy ExecutionPolicy>
template <execution_policy ExecutionPolicy, std::floating_point data_dtype>
void apply_weighted(ExecutionPolicy &&, Tensor<2> new_states, Tensor<2> states,
std::mdspan<data_dtype, std::dextents<size_t, 2>> data) const
{
Expand Down Expand Up @@ -319,6 +345,7 @@ template <std::floating_point T> struct SummedPauliOp
{
for (size_t k = 0; k < n_ops; ++k)
{
// TODO we should transpose the data here for better memory access
weighted_coeffs(j, t) += coeffs(j, k) * data(k, t);
}
}
Expand Down Expand Up @@ -406,12 +433,12 @@ template <std::floating_point T> struct SummedPauliOp
* n_states).
*
* \f$
* \bra{\psi_t} \big(\sum_k x_{tk} \sum_i h_{ik} \mathcal{\hat{P}}_i \big) \ket{\psi_t}
* \bra{\psi_t} \big(\sum_k \sum_i h_{ik} \mathcal{\hat{P}}_i \big) \ket{\psi_t}
* \f$
*
* @param expectation_vals_out Output tensor for the expectation values
* (n_operators x n_states)
* @param states The states used to calculate the expectation values (n_dim x
* @param states The states used to calculate the expectation values (n_dim,
* n_states)
*/
void expectation_value(Tensor<2> expectation_vals_out, Tensor<2> states) const
Expand All @@ -422,9 +449,7 @@ template <std::floating_point T> struct SummedPauliOp
/**
* @brief \copydoc SummedPauliOp::expectation_value(Tensor<2>, Tensor<2>) const
*
* @tparam ExecutionPolicy
* @param expectation_vals_out
* @param states
* @tparam ExecutionPolicy Execution policy for parallelization
*/
template <execution_policy ExecutionPolicy>
void expectation_value(ExecutionPolicy &&, Tensor<2> expectation_vals_out, Tensor<2> states) const
Expand Down
58 changes: 44 additions & 14 deletions fast_pauli/cpp/src/fast_pauli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -900,20 +900,50 @@ np.ndarray
// See
// https://nanobind.readthedocs.io/en/latest/api_core.html#_CPPv4IDpEN8nanobind4initE
.def(nb::init<>())
.def("__init__",
[](fp::SummedPauliOp<float_type> *new_obj, std::vector<fp::PauliString> const &pauli_strings,
nb::ndarray<cfloat_t> coeffs) {
auto coeffs_mdspan = fp::__detail::ndarray_to_mdspan<cfloat_t, 2>(coeffs);
new (new_obj) fp::SummedPauliOp<float_type>(pauli_strings, coeffs_mdspan);
})
.def("__init__",
[](fp::SummedPauliOp<float_type> *new_obj, std::vector<std::string> &pauli_strings,
nb::ndarray<cfloat_t> coeffs) {
//
auto coeffs_mdspan = fp::__detail::ndarray_to_mdspan<cfloat_t, 2>(coeffs);
.def(
"__init__",
[](fp::SummedPauliOp<float_type> *new_obj, std::vector<fp::PauliString> const &pauli_strings,
nb::ndarray<cfloat_t> coeffs) {
auto coeffs_mdspan = fp::__detail::ndarray_to_mdspan<cfloat_t, 2>(coeffs);
new (new_obj) fp::SummedPauliOp<float_type>(pauli_strings, coeffs_mdspan);
},
"pauli_strings"_a, "coeffs"_a, R"%(Initialize SummedPauliOp from PauliStrings and coefficients.
new (new_obj) fp::SummedPauliOp<float_type>(pauli_strings, coeffs_mdspan);
})
Parameters
----------
pauli_strings : List[PauliString]
List of PauliStrings to use in the SummedPauliOp (n_pauli_strings,)
coeffs : np.ndarray
Array of coefficients corresponding to the PauliStrings (n_pauli_strings, n_operators)
Returns
-------
SummedPauliOp
New SummedPauliOp instance
)%")
.def(
"__init__",
[](fp::SummedPauliOp<float_type> *new_obj, std::vector<std::string> &pauli_strings,
nb::ndarray<cfloat_t> coeffs) {
//
auto coeffs_mdspan = fp::__detail::ndarray_to_mdspan<cfloat_t, 2>(coeffs);

new (new_obj) fp::SummedPauliOp<float_type>(pauli_strings, coeffs_mdspan);
},
"pauli_strings"_a, "coeffs"_a, R"%(Initialize SummedPauliOp from PauliStrings and coefficients.
Parameters
----------
pauli_strings : List[str]
List of PauliStrings to use in the SummedPauliOp (n_pauli_strings,)
coeffs : np.ndarray
Array of coefficients corresponding to the PauliStrings (n_pauli_strings, n_operators)
Returns
-------
SummedPauliOp
New SummedPauliOp instance
)%")

.def_prop_ro("dim", &fp::SummedPauliOp<float_type>::dim)
.def_prop_ro("n_operators", &fp::SummedPauliOp<float_type>::n_operators)
Expand All @@ -937,7 +967,7 @@ np.ndarray
auto new_states = fp::__detail::owning_ndarray_like_mdspan<cfloat_t, 2>(states_mdspan);
auto new_states_mdspan = fp::__detail::ndarray_to_mdspan<cfloat_t, 2>(new_states);

self.apply_weighted<float_type>(std::execution::par, new_states_mdspan, states_mdspan, data_mdspan);
self.apply_weighted(std::execution::par, new_states_mdspan, states_mdspan, data_mdspan);

return new_states;
})
Expand Down

0 comments on commit f83d39d

Please sign in to comment.