From 4cfdb5a56bae97e467fe9c7f14bfc161ba378cef Mon Sep 17 00:00:00 2001 From: Alex McCaskey Date: Fri, 7 Mar 2025 17:33:11 +0000 Subject: [PATCH] remove use of get_raw_data and for_each_term Signed-off-by: Alex McCaskey --- libs/qec/lib/stabilizer_utils.cpp | 15 ++++-- .../operator_pools/spin_complement_gsd.cpp | 48 ++----------------- libs/solvers/lib/qaoa/qaoa.cpp | 4 +- .../python/tests/test_jordan_wigner.py | 9 +--- libs/solvers/unittests/test_bravyi_kitaev.cpp | 29 ++++++----- 5 files changed, 36 insertions(+), 69 deletions(-) diff --git a/libs/qec/lib/stabilizer_utils.cpp b/libs/qec/lib/stabilizer_utils.cpp index 40caaa2a..62bc1d53 100644 --- a/libs/qec/lib/stabilizer_utils.cpp +++ b/libs/qec/lib/stabilizer_utils.cpp @@ -62,6 +62,13 @@ to_parity_matrix(const std::vector &stabilizers, p_stabilizers = &stabilizers_copy; } + auto isZ = [](const cudaq::spin_op &op, std::size_t idx) { + return op.to_string(false)[idx] == 'Z'; + }; + auto isX = [](const cudaq::spin_op &op, std::size_t idx) { + return op.to_string(false)[idx] == 'X'; + }; + if (type == stabilizer_type::XZ) { auto numQubits = (*p_stabilizers)[0].num_qubits(); cudaqx::tensor t({p_stabilizers->size(), 2 * numQubits}); @@ -76,7 +83,7 @@ to_parity_matrix(const std::vector &stabilizers, // Need to shift Z bits left for (std::size_t row = 0; row < numZRows; row++) { for (std::size_t i = numQubits; i < 2 * numQubits; i++) { - if ((*p_stabilizers)[row].get_raw_data().first[0][i]) + if (isZ((*p_stabilizers)[row], i - numQubits)) t.at({row, i - numQubits}) = 1; } } @@ -85,7 +92,7 @@ to_parity_matrix(const std::vector &stabilizers, for (std::size_t row = 0; row < numXRows; row++) { for (std::size_t i = 0; i < numQubits; i++) { - if ((*p_stabilizers)[numZRows + row].get_raw_data().first[0][i]) + if (isX((*p_stabilizers)[numZRows + row], i)) t.at({numZRows + row, i + numQubits}) = 1; } } @@ -109,7 +116,7 @@ to_parity_matrix(const std::vector &stabilizers, cudaqx::tensor ret({numZRows, numQubits}); for (std::size_t row = 0; row < numZRows; row++) { for (std::size_t i = numQubits; i < 2 * numQubits; i++) { - if ((*p_stabilizers)[row].get_raw_data().first[0][i]) + if (isZ((*p_stabilizers)[row], i - numQubits)) ret.at({row, i - numQubits}) = 1; } } @@ -134,7 +141,7 @@ to_parity_matrix(const std::vector &stabilizers, cudaqx::tensor ret({numXRows, numQubits}); for (std::size_t row = 0; row < numXRows; row++) { for (std::size_t i = 0; i < numQubits; i++) { - if ((*p_stabilizers)[numZRows + row].get_raw_data().first[0][i]) + if (isX((*p_stabilizers)[numZRows + row], i)) ret.at({row, i}) = 1; } } diff --git a/libs/solvers/lib/operators/operator_pools/spin_complement_gsd.cpp b/libs/solvers/lib/operators/operator_pools/spin_complement_gsd.cpp index 30541c2a..a06bc523 100644 --- a/libs/solvers/lib/operators/operator_pools/spin_complement_gsd.cpp +++ b/libs/solvers/lib/operators/operator_pools/spin_complement_gsd.cpp @@ -48,21 +48,7 @@ spin_complement_gsd::generate(const heterogeneous_map &config) const { adag(numQubits, p) * a(numQubits, q); oneElectron += adag(numQubits, q + 1) * a(numQubits, p + 1) - adag(numQubits, p + 1) * a(numQubits, q + 1); - - std::unordered_map> - terms; - oneElectron.for_each_term([&](cudaq::spin_op &term) { - auto coeff = term.get_coefficient(); - if (std::fabs(coeff.real()) < 1e-12 && std::fabs(coeff.imag()) < 1e-12) - return; - - if (std::fabs(coeff.real()) < 1e-12) - terms.insert({term.get_raw_data().first[0], - std::complex{0., coeff.imag()}}); - }); - - if (!terms.empty()) - pool.emplace_back(terms); + pool.push_back(oneElectron); } } @@ -88,22 +74,7 @@ spin_complement_gsd::generate(const heterogeneous_map &config) const { adag(numQubits, s + 1) * a(numQubits, q + 1) - adag(numQubits, q + 1) * a(numQubits, s + 1) * adag(numQubits, p + 1) * a(numQubits, r + 1); - - std::unordered_map> - terms; - twoElectron.for_each_term([&](cudaq::spin_op &term) { - auto coeff = term.get_coefficient(); - if (std::fabs(coeff.real()) < 1e-12 && - std::fabs(coeff.imag()) < 1e-12) - return; - - if (std::fabs(coeff.real()) < 1e-12) - terms.insert({term.get_raw_data().first[0], - std::complex{0., coeff.imag()}}); - }); - - if (!terms.empty()) - pool.push_back(terms); + pool.push_back(twoElectron); rs++; } } @@ -133,20 +104,7 @@ spin_complement_gsd::generate(const heterogeneous_map &config) const { adag(numQubits, r + 1) * a(numQubits, p + 1) - adag(numQubits, p + 1) * a(numQubits, r + 1) * adag(numQubits, q - 1) * a(numQubits, s - 1); - std::unordered_map> - terms; - twoElectron.for_each_term([&](cudaq::spin_op &term) { - auto coeff = term.get_coefficient(); - if (std::fabs(coeff.real()) < 1e-12 && - std::fabs(coeff.imag()) < 1e-12) - return; - - if (std::fabs(coeff.real()) < 1e-12) - terms.insert({term.get_raw_data().first[0], - std::complex{0., coeff.imag()}}); - }); - if (!terms.empty()) - pool.push_back(terms); + pool.push_back(twoElectron); rs++; } } diff --git a/libs/solvers/lib/qaoa/qaoa.cpp b/libs/solvers/lib/qaoa/qaoa.cpp index 369b8194..7fa2b5c4 100644 --- a/libs/solvers/lib/qaoa/qaoa.cpp +++ b/libs/solvers/lib/qaoa/qaoa.cpp @@ -41,10 +41,10 @@ std::size_t get_num_qaoa_parameters(const cudaq::spin_op &problemHamiltonian, std::size_t expectedNumParams = 0; if (full_parameterization) { auto nonIdTerms = 0; - referenceHamiltonian.for_each_term([&](cudaq::spin_op &term) { + for (const auto &term : referenceHamiltonian) if (!term.is_identity()) nonIdTerms++; - }); + expectedNumParams = numLayers * (problemHamiltonian.num_terms() + nonIdTerms); } else { diff --git a/libs/solvers/python/tests/test_jordan_wigner.py b/libs/solvers/python/tests/test_jordan_wigner.py index 38647923..8ad7d8ac 100644 --- a/libs/solvers/python/tests/test_jordan_wigner.py +++ b/libs/solvers/python/tests/test_jordan_wigner.py @@ -14,16 +14,11 @@ def extract_words(hamiltonian: cudaq.SpinOperator): - result = [] - hamiltonian.for_each_term(lambda term: result.append(term.to_string(False))) - return result + return [term.to_string(False) for term in hamiltonian] def extract_coefficients(hamiltonian: cudaq.SpinOperator): - result = [] - hamiltonian.for_each_term( - lambda term: result.append(term.get_coefficient())) - return result + return [term.get_coefficient() for term in hamiltonian] def extract_spin_op_to_dict(op: cudaq.SpinOperator) -> dict: diff --git a/libs/solvers/unittests/test_bravyi_kitaev.cpp b/libs/solvers/unittests/test_bravyi_kitaev.cpp index 8f95e2ce..4be74f0b 100644 --- a/libs/solvers/unittests/test_bravyi_kitaev.cpp +++ b/libs/solvers/unittests/test_bravyi_kitaev.cpp @@ -15,6 +15,13 @@ #include "cudaq/solvers/operators/molecule/fermion_compilers/bravyi_kitaev.h" +auto get_coefficients(const cudaq::spin_op &op) { + std::vector> ret; + for (const auto &term : op) + ret.push_back(term.get_coefficient()); + return ret; +} + // One- and Two-body integrals were copied from test_molecule.cpp. // They were further validated using the script ./support/h2_pyscf_hf.py. // @@ -77,7 +84,7 @@ TEST(BravyiKitaev, testH2Hamiltonian) { 0.12020049071260128 * z(0) * z(2) * z(3) + 0.1683359862516207 * z(1) - 0.22004130022421792 * z(1) * z(2) * z(3) + 0.17407289249680227 * z(1) * z(3) - 0.22004130022421792 * z(2); - auto [terms, residuals] = (result - gold).get_raw_data(); + auto residuals = get_coefficients(result - gold); for (auto r : residuals) EXPECT_NEAR(std::abs(r), 0.0, 1e-4); } @@ -91,7 +98,7 @@ TEST(BravyiKitaev, testSRLCase0) { cudaq::spin_op gold = double_complex(-2.0, 0.0) * i(0) * i(1) * z(2) + double_complex(2.0, 0.0) * i(0) * i(1) * i(2); - auto [terms, residuals] = (result - gold).get_raw_data(); + auto residuals = get_coefficients(result - gold); for (auto r : residuals) EXPECT_NEAR(std::abs(r), 0.0, 1e-4); } @@ -109,7 +116,7 @@ TEST(BravyiKitaev, testSRLCase1) { i(4) * z(5) * x(6) + double_complex(0.0, -1.0) * i(0) * z(1) * y(2) * y(3) * i(4) * z(5) * y(6); - auto [terms, residuals] = (result - gold).get_raw_data(); + auto residuals = get_coefficients(result - gold); for (auto r : residuals) EXPECT_NEAR(std::abs(r), 0.0, 1e-4); } @@ -125,7 +132,7 @@ TEST(BravyiKitaev, testSRLCase2) { double_complex(1.0, 0.0) * z(1) * x(2) * y(3) * y(5) + double_complex(0.0, 1.0) * z(1) * y(2) * y(3) * y(5); - auto [terms, residuals] = (result - gold).get_raw_data(); + auto residuals = get_coefficients(result - gold); for (auto r : residuals) EXPECT_NEAR(std::abs(r), 0.0, 1e-4); } @@ -140,7 +147,7 @@ TEST(BravyiKitaev, testSRLCase3) { double_complex(1.0, 0.0) * i(0) * x(1) * x(2) + double_complex(0.0, 1.0) * i(0) * x(1) * y(2); - auto [terms, residuals] = (result - gold).get_raw_data(); + auto residuals = get_coefficients(result - gold); for (auto r : residuals) EXPECT_NEAR(std::abs(r), 0.0, 1e-4); } @@ -156,7 +163,7 @@ TEST(BravyiKitaev, testSRLCase4) { double_complex(1.0, 0.0) * x(0) * x(1) * i(2) * y(3) * i(4) * y(5) + double_complex(0.0, -1.0) * y(0) * x(1) * i(2) * y(3) * i(4) * y(5); - auto [terms, residuals] = (result - gold).get_raw_data(); + auto residuals = get_coefficients(result - gold); for (auto r : residuals) EXPECT_NEAR(std::abs(r), 0.0, 1e-4); } @@ -171,7 +178,7 @@ TEST(BravyiKitaev, testSRLCase6) { double_complex(0.0, 1.0) * z(17) * y(18) * z(19) + double_complex(-1.0, 0.0) * z(17) * x(18) * z(19); - auto [terms, residuals] = (result - gold).get_raw_data(); + auto residuals = get_coefficients(result - gold); for (auto r : residuals) EXPECT_NEAR(std::abs(r), 0.0, 1e-4); } @@ -188,7 +195,7 @@ TEST(BravyiKitaev, testSRLCase7) { double_complex(1.0, 0.0) * z(3) * z(4) * x(5) * y(7) * y(11) + double_complex(0.0, 1.0) * z(3) * y(5) * y(7) * y(11); - auto [terms, residuals] = (result - gold).get_raw_data(); + auto residuals = get_coefficients(result - gold); for (auto r : residuals) EXPECT_NEAR(std::abs(r), 0.0, 1e-4); } @@ -205,7 +212,7 @@ TEST(BravyiKitaev, testSRLCase8) { double_complex(1.0, 0.0) * x(7) * z(8) * x(9) * x(11) + double_complex(0.0, 1.0) * x(7) * y(9) * x(11); - auto [terms, residuals] = (result - gold).get_raw_data(); + auto residuals = get_coefficients(result - gold); for (auto r : residuals) EXPECT_NEAR(std::abs(r), 0.0, 1e-4); } @@ -221,7 +228,7 @@ TEST(BravyiKitaev, testSRLCase9) { double_complex(-1.0, 0.0) * z(7) * z(8) * x(9) * x(11) * z(15) + double_complex(0.0, 1.0) * z(7) * y(9) * x(11) * z(15); - auto [terms, residuals] = (result - gold).get_raw_data(); + auto residuals = get_coefficients(result - gold); for (auto r : residuals) EXPECT_NEAR(std::abs(r), 0.0, 1e-4); } @@ -237,7 +244,7 @@ TEST(BravyiKitaev, testSRLCase10) { double_complex(-1.0, 0.0) * z(1) * z(2) * x(3) * z(7) + double_complex(0.0, 1.0) * y(3) * z(7); - auto [terms, residuals] = (result - gold).get_raw_data(); + auto residuals = get_coefficients(result - gold); for (auto r : residuals) EXPECT_NEAR(std::abs(r), 0.0, 1e-4); }