Skip to content

2nd order Trotter and Corresponding Error Bounds#384

Open
v-agamshayit wants to merge 25 commits intomainfrom
feature/agamshayit/2ndordertrotter
Open

2nd order Trotter and Corresponding Error Bounds#384
v-agamshayit wants to merge 25 commits intomainfrom
feature/agamshayit/2ndordertrotter

Conversation

@v-agamshayit
Copy link
Contributor

Added support for second-order Trotter time evolution. Implemented the Naive and commutator-based error bounds for the second-order Trotter formula and added some tests

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds second-order (Strang) Trotter time evolution support and extends the Trotter step-count estimation utilities with second-order naive and commutator-based error bounds, along with new tests covering the added behavior.

Changes:

  • Extend Trotter builder to support order=2 decomposition.
  • Add second-order commutator-bound calculation and integrate it into step estimation.
  • Expand Python test coverage for second-order decomposition and error-bound step selection.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
python/src/qdk_chemistry/algorithms/time_evolution/builder/trotter.py Add order=2 path in builder and implement second-order step decomposition.
python/src/qdk_chemistry/algorithms/time_evolution/builder/trotter_error.py Extend naive/commutator step estimators to support order=2.
python/src/qdk_chemistry/utils/pauli_commutation.py Add nested-commutator vanishing check and second-order commutator bound computation.
python/tests/test_trotter_error.py Add second-order error-bound tests and update unsupported-order checks.
python/tests/test_time_evolution_trotter.py Add second-order builder tests and accuracy-aware step selection tests for order=2.
Comments suppressed due to low confidence (14)

python/src/qdk_chemistry/algorithms/time_evolution/builder/trotter.py:223

  • The docstring lists an order argument here, but _decompose_trotter_step doesn’t accept an order parameter (it reads from self._settings). This is misleading for readers and for generated docs; please remove or reword this Args entry.
        """Decompose a single Trotter step into exponentiated Pauli terms.

        Args:
            qubit_hamiltonian: The qubit Hamiltonian to be decomposed.
            time: The evolution time for the single step.
            order: The order of the Trotter decomposition.
            atol: Absolute tolerance for filtering small coefficients.

python/tests/test_trotter_error.py:138

  • This test compares order=2 commutator steps against the default naive steps (which are order=1). If the intent is “commutator bound is never looser than naive” for second-order, call trotter_steps_naive(..., order=2) so both bounds are for the same order.
    def test_tighter_than_naive_second_order(self):
        """Test that commutator bound is never looser than naive."""
        h = QubitHamiltonian(pauli_strings=["X", "Z"], coefficients=[1.0, 1.0])
        eps = 0.01
        time = 1.0
        n_naive = trotter_steps_naive(h, time, eps)
        n_comm = trotter_steps_commutator(h, time, eps, order=2)
        assert n_comm <= n_naive

python/tests/test_trotter_error.py:122

  • The arithmetic in this comment is inconsistent: ceil(10) = 4 is incorrect and the intermediate value here isn’t 10 for the given formula. Please fix the comment so it matches the actual calculation that leads to 4 steps (to avoid misleading future maintainers).
        # X and Z anticommute: commutator bound = 2 * 2**2 = 8
        # N = ceil(sqrt(8) * 1**(3/2) / (sqrt(3! * 0.1))) = ceil(10) = 4
        h = QubitHamiltonian(pauli_strings=["X", "Z"], coefficients=[1.0, 1.0])

python/tests/test_time_evolution_trotter.py:395

  • The explanatory comment doesn’t match the asserted result. With the current commutator_bound_second_order implementation for H=X+Z, the bound is 8 (not 4), which yields N=12 for t=1, eps=0.01. Please update the comment so the derivation matches the expected step count.
        # H = X + Z, X and Z anticommute -> commutator bound = 4
        # N = ceil(sqrt(4) * t^(3/2) / (sqrt(3! * eps))) = 17
        hamiltonian = QubitHamiltonian(pauli_strings=["X", "Z"], coefficients=[1.0, 1.0])
        builder = Trotter(target_accuracy=0.01, order=2)
        unitary = builder.run(hamiltonian, time=1.0)
        container = unitary.get_container()
        assert container.step_reps == 12

python/tests/test_time_evolution_trotter.py:404

  • This comment uses 2^1/2, but the implemented naive formula for order=2 scales like one_norm^(3/2) / sqrt(eps) (for t=1). Consider updating the comment to 2^(3/2) / 0.1 = 28.28 -> 29 so it matches the actual computation.
        container = unitary.get_container()
        # one_norm = 2, N = ceil(2^1/2 / 0.01) = 29
        assert container.step_reps == 29

python/src/qdk_chemistry/algorithms/time_evolution/builder/trotter_error.py:110

  • The displayed second-order equation (N_2 = t^3/3! * sum ...) does not match what this function returns (a step count) nor the scaling implemented below (which solves for N given ε, including a factorial factor and a root). Please rewrite the math block so it defines N for order=2 in terms of ε and the computed commutator sum.
    The tighter commutator-based bound from Childs *et al.* (2021) is

    .. math::

        N_1 = \left\lceil \frac{t^2}{2\epsilon}
            \sum_{j<k} \lVert [\alpha_j P_j,\, \alpha_k P_k] \rVert
        \right\rceil

        N_2 = \frac{t^3}{3!} \sum_{j < k < l}
            \lVert \lvert [\alpha_j P_l,\, [\alpha_j P_j,\, \alpha_k P_k] \rVert ] \rVert

python/src/qdk_chemistry/utils/pauli_commutation.py:321

  • The math in this docstring appears inconsistent (index names don’t match, e.g. P_i/P_l, and the triple-sum condition j < k < l doesn’t reflect the (i, j, k) iteration used below). Please update the formula/description so it matches the actual bound being computed.
    r"""Compute the second-order Trotter commutator bound.

    For a Hamiltonian :math:`H = \sum_j \alpha_j P_j` the second-order
    (Lie-Trotter) product formula has error bounded by

    .. math::

        \lVert U(t) - S_2(t) \rVert \le
            \frac{t^3}{3!} \sum_{j < k < l}
            \lVert \lvert [\alpha_j P_i,\, [\alpha_j P_j,\, \alpha_k P_k] \rVert ] \rVert

python/src/qdk_chemistry/utils/pauli_commutation.py:331

  • This docstring says users should multiply by t^3 / (3! * N) to get the per-step error, but the second-order Strang error scales like O(t^3 / N^2) for a full evolution split into N steps. Please correct the N-dependence described here to match how trotter_steps_commutator(..., order=2) solves for N.
    This function returns
    :math:`\sum_{j < k < l}
            \lVert \lvert [\alpha_j P_i,\, [\alpha_j P_j,\, \alpha_k P_k] \rVert ] \rVert`,
    so the user can multiply by :math:`t^{3} / (3! * N)` to get the per-step
    error.

python/tests/test_time_evolution_trotter.py:284

  • The comment says the second-order error should scale as O(t^2), but the assertion uses atol=t**3, which corresponds to the expected O(t^3) global error scaling for a second-order (Strang) formula at fixed step count. Please correct the comment to avoid confusion.
        # Compare: the error should scale as O(t^2) for second-order Trotter
        assert np.allclose(u_trot, u_exact, atol=t**3)

python/src/qdk_chemistry/algorithms/time_evolution/builder/trotter_error.py:87

  • This return statement is likely to exceed the configured Ruff line length (120) and is hard to read/maintain in its current form. Consider breaking the expression into intermediate variables or multiple lines so it passes formatting/linting consistently.
    real_terms = hamiltonian.get_real_coefficients(tolerance=weight_threshold)
    one_norm = sum(abs(coeff) for _, coeff in real_terms)
    return max(1, math.ceil((one_norm ** (1 + 1 / order) * time ** (1 + 1 / order)) / (target_accuracy ** (1 / order))))

python/src/qdk_chemistry/algorithms/time_evolution/builder/trotter.py:152

  • This method is now used for both order=1 and order=2, but the docstring still describes only the first-order formula. Please update the docstring to document the second-order (Strang) construction as well, since it’s part of the public behavior now.
    def _first_or_second_order_trotter(self, qubit_hamiltonian: QubitHamiltonian, time: float) -> TimeEvolutionUnitary:
        r"""Construct the time evolution unitary using first-order Trotter decomposition.

        The First Order Trotter method approximates the time evolution operator :math:`e^{-iHt}`
        by decomposing the Hamiltonian H into a sum of terms and using the product formula:
        :math:`e^{-iHt} \approx \left[\prod_i e^{-iH_i t/n}\right]^n`, where n is the number of divisions.

python/src/qdk_chemistry/algorithms/time_evolution/builder/trotter.py:255

  • get_real_coefficients(tolerance=atol) is called three times in the order == 2 branch (slice, last element, reversed slice). Cache the filtered term list once to avoid repeated work and to guarantee consistent ordering across the forward/center/reverse parts.
            # \prod_{i=1}^{L-1} e^{-iH_i t/(2n)}
            for label, coeff in qubit_hamiltonian.get_real_coefficients(tolerance=atol)[:-1]:
                mapping = self._pauli_label_to_map(label)
                angle = coeff * time / 2
                terms.append(ExponentiatedPauliTerm(pauli_term=mapping, angle=angle))
            # e^{-iH_L t/n}
            label, coeff = qubit_hamiltonian.get_real_coefficients(tolerance=atol)[-1]
            mapping = self._pauli_label_to_map(label)
            angle = coeff * time
            terms.append(ExponentiatedPauliTerm(pauli_term=mapping, angle=angle))

            # \prod_{i=L-1}^1 e^{-iH_i t/(2n)}
            for label, coeff in reversed(qubit_hamiltonian.get_real_coefficients(tolerance=atol)[:-1]):
                mapping = self._pauli_label_to_map(label)

python/src/qdk_chemistry/utils/pauli_commutation.py:43

  • commutator_bound_second_order() is a new top-level API in this module but isn’t included in __all__, while commutator_bound_first_order() is. If the second-order bound is intended to be public (it’s already imported elsewhere), add it to __all__ for consistency.
__all__: list[str] = [
    "commutator_bound_first_order",
    "do_pauli_labels_commute",
    "do_pauli_labels_qw_commute",
    "do_pauli_maps_commute",
    "do_pauli_maps_qw_commute",
    "does_nested_commutator_vanish",
    "get_commutation_checker",
]

python/tests/test_trotter_error.py:151

  • The docstring says t^3 scaling, but the assertion below checks t^(3/2) scaling (2**1.5). Please update the docstring/comment so it matches the expected scaling for how N depends on t for the second-order bound.
    def test_time_scaling_second_order(self):
        """Test that step count scales with t^3."""
        h = QubitHamiltonian(pauli_strings=["X", "Z"], coefficients=[1.0, 1.0])
        n1 = trotter_steps_commutator(h, 1.0, 0.1, order=2)
        n2 = trotter_steps_commutator(h, 2.0, 0.1, order=2)
        # n2 should be approximately 2**1.5 * n1 (t^1.5 scaling)
        assert n2 >= math.ceil(2**1.5) * n1 - 1  # Allow for ceiling effects

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI commented Mar 2, 2026

@v-agamshayit I've opened a new pull request, #385, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI and others added 2 commits March 2, 2026 19:57
…d orders

Co-authored-by: v-agamshayit <257422224+v-agamshayit@users.noreply.github.com>
Copy link
Contributor

Copilot AI commented Mar 2, 2026

@v-agamshayit I've opened a new pull request, #386, to work on those changes. Once the pull request is ready, I'll request review from you.

@github-actions
Copy link

github-actions bot commented Mar 2, 2026

📊 Coverage Summary

Component Coverage
C++ Library 78%
Python Package 86%
Pybind11 Bindings 89%

Detailed Coverage Reports

C++ Coverage Details
------------------------------------------------------------------------------
                           GCC Code Coverage Report
Directory: cpp
------------------------------------------------------------------------------
File                                       Lines    Exec  Cover   Missing
------------------------------------------------------------------------------
include/qdk/chemistry/algorithms/active_space.hpp
                                               5       5   100%
include/qdk/chemistry/algorithms/algorithm.hpp
                                              60      55    91%   187,209,211-212,270
include/qdk/chemistry/algorithms/dynamical_correlation_calculator.hpp
                                               7       6    85%   115
include/qdk/chemistry/algorithms/hamiltonian.hpp
                                               5       5   100%
include/qdk/chemistry/algorithms/localization.hpp
                                               5       5   100%
include/qdk/chemistry/algorithms/mc.hpp       18      18   100%
include/qdk/chemistry/algorithms/mcscf.hpp
                                               6       6   100%
include/qdk/chemistry/algorithms/pmc.hpp       9       8    88%   186
include/qdk/chemistry/algorithms/scf.hpp      13      12    92%   23
include/qdk/chemistry/algorithms/stability.hpp
                                               5       4    80%   131
include/qdk/chemistry/data/ansatz.hpp          3       3   100%
include/qdk/chemistry/data/basis_set.hpp      35      30    85%   108-109,112,114,319
include/qdk/chemistry/data/configuration.hpp
                                              32      30    93%   71,119
include/qdk/chemistry/data/configuration_set.hpp
                                               3       2    66%   35
include/qdk/chemistry/data/data_class.hpp
                                               4       4   100%
include/qdk/chemistry/data/element_data.hpp
                                              18      18   100%
include/qdk/chemistry/data/hamiltonian.hpp
                                              12      12   100%
include/qdk/chemistry/data/hamiltonian_containers/canonical_four_center.hpp
                                               1       1   100%
include/qdk/chemistry/data/hamiltonian_containers/cholesky.hpp
                                               1       1   100%
include/qdk/chemistry/data/hamiltonian_containers/sparse.hpp
                                               1       1   100%
include/qdk/chemistry/data/lattice_graph.hpp
                                               3       1    33%   324-325
include/qdk/chemistry/data/orbitals.hpp        6       6   100%
include/qdk/chemistry/data/pauli_operator.hpp
                                              88      83    94%   1203,1227,1262,1274,1288
include/qdk/chemistry/data/settings.hpp       90      68    75%   180-181,311,353,488,857,864,866,881-882,886-888,892-893,895-897,899-900,989,993
include/qdk/chemistry/data/stability_result.hpp
                                              38      38   100%
include/qdk/chemistry/data/structure.hpp       8       8   100%
include/qdk/chemistry/data/wavefunction.hpp
                                              25      19    76%   496,502,510-512,673
include/qdk/chemistry/data/wavefunction_containers/cas.hpp
                                               1       1   100%
include/qdk/chemistry/data/wavefunction_containers/cc.hpp
                                               1       1   100%
include/qdk/chemistry/data/wavefunction_containers/mp2.hpp
                                               1       1   100%
include/qdk/chemistry/data/wavefunction_containers/sci.hpp
                                               1       1   100%
include/qdk/chemistry/data/wavefunction_containers/sd.hpp
                                               1       1   100%
include/qdk/chemistry/utils/hash.hpp           4       4   100%
include/qdk/chemistry/utils/logger.hpp        41      35    85%   223-224,226,233-234,236
include/qdk/chemistry/utils/model_hamiltonians.hpp
                                             119     110    92%   101,105,109,113,186,253,257,406,410
include/qdk/chemistry/utils/string_utils.hpp
                                              11      10    90%   41
src/qdk/chemistry/algorithms/active_space.cpp
                                             232     142    61%   35-36,40-41,45-46,116-118,143-145,147,151-154,156-159,162-163,165-168,173-174,176-179,182-184,187-189,191,194-196,218,220,224,226-229,231-232,236-239,241,243,246-249,251,253,255-256,277-278,307,310,342,347-348,350-353,355-357,359-360,363,367,369-371,413,415,417
src/qdk/chemistry/algorithms/dynamical_correlation_calculator.cpp
                                               8       8   100%
src/qdk/chemistry/algorithms/hamiltonian.cpp
                                              14      14   100%
src/qdk/chemistry/algorithms/localization.cpp
                                              15      15   100%
src/qdk/chemistry/algorithms/mc.cpp           11      11   100%
src/qdk/chemistry/algorithms/microsoft/active_space/autocas_active_space.cpp
                                              80      78    97%   103,133
src/qdk/chemistry/algorithms/microsoft/active_space/autocas_active_space.hpp
                                              16      16   100%
src/qdk/chemistry/algorithms/microsoft/active_space/entropy_active_space.cpp
                                              41      41   100%
src/qdk/chemistry/algorithms/microsoft/active_space/entropy_active_space.hpp
                                              10      10   100%
src/qdk/chemistry/algorithms/microsoft/active_space/occupation_active_space.cpp
                                              60      54    90%   46,48,81,83,101-102
src/qdk/chemistry/algorithms/microsoft/active_space/occupation_active_space.hpp
                                               6       6   100%
src/qdk/chemistry/algorithms/microsoft/active_space/valence_active_space.cpp
                                              75      63    84%   34,36,68-69,76-77,104-105,120-121,124-125
src/qdk/chemistry/algorithms/microsoft/active_space/valence_active_space.hpp
                                               9       9   100%
src/qdk/chemistry/algorithms/microsoft/cholesky_hamiltonian.cpp
                                             465     421    90%   94,98,417,436,439-440,459,470,473-474,504-505,554-555,561-563,570-571,578-579,610,613-614,629,637,639-641,791,793,805,810,824,831,894,899-900,902-903,1012-1013,1016-1017
src/qdk/chemistry/algorithms/microsoft/cholesky_hamiltonian.hpp
                                              11      11   100%
src/qdk/chemistry/algorithms/microsoft/hamiltonian.cpp
                                             247     230    93%   46-47,53-55,62-63,105-106,165-166,293,295,306,318,380,488
src/qdk/chemistry/algorithms/microsoft/hamiltonian.hpp
                                              10      10   100%
src/qdk/chemistry/algorithms/microsoft/localization/iterative_localizer_base.cpp
                                               5       5   100%
src/qdk/chemistry/algorithms/microsoft/localization/iterative_localizer_base.hpp
                                               8       8   100%
src/qdk/chemistry/algorithms/microsoft/localization/mp2_natural_orbitals.cpp
                                              79      74    93%   44,81,83,104,106
src/qdk/chemistry/algorithms/microsoft/localization/mp2_natural_orbitals.hpp
                                               3       3   100%
src/qdk/chemistry/algorithms/microsoft/localization/pipek_mezey.cpp
                                             169     160    94%   26,34,41,43,47,49,246,329,332
src/qdk/chemistry/algorithms/microsoft/localization/pipek_mezey.hpp
                                               6       6   100%
src/qdk/chemistry/algorithms/microsoft/localization/vvhv.cpp
                                             646     575    89%   336,338-339,452-453,476,534,695,739,741,746,762-765,768,778-781,784,819-821,827-831,859-862,865,887,889-891,968-972,1018-1022,1040-1043,1047-1050,1052-1054,1057,1131,1194-1196,1267,1286,1289,1293,1295,1300-1301
src/qdk/chemistry/algorithms/microsoft/localization/vvhv.hpp
                                               6       6   100%
src/qdk/chemistry/algorithms/microsoft/macis_asci.cpp
                                              56      53    94%   51,144,146
src/qdk/chemistry/algorithms/microsoft/macis_asci.hpp
                                              61      61   100%
src/qdk/chemistry/algorithms/microsoft/macis_base.cpp
                                              74      58    78%   29-31,41,46,98-99,102,106-107,110-112,119-121
src/qdk/chemistry/algorithms/microsoft/macis_base.hpp
                                              87      64    73%   62-67,69,178-180,182,185,187,190-192,194-196,198-200,202
src/qdk/chemistry/algorithms/microsoft/macis_cas.cpp
                                              45      42    93%   47,109,111
src/qdk/chemistry/algorithms/microsoft/macis_cas.hpp
                                               3       3   100%
src/qdk/chemistry/algorithms/microsoft/macis_pmc.cpp
                                              82      80    97%   114,153
src/qdk/chemistry/algorithms/microsoft/macis_pmc.hpp
                                              16      16   100%
src/qdk/chemistry/algorithms/microsoft/mp2.cpp
                                             191     173    90%   33,78,82-83,93-94,97,101-102,142-143,146-147,157-158,161,165-166
src/qdk/chemistry/algorithms/microsoft/mp2.hpp
                                               2       2   100%
src/qdk/chemistry/algorithms/microsoft/scf.cpp
                                             270     253    93%   101-102,132-133,141,143,197,242,317,349,354,356,382-384,403,474
src/qdk/chemistry/algorithms/microsoft/scf.hpp
                                              18      18   100%
src/qdk/chemistry/algorithms/microsoft/scf/include/qdk/chemistry/scf/core/basis_set.h
                                               9       8    88%   134
src/qdk/chemistry/algorithms/microsoft/scf/include/qdk/chemistry/scf/core/enums.h
                                              16       0     0%   38-39,48-49,54-59,70-75
src/qdk/chemistry/algorithms/microsoft/scf/include/qdk/chemistry/scf/core/eri.h
                                              15      12    80%   46-47,49
src/qdk/chemistry/algorithms/microsoft/scf/include/qdk/chemistry/scf/core/exc.h
                                               3       3   100%
src/qdk/chemistry/algorithms/microsoft/scf/include/qdk/chemistry/scf/core/moeri.h
                                               3       3   100%
src/qdk/chemistry/algorithms/microsoft/scf/include/qdk/chemistry/scf/core/molecule.h
                                               1       1   100%
src/qdk/chemistry/algorithms/microsoft/scf/include/qdk/chemistry/scf/eri/eri_multiplexer.h
                                               6       3    50%   126-127,135
src/qdk/chemistry/algorithms/microsoft/scf/include/qdk/chemistry/scf/util/cache.h
                                              27      26    96%   44
src/qdk/chemistry/algorithms/microsoft/scf/include/qdk/chemistry/scf/util/class_registry.h
                                              13      13   100%
src/qdk/chemistry/algorithms/microsoft/scf/include/qdk/chemistry/scf/util/gauxc_registry.h
                                               6       5    83%   39
src/qdk/chemistry/algorithms/microsoft/scf/include/qdk/chemistry/scf/util/gauxc_util.h
                                              21      21   100%
src/qdk/chemistry/algorithms/microsoft/scf/include/qdk/chemistry/scf/util/int1e.h
                                               2       2   100%
src/qdk/chemistry/algorithms/microsoft/scf/include/qdk/chemistry/scf/util/singleton.h
                                              13      13   100%
src/qdk/chemistry/algorithms/microsoft/scf/src/core/basis_set.cpp
                                             361     279    77%   33-34,92-93,97-98,146,150-154,157-161,172,183-184,188,190-191,197-198,201-206,210,212-215,217,219,223,225-226,228-229,231,248,257,265-266,313-314,335,337,342-343,345-346,348,401,406-407,415,436,458,460-461,463-465,478,480,482-485,487,490,493-494,542,544,548-549
src/qdk/chemistry/algorithms/microsoft/scf/src/core/scf.cpp
                                               7       7   100%
src/qdk/chemistry/algorithms/microsoft/scf/src/eri/eri.cpp
                                              35      28    80%   58-60,64-65,88-89
src/qdk/chemistry/algorithms/microsoft/scf/src/eri/eri_df_base.cpp
                                              34      32    94%   29-30
src/qdk/chemistry/algorithms/microsoft/scf/src/eri/eri_df_base.h
                                               2       2   100%
src/qdk/chemistry/algorithms/microsoft/scf/src/eri/eri_multiplexer.cpp
                                              61      37    60%   16-17,26-29,40,46-49,52-55,79,81,83-85,87-88,91,93
src/qdk/chemistry/algorithms/microsoft/scf/src/eri/INCORE/incore.cpp
                                              42      29    69%   40,42,44,66,68,70-72,74-75,77-79
src/qdk/chemistry/algorithms/microsoft/scf/src/eri/INCORE/incore_impl.cpp
                                              96      88    91%   44,136,138,235,237,239,287,289
src/qdk/chemistry/algorithms/microsoft/scf/src/eri/INCORE/incore_impl_df.cpp
                                             102      60    58%   86-87,89,203,205,207-214,216-221,224,227-233,236,253,256,263-264,286,291,305-306,309,320-321,323-324,326
src/qdk/chemistry/algorithms/microsoft/scf/src/eri/LIBINT2_DIRECT/libint2_direct.cpp
                                             179     167    93%   592,594,596,893,895-898,901,903-905
src/qdk/chemistry/algorithms/microsoft/scf/src/eri/moeri.cpp
                                              36      34    94%   32-33
src/qdk/chemistry/algorithms/microsoft/scf/src/eri/schwarz.cpp
                                              33      13    39%   80-81,83-88,90-93,95-98,101-102,104,106
src/qdk/chemistry/algorithms/microsoft/scf/src/eri/SNK/snk.cpp
                                              66       0     0%   36,58-60,62-65,67,69-70,72,98,100,102-104,107-110,114-116,119-121,124-127,146,148,150,167-168,170,187,191,193-194,200-201,203,205-207,209,212,214,216-218,221,223,225-227,230,232,234-235,239-240,242-243
src/qdk/chemistry/algorithms/microsoft/scf/src/exc/exc.cpp
                                              16      14    87%   42-43
src/qdk/chemistry/algorithms/microsoft/scf/src/exc/GauXC/gauxc.cpp
                                              34      25    73%   42,46-47,50-52,54,56,67
src/qdk/chemistry/algorithms/microsoft/scf/src/exc/GauXC/gauxc_impl.cpp
                                             229     163    71%   79,119,160-161,249-258,260,262-270,352-353,360-364,366,368-377,380-381,383-384,387-389,396,398-399,405-409,411,413-417,419-420,426
src/qdk/chemistry/algorithms/microsoft/scf/src/scf/cpscf.cpp
                                             234     232    99%   232,237
src/qdk/chemistry/algorithms/microsoft/scf/src/scf/guess.cpp
                                              63      63   100%
src/qdk/chemistry/algorithms/microsoft/scf/src/scf/ks_impl.cpp
                                              81      63    77%   73,75-82,140,155-158,160-161,171-172
src/qdk/chemistry/algorithms/microsoft/scf/src/scf/scf_impl.cpp
                                             546     415    76%   73,101,116,122,167-168,184-185,328-329,338-341,466,470,550,587,606-608,675,714-715,719-720,729-734,744,748-751,753-760,773-777,779-782,784-785,792-793,795-800,802-807,809,817-820,830-831,842-844,858-863,866-869,872,875,877,976-978,981,983,987-988,990-994,996-999,1001-1002,1006,1008,1010-1018,1021-1024,1027-1029,1031,1033
src/qdk/chemistry/algorithms/microsoft/scf/src/scf/scf_impl.h
                                              21      16    76%   98-100,113,161
src/qdk/chemistry/algorithms/microsoft/scf/src/scf/scf_solver.cpp
                                              82      54    65%   35,37,51,55-59,66,68,90,92-93,101-103,111-113,126-128,131-133,141-143
src/qdk/chemistry/algorithms/microsoft/scf/src/scf/soad.cpp
                                              15       0     0%   189,192-204,208
src/qdk/chemistry/algorithms/microsoft/scf/src/scf_algorithm/asahf.cpp
                                             286     275    96%   49,51,68-69,101,271,464-465,506,530-531
src/qdk/chemistry/algorithms/microsoft/scf/src/scf_algorithm/diis.cpp
                                             278     259    93%   147,149,158-159,228,234,241,246,268-269,286,486-489,511,520,528,536
src/qdk/chemistry/algorithms/microsoft/scf/src/scf_algorithm/diis_gdm.cpp
                                              36      36   100%
src/qdk/chemistry/algorithms/microsoft/scf/src/scf_algorithm/gdm.cpp
                                             401     366    91%   226,249,272,443-446,449-452,478-482,487,518-522,664,667-673,805,809,899,903,905
src/qdk/chemistry/algorithms/microsoft/scf/src/scf_algorithm/line_search.h
                                              63      62    98%   60
src/qdk/chemistry/algorithms/microsoft/scf/src/scf_algorithm/scf_algorithm.cpp
                                             143     130    90%   63,71-73,75,85-88,175-176,205,264
src/qdk/chemistry/algorithms/microsoft/scf/src/util/gauxc_util.cpp
                                              85      20    23%   26-31,34-43,48-49,52-59,63-66,68,70,72-74,81-88,92-99,106-111,115-118,122-123,134-135
src/qdk/chemistry/algorithms/microsoft/scf/src/util/int1e.cpp
                                             336     226    67%   206-209,211,243,288,290-296,298-303,305-311,314-315,326,328-329,569,592,622,699,702-703,705,713,755,757-758,762-771,780,782-783,787-796,805,807-808,812-824,826-829,838,941-942,946-954,956-962,964-967,976
src/qdk/chemistry/algorithms/microsoft/scf/src/util/libint2_util.cpp
                                             181      91    50%   39,42-45,47,49-51,53-54,58-60,64-66,72,74,76-79,81-82,85-91,94-95,97-102,104-107,109-119,125-126,477,483-490,492-495,497,499,503-504,506,560,562,566-569,571-573,576,580-582,584,627
src/qdk/chemistry/algorithms/microsoft/scf/src/util/matrix_exp.cpp
                                              53      53   100%
src/qdk/chemistry/algorithms/microsoft/scf/src/util/mpi_vars.h
                                               2       2   100%
src/qdk/chemistry/algorithms/microsoft/scf/src/util/opt/gmresxx/arnoldi/arnoldi.h
                                              12      12   100%
src/qdk/chemistry/algorithms/microsoft/scf/src/util/opt/gmresxx/arnoldi/arnoldi_gmres.h
                                             202     168    83%   53-55,176,183,185-188,190-194,196,198,202,205,209,212,217-218,221,223,290,293-294,298,481-482,493,522-523,589
src/qdk/chemistry/algorithms/microsoft/scf/src/util/opt/gmresxx/linalg.h
                                              40      40   100%
src/qdk/chemistry/algorithms/microsoft/scf/src/util/timer.h
                                              29      29   100%
src/qdk/chemistry/algorithms/microsoft/stability.cpp
                                             317     294    92%   191-192,321-323,411,413,430,433-442,446,448,452,454,493
src/qdk/chemistry/algorithms/microsoft/stability.hpp
                                              13      13   100%
src/qdk/chemistry/algorithms/microsoft/utils.cpp
                                             248     171    69%   45-46,52,54,111-112,123-124,126-127,133,135,138-139,141,143-147,150-151,182,184,186,190-191,195,198-205,207-209,211,214-218,220-225,227-229,231,234-235,237,240-245,251,253-255,258-262,387-388,427,429
src/qdk/chemistry/algorithms/pmc.cpp           8       8   100%
src/qdk/chemistry/algorithms/scf.cpp           7       7   100%
src/qdk/chemistry/algorithms/stability.cpp
                                               6       6   100%
src/qdk/chemistry/data/ansatz.cpp            553     380    68%   26,36,39,46-48,50-51,53,55-56,58-60,62,69,84,99,104-105,107-108,115,120,122,148,150,207,209,280,295,297,302-303,336-340,345,347,357,359,362,364,374,376,379,381,394,396,401,403-404,410,412,417,419-420,434,436,441,443-444,449,451,456,458-459,461-462,464,468-469,471-472,474-475,477-478,480-484,486-487,489,492,495-500,502-503,506-508,510,513,515-516,549,559,569,579,601,608,612,626,630-631,641,651-652,659,668,684-687,690-691,694-696,698-699,701-703,719,727,744-747,782-783,792-793,804,812-813,824,835-836,843,852,869-872,875-876,879-881,883-884,886-888,894-895,906-907,931-934
src/qdk/chemistry/data/basis_set.cpp        1438    1250    86%   31,38,70,91-92,221,225,259-260,276-277,326-327,341,361,387,402,433,460,493,506-507,513-514,529-530,545-546,565,568-569,615,618-620,648,651-653,719,761,785,814,845,881,914,936,966,1006,1023,1032,1050,1067,1079,1090,1180-1181,1235,1249,1262,1276,1291,1298,1308,1310,1317,1331-1332,1465,1522-1523,1537-1539,1541-1542,1548-1551,1560-1561,1727,1791-1792,1805-1806,1906,1914,1926,1962-1966,1968-1970,1973-1977,2010,2024-2028,2031-2040,2042-2045,2047-2051,2053-2055,2058-2061,2065-2066,2068,2070-2074,2077-2078,2082-2086,2090-2092,2098-2101,2103-2105,2108,2110,2112,2132-2133,2142-2143,2151-2153,2160-2161,2181-2182,2184,2201-2203,2268-2269,2271-2276,2282,2390
src/qdk/chemistry/data/configuration.cpp     279     171    61%   67,167,170,172-173,176-177,179-180,183-184,186,190,194-195,204,210,236-238,266-268,271-272,274-283,285,287,289-292,294-295,297,299-300,302-304,307-308,310-311,313,315-316,318-325,327,329,331-334,336-337,341-342,344-348,351-352,354-355,358-359,361-368,370-371,373-381,421-422,432,434
src/qdk/chemistry/data/configuration_set.cpp
                                             328     209    63%   33-34,85-87,90-92,234,247,272-277,287-288,331-333,350-354,356,376-377,400-402,421,425,427,429,431-434,436-437,439,441-442,444-447,450-451,453-455,458-463,465-466,468-478,480,482,484-487,489-490,494-495,497-501,503,506-508,510-514,517-524,526-527,529-540
src/qdk/chemistry/data/filename_utils.hpp
                                              44      26    59%   30-33,35-36,51-53,72-75,77-78,93-95
src/qdk/chemistry/data/hamiltonian.cpp       467     323    69%   39,44-45,66,71-72,80,93,95-97,100-102,106-113,130,138,158-160,192-193,211-215,230-234,239,241,247,249,272-285,287,290-291,294-297,299-302,305-308,310-313,317-320,322-325,328-332,334-337,339-342,344-347,350-351,357,371,380-381,399,402-403,435,448,460,473,486,499,506,524,542,549,556,563-565,571,582-583,603-604,620-621,629-630,655-659,688,690-691,754-756
src/qdk/chemistry/data/hamiltonian_containers/canonical_four_center.cpp
                                             493     428    86%   38-39,67-68,98,110,128-129,156,163,169-171,204-205,213,282,315,355,359,367,379,391,397-398,429,438,443-444,449-450,468,476,483-490,493-500,520-522,603-604,613-614,640,662,727-728,742,754,757,762,765
src/qdk/chemistry/data/hamiltonian_containers/cholesky.cpp
                                             243     173    71%   62-67,98,102,110,122,134,140-141,169-170,172,181,186-187,192-193,206-207,210-213,219,235-242,245-252,265,268,272-274,302-303,312-313,339,361,378,388-390,392-394,400-401,407-408,425,428,432-433
src/qdk/chemistry/data/hamiltonian_containers/sparse.cpp
                                             393     344    87%   89,103,153-155,212,232-235,260-263,364-366,398,435-441,443,471-479,481,484,487-488,494-497,506-507,512,598,607,622
src/qdk/chemistry/data/hdf5_error_handling.hpp
                                              10       3    30%   20-21,23,25-26,28-29
src/qdk/chemistry/data/hdf5_serialization.cpp
                                             240     119    49%   13,15-22,24,26-32,34,36-44,46,48-56,65-67,69-71,73-74,77-79,82-85,95,98,106-109,111-113,115-116,119-121,124-127,138,141,143-150,153-160,238-240,249-251,253-255,258-260,277-280,282-286,288-289,308-310,312-316,318-319
src/qdk/chemistry/data/json_serialization.cpp
                                             177      86    48%   29,38,45-47,57,64-68,70-71,83,90-92,94-98,100,102-103,105,114,120-121,128-129,131,133-134,136-139,141,143-146,148-149,152-153,155,163-164,173,178-179,188-189,196,201,210,212,214,216-217,219-222,225-229,231-236,246-249,252-256,260-264
src/qdk/chemistry/data/lattice_graph.cpp     408     191    46%   33-36,47-50,68,70-71,73-76,78,80-81,83-86,135,161,164,167,209,212,215,267,270,273,318,321,324,394-395,397-404,406,408,410-413,415-416,418,420-421,424-428,432-437,439-440,442-444,446-448,450,452-453,455-456,459-461,464-467,470-472,474-482,486-493,495-496,498-505,507,509,511-514,516-517,521-522,524-528,530-533,535-536,538-539,541-542,544-545,548-549,551-560,562,564-569,571-572,574-579,581-582,584-592,594-596,599-601,603-605,607-610,612-613,615,617-628,630,633-638
src/qdk/chemistry/data/orbitals.cpp         1177     915    77%   106-107,128,144-145,151-152,156-157,178,180,237,251,292,307,321,363,373,377,400,403,405-406,409-413,416-417,421-424,426-427,429,431,433-434,437-440,443,447,449,453,455,457-458,461-467,470-471,474-475,477-478,480,482,484-485,488-492,495,498,500,563-567,570-571,573-574,576-577,580-581,584,586,589-590,592-593,595-596,599-601,604,606,609-610,612-613,615-616,619-620,623,625,665,668,691,759,770,776,781,808,818,862-866,904,917,929,942,962,980,989,1065-1068,1083-1084,1109-1113,1121-1122,1157,1181-1182,1191-1192,1198-1199,1205-1206,1208-1209,1212-1213,1215-1216,1229,1231-1232,1236-1237,1243,1285-1286,1314,1320,1364-1368,1396-1397,1399-1403,1406,1409,1411,1414,1416,1419,1421-1423,1425-1427,1430-1432,1434-1436,1438-1441,1460-1462,1465-1467,1470-1472,1534-1535,1564-1566,1581-1583,1617-1618,1630-1631,1789-1793,1806-1807,1810,1813-1814,1817-1819,1821,1860,1897,1912-1914,1963-1964,1999-2000,2006-2007,2013-2014,2016-2017,2020-2021,2023-2024,2031,2047-2048
src/qdk/chemistry/data/pauli_operator.cpp
                                             756     683    90%   60,63,87-88,190,202-203,224,397,407,421-423,517,555-557,559-561,577-579,581-583,606,609,721,806,818,820-821,855,860-862,877,882-884,912,938-942,944,946,951,956,996,1014-1016,1029,1036-1037,1039-1044,1062,1073-1076,1202,1222,1300,1343
src/qdk/chemistry/data/settings.cpp         1106     554    50%   23,27,55-64,66-81,88-93,96-99,101-105,107-111,113,115-118,120-125,127-131,133-143,147-156,169,173,210,222-225,227-229,232-236,238-239,241-243,245-246,248-249,292-293,296,311,342-343,346-348,350-355,357,359-364,367,387-391,394-395,398,400,406,408,410,414,416,420,464-465,467,469,471-472,474-477,481-482,484-486,489-490,494-496,499-501,505,507,510-515,520-524,526-536,538-541,543-547,549-552,556,560-563,567-571,575-578,581-585,587-588,590,592-595,597-599,601-602,604-606,608,610-612,614-618,621-625,627,629-631,633-635,637-641,644-648,650,652-654,657-659,661,664-666,669-670,673-680,682-683,685-686,689-690,692-698,701-707,711,714-715,718-719,722-723,726-727,730-734,736,738,740-741,743-746,748-749,751-752,754-757,759-760,762,764-767,770,772-775,779-784,788-789,791,793-796,800,803-804,817,823,826,831-833,836,844,848,865,869-870,887-890,899,902,974-975,987,989,1137,1139-1142,1145,1147-1148,1154-1155,1158-1163,1165,1169,1171,1176,1180-1182,1188,1192,1195-1196,1201,1203-1205,1209,1254,1261,1279,1330-1332,1362,1368-1371,1393-1394,1429-1430,1432,1461-1463,1482-1487,1513-1515,1517,1519-1520,1523-1525,1527-1529,1535,1556-1563,1566-1569,1625,1653,1668-1670,1674-1684,1686-1691,1693-1695,1697-1703,1705-1707,1709,1711,1713-1717,1719-1723,1725-1727,1729-1730,1732-1739,1741-1750,1752-1754,1756-1758,1774
src/qdk/chemistry/data/stability_result.cpp
                                             317     292    92%   25,32,42,176,213,218,271,281,299,315,344,346,350,356,379,419,421,425,451,458,503-507
src/qdk/chemistry/data/structure.cpp         761     703    92%   86,101,115-116,127,140,159,176-177,204,245-246,295,479,492,512,530,649,665,802,816,964-966,974-975,985,995-996,1018-1019,1027,1055-1057,1063,1076,1122-1123,1126,1132-1135,1138-1147,1151-1153,1156
src/qdk/chemistry/data/wavefunction.cpp     1315    1133    86%   45,65,171,174,182-184,265-266,282,303-306,308-311,314,332-337,340,382,413,450,463,483,488,504-505,526,543,546,569,572,575-584,615-621,623-625,727-736,833-837,932-934,979,993,1006,1008,1013,1015,1037-1038,1097,1099-1100,1114,1116,1119-1120,1141-1144,1146,1181,1183-1184,1209,1226,1352,1451-1454,1482,1489,1495,1502,1518,1524-1526,1532,1543,1573-1574,1589-1590,1597-1598,1618,1623-1624,1630,1641,1677,1787-1788,1798-1799,1826,1852-1853,1883-1884,1956,1958,1961-1962,1970-1972,1990-1992,1994-1995,2001-2004,2007-2017,2019-2020,2022-2025,2028-2031,2033-2035,2037-2038,2040-2041
src/qdk/chemistry/data/wavefunction_containers/cas.cpp
                                             252     199    79%   76-77,79-82,84-85,87-88,90,92-93,95-96,98-99,101,116,161-162,166,168,172,174,178-179,191-193,199,201-204,207-210,227-228,231-232,337-339,359,377-378,387,398,421-422
src/qdk/chemistry/data/wavefunction_containers/cc.cpp
                                             878     525    59%   48,52,57,59,62,66,71-72,74-77,79,87-88,122-127,153-160,169-175,203-204,206-220,222-224,226-228,231,233-234,250,258-259,261,267,277,287,299,319,324,326-328,331-334,337,339-340,343,345-349,351-352,354-355,358-359,381-383,385-387,389-391,393-395,397-399,425,432,463-466,528-529,595-596,599,601,603,606-607,609-610,612,615,617-620,622-624,627-628,630,633,637,639-640,643,687,696-697,699,705-706,708-709,716,728,737-738,747-748,754,790,800,810,820,830,841,940-950,952-956,969-979,981,983-985,1058-1069,1071-1083,1085-1091,1093-1100,1115-1126,1128-1140,1142-1148,1150-1156,1171-1181,1183-1195,1197-1200,1202,1204-1207,1223-1232,1234-1246,1248-1251,1253-1257,1322-1324,1326-1327,1330,1332-1333,1335,1337-1338,1342-1344
src/qdk/chemistry/data/wavefunction_containers/mp2.cpp
                                             608     419    68%   32,36,40-41,45-47,60-62,78,85,110,150-151,210-211,283,288,290-292,295-297,300-303,306-311,313-319,321-323,344,407-408,438-439,447,460-462,464,468-470,472,505,514-515,517,523-524,526-527,534,546,555-556,576,593-594,597-598,601,603-609,611-614,616,618,620,622-628,630-633,635,637,639,641-647,649-652,654,658-667,673-682,688-697,704-706,708-709,713,715-716,718-720,724-727,729,895,901,903,934-935,938-939,943,945,976,993,1027,1051,1053,1058,1062-1072
src/qdk/chemistry/data/wavefunction_containers/sci.cpp
                                             213     176    82%   78-79,81-84,86-87,89-90,92,94-95,97-98,100-101,103,117,151,153,155-156,166-167,170-171,260-262,282,300-301,310,321,344-345
src/qdk/chemistry/data/wavefunction_containers/sd.cpp
                                             399     336    84%   17,42-46,54,56-60,111,113,118,120,136-137,140,143-144,156,158,161-162,200,202,205-206,275,277,280-282,309,311,314,316,369,371,467,497-498,501,511-512,515,562,571,577,591,599-602,646-647,664-665,683-684,694-695
src/qdk/chemistry/utils/logger.cpp            98      93    94%   184-186,205,250
src/qdk/chemistry/utils/orbital_rotation.cpp
                                              93      56    60%   60-62,140-142,145,149-150,152,154-155,176,178,180,182,185-186,188,192-193,196-197,200,202-203,205,208-211,214,218-219,221,223-224
src/qdk/chemistry/utils/valence_space.cpp
                                              43      37    86%   60-63,79,83
------------------------------------------------------------------------------
TOTAL                                      22163   17435    78%
------------------------------------------------------------------------------
Python Coverage Details
src/qdk_chemistry/data/qpe_result.py                                                               103      2    98%
src/qdk_chemistry/data/qubit_hamiltonian.py                                                        164      2    99%
src/qdk_chemistry/data/time_evolution/__init__.py                                                    0      0   100%
src/qdk_chemistry/data/time_evolution/base.py                                                       40     12    70%
src/qdk_chemistry/data/time_evolution/containers/__init__.py                                         0      0   100%
src/qdk_chemistry/data/time_evolution/containers/base.py                                            26      0   100%
src/qdk_chemistry/data/time_evolution/containers/pauli_product_formula.py                           93      4    96%
src/qdk_chemistry/data/time_evolution/controlled_time_evolution.py                                  46      8    83%
src/qdk_chemistry/definitions.py                                                                     8      0   100%
src/qdk_chemistry/plugins/__init__.py                                                                0      0   100%
src/qdk_chemistry/plugins/pyscf/__init__.py                                                         18      0   100%
src/qdk_chemistry/plugins/pyscf/active_space_avas.py                                                77      7    91%
src/qdk_chemistry/plugins/pyscf/conversion.py                                                      264     16    94%
src/qdk_chemistry/plugins/pyscf/coupled_cluster.py                                                 101     27    73%
src/qdk_chemistry/plugins/pyscf/localization.py                                                     72      8    89%
src/qdk_chemistry/plugins/pyscf/mcscf.py                                                           123     15    88%
src/qdk_chemistry/plugins/pyscf/scf_solver.py                                                      102      5    95%
src/qdk_chemistry/plugins/pyscf/stability.py                                                       154      2    99%
src/qdk_chemistry/plugins/qiskit/__init__.py                                                        45      0   100%
src/qdk_chemistry/plugins/qiskit/_interop/__init__.py                                                0      0   100%
src/qdk_chemistry/plugins/qiskit/_interop/circuit.py                                               130      0   100%
src/qdk_chemistry/plugins/qiskit/_interop/noise_model.py                                            15      1    93%
src/qdk_chemistry/plugins/qiskit/_interop/qir.py                                                    83     23    72%
src/qdk_chemistry/plugins/qiskit/_interop/transpiler.py                                            139      6    96%
src/qdk_chemistry/plugins/qiskit/circuit_executor.py                                                38      0   100%
src/qdk_chemistry/plugins/qiskit/conversion.py                                                      31      0   100%
src/qdk_chemistry/plugins/qiskit/energy_estimator.py                                                69      1    99%
src/qdk_chemistry/plugins/qiskit/qubit_mapper.py                                                    35      1    97%
src/qdk_chemistry/plugins/qiskit/regular_isometry.py                                                40      0   100%
src/qdk_chemistry/plugins/qiskit/standard_phase_estimation.py                                       69      4    94%
src/qdk_chemistry/utils/__init__.py                                                                  4      0   100%
src/qdk_chemistry/utils/cubegen.py                                                                  54     54     0%
src/qdk_chemistry/utils/enum.py                                                                     23      3    87%
src/qdk_chemistry/utils/model_hamiltonians.py                                                        2      0   100%
src/qdk_chemistry/utils/pauli_commutation.py                                                        83      4    95%
src/qdk_chemistry/utils/phase.py                                                                    39      1    97%
src/qdk_chemistry/utils/qsharp/__init__.py                                                          17      0   100%
src/qdk_chemistry/utils/telemetry.py                                                               142     87    39%
src/qdk_chemistry/utils/telemetry_events.py                                                         59     48    19%
src/qdk_chemistry/utils/wavefunction.py                                                             57     57     0%
--------------------------------------------------------------------------------------------------------------------
TOTAL                                                                                             5018    680    86%
Coverage HTML written to dir ../coverage-reports/python_coverage_html
Coverage XML written to file ../coverage-reports/python_coverage.xml
=========================== short test summary info ============================
SKIPPED [1] tests/test_sample_workflow.py:219: Skipping slow test. Set QDK_CHEMISTRY_RUN_SLOW_TESTS=1 to enable.
SKIPPED [1] tests/test_sample_workflow.py:236: Skipping slow test. Set QDK_CHEMISTRY_RUN_SLOW_TESTS=1 to enable.
SKIPPED [1] tests/test_sample_workflow_openfermion.py:35: OpenFermion not available
SKIPPED [1] tests/test_sample_workflow_rdkit.py:30: Skipping: RDKit not installed
=========== 1289 passed, 4 skipped, 1 warning in 1389.23s (0:23:09) ============
Pybind11 Coverage Details
------------------------------------------------------------------------------
                           GCC Code Coverage Report
Directory: .
------------------------------------------------------------------------------
File                                       Lines     Exec  Cover   Missing
------------------------------------------------------------------------------
src/pybind11/algorithms/active_space.cpp      37       37   100%
src/pybind11/algorithms/davidson_solver.cpp
                                              35       34    97%   28
src/pybind11/algorithms/dynamical_correlation_calculator.cpp
                                              30       30   100%
src/pybind11/algorithms/factory_bindings.hpp
                                             198      189    95%   218,218,218,218,218,218,218,218,218
src/pybind11/algorithms/hamiltonian.cpp       35       35   100%
src/pybind11/algorithms/localizer.cpp         37       37   100%
src/pybind11/algorithms/mc.cpp                36       36   100%
src/pybind11/algorithms/mcscf.cpp             33       33   100%
src/pybind11/algorithms/pmc.cpp               35       34    97%   178
src/pybind11/algorithms/scf.cpp               34       34   100%
src/pybind11/algorithms/stability.cpp         33       33   100%
src/pybind11/algorithms/syev_solver.cpp       19       18    94%   43
src/pybind11/constants.cpp                    89       89   100%
src/pybind11/data/ansatz.cpp                  69       69   100%
src/pybind11/data/basis_set.cpp              204      204   100%
src/pybind11/data/configuration.cpp           30       29    96%   200
src/pybind11/data/configuration_set.cpp       84       84   100%
src/pybind11/data/data_class.cpp             109       27    24%   19-20,23-24,27,29,32,34-37,39-44,46,48-49,52,54,57-59,64,67,71-72,75,78-79,81-82,90,92,94-96,98,101,104-105,107,110,113-115,117-120,124,126,128-129,131,133,135-137,139,141,143-145,150-151,153,156-157,159,162-163,165,168-169,171,174,176,178,249
src/pybind11/data/element_data.cpp           123      123   100%
src/pybind11/data/hamiltonian.cpp            234      225    96%   62,65,67,408,427,600,620,805,826
src/pybind11/data/lattice_graph.cpp          101       73    72%   20,23,25,27,29-30,33,36-37,39,41-42,45,48-49,51,53-54,423-425,429,448,459,562,564,566,568
src/pybind11/data/orbitals.cpp               138      137    99%   940
src/pybind11/data/path_utils.hpp              19       11    57%   37,39,42-47
src/pybind11/data/pauli_operator.cpp         274      254    92%   146,257,322,398,403,409,415,427,467,473,505,511,517,529,604,636,641,655,659,667
src/pybind11/data/property_binding_helpers.hpp
                                             304      304   100%
src/pybind11/data/serialization.cpp            5        5   100%
src/pybind11/data/settings.cpp               712      478    67%   40-41,57-58,108-109,115-116,121-122,127,129,134,136,162-166,175-177,180-183,188-192,196-198,208-211,215-219,228-231,235-240,244-247,257-260,264-268,271-275,279-289,291-309,311-325,327-329,333,336-338,375-378,391,441,443-444,480,551,1211,1219,1225,1228,1345,1379,1457,1520,1545,1570,1596,1660,1748-1749,1751-1755,1789-1793,1795-1800,1851,1905,1931-1932,1934,1937-1940,1966,2008-2009,2011-2012,2043-2044,2046,2049-2052,2079-2081,2102-2104,2106-2107,2126-2132,2152-2154,2156-2157,2179-2183,2185-2190,2221-2222,2240-2246,2268-2269,2287-2293,2423
src/pybind11/data/stability_result.cpp       112      112   100%
src/pybind11/data/structure.cpp              199      184    92%   69,72,75-78,82-84,87,90-91,969,977,999
src/pybind11/data/wavefunction.cpp           365      347    95%   39,98,100,264-265,268,272,278,473-477,479,1016,1018,1064,1067
src/pybind11/module.cpp                       43       43   100%
src/pybind11/qdk_scf_config.cpp               12       12   100%
src/pybind11/utils/logger.cpp                191      177    92%   27,54,68-69,92,97-99,105-106,262-263,476,480
src/pybind11/utils/model_hamiltonians.cpp
                                              57       53    93%   214-217
src/pybind11/utils/orbital_rotation.cpp        7        7   100%
src/pybind11/utils/valence_space.cpp           5        5   100%
------------------------------------------------------------------------------
TOTAL                                       4048     3602    89%
------------------------------------------------------------------------------

Copilot AI review requested due to automatic review settings March 2, 2026 20:01
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (11)

python/src/qdk_chemistry/utils/pauli_commutation.py:331

  • The second-order bound docstring/math appears inconsistent with the actual implementation: the code sums over i, j, k with j<k (including repeated indices like i=j), but the docstring states a j<k<l triple sum and has mismatched indices/brackets. Please update the formula/notation to match what is actually computed (and fix the malformed \lVert/\rVert expression) so users don’t misinterpret the bound.
    r"""Compute the second-order Trotter commutator bound.

    For a Hamiltonian :math:`H = \sum_j \alpha_j P_j` the second-order
    (Lie-Trotter) product formula has error bounded by

    .. math::

        \lVert U(t) - S_2(t) \rVert \le
            \frac{t^3}{3!} \sum_{j < k < l}
            \lVert \lvert [\alpha_j P_i,\, [\alpha_j P_j,\, \alpha_k P_k] \rVert ] \rVert

    For Pauli strings the spectral norm of the commutator is

    * 0  if :math:`P_j` and :math:`P_k` commute, or
    * :math:`2 |\alpha_j| |\alpha_k|`  if they anticommute.

    This function returns
    :math:`\sum_{j < k < l}
            \lVert \lvert [\alpha_j P_i,\, [\alpha_j P_j,\, \alpha_k P_k] \rVert ] \rVert`,
    so the user can multiply by :math:`t^{3} / (3! * N)` to get the per-step
    error.

python/src/qdk_chemistry/algorithms/time_evolution/builder/trotter_error.py:88

  • The naive-bound docstring still states the first-order formula N = ceil((sum|α|)^2 t^2 / ε), but the implementation now uses an order-dependent exponent (and supports order=2). Update the docstring (and module-level description if needed) to document the order-2 formula used here, otherwise the docs disagree with runtime behavior.
    r"""Compute the number of Trotter steps using the naive bound.

    The naive (triangle-inequality) bound is

    .. math::

        N = \left\lceil \frac{(\sum_j |\alpha_j|)^2 \, t^2}{\epsilon} \right\rceil

    where :math:`\sum_j |\alpha_j|` is the 1-norm of the Hamiltonian
    coefficients.

    Args:
        hamiltonian: The qubit Hamiltonian to simulate.
        time: The total evolution time *t*.
        target_accuracy: The target accuracy :math:`\epsilon > 0`.
        order: The order of the Trotter-Suzuki product formula.
        weight_threshold: Absolute threshold below which coefficients are discarded.

    Returns:
        The minimum number of Trotter steps (at least 1).

    Raises:
        ValueError: If ``target_accuracy`` is not positive.
        NotImplementedError: If *order* is not yet supported.

    """
    if target_accuracy <= 0:
        raise ValueError(f"target_accuracy must be positive, got {target_accuracy}.")
    if order != 1 and order != 2:
        raise NotImplementedError(
            f"Trotter step estimation for order {order} is not yet implemented. "
            "Only orders 1 or 2 are currently supported."
        )
    real_terms = hamiltonian.get_real_coefficients(tolerance=weight_threshold)
    one_norm = sum(abs(coeff) for _, coeff in real_terms)
    return max(1, math.ceil((one_norm ** (1 + 1 / order) * time ** (1 + 1 / order)) / (target_accuracy ** (1 / order))))

python/src/qdk_chemistry/algorithms/time_evolution/builder/trotter.py:153

  • This method (and its docstring) still describes first-order Trotter only, but it is now used for both order=1 and order=2. Please update the docstring to describe both decompositions (or make the wording order-agnostic) so that public behavior matches documentation.
    def _first_or_second_order_trotter(self, qubit_hamiltonian: QubitHamiltonian, time: float) -> TimeEvolutionUnitary:
        r"""Construct the time evolution unitary using first-order Trotter decomposition.

        The First Order Trotter method approximates the time evolution operator :math:`e^{-iHt}`
        by decomposing the Hamiltonian H into a sum of terms and using the product formula:
        :math:`e^{-iHt} \approx \left[\prod_i e^{-iH_i t/n}\right]^n`, where n is the number of divisions.

python/src/qdk_chemistry/algorithms/time_evolution/builder/trotter.py:223

  • _decompose_trotter_step’s docstring lists an order argument, but the function signature doesn’t accept it (it reads order from settings instead). Please remove that parameter from the docstring or add it to the signature to avoid misleading API docs.
    def _decompose_trotter_step(
        self, qubit_hamiltonian: QubitHamiltonian, time: float, *, atol: float = 1e-12
    ) -> list[ExponentiatedPauliTerm]:
        """Decompose a single Trotter step into exponentiated Pauli terms.

        Args:
            qubit_hamiltonian: The qubit Hamiltonian to be decomposed.
            time: The evolution time for the single step.
            order: The order of the Trotter decomposition.
            atol: Absolute tolerance for filtering small coefficients.

python/tests/test_trotter_error.py:138

  • In the second-order version of this test, n_naive is computed with the default order=1, while n_comm is computed with order=2. That makes the assertion n_comm <= n_naive compare different orders and doesn’t actually test “commutator bound is never looser than naive” for second-order. Pass order=2 to trotter_steps_naive here.
    def test_tighter_than_naive_second_order(self):
        """Test that commutator bound is never looser than naive."""
        h = QubitHamiltonian(pauli_strings=["X", "Z"], coefficients=[1.0, 1.0])
        eps = 0.01
        time = 1.0
        n_naive = trotter_steps_naive(h, time, eps)
        n_comm = trotter_steps_commutator(h, time, eps, order=2)
        assert n_comm <= n_naive

python/src/qdk_chemistry/utils/pauli_commutation.py:43

  • commutator_bound_second_order() is a top-level utility that is imported and used elsewhere, but it is not included in this module’s __all__ (while commutator_bound_first_order is). Either add it to __all__ for consistency/public API clarity, or rename it with a leading underscore if it’s intended to stay private.
__all__: list[str] = [
    "commutator_bound_first_order",
    "do_pauli_labels_commute",
    "do_pauli_labels_qw_commute",
    "do_pauli_maps_commute",
    "do_pauli_maps_qw_commute",
    "does_nested_commutator_vanish",
    "get_commutation_checker",
]

python/src/qdk_chemistry/algorithms/time_evolution/builder/trotter_error.py:111

  • The commutator-bound docstring’s second-order section is internally inconsistent (e.g., N_2 is not a step-count expression/ceil, indices don’t match, and the norm expression appears malformed). Since this function now supports order=2 with a specific closed-form step-count formula, please rewrite the math block to match the implemented calculation for orders 1 and 2.
    r"""Compute the number of Trotter steps using the commutator bound.

    The tighter commutator-based bound from Childs *et al.* (2021) is

    .. math::

        N_1 = \left\lceil \frac{t^2}{2\epsilon}
            \sum_{j<k} \lVert [\alpha_j P_j,\, \alpha_k P_k] \rVert
        \right\rceil

        N_2 = \frac{t^3}{3!} \sum_{j < k < l}
            \lVert \lvert [\alpha_j P_l,\, [\alpha_j P_j,\, \alpha_k P_k] \rVert ] \rVert

    For Pauli strings the commutator norm is :math:`2|\alpha_j||\alpha_k|`

python/tests/test_trotter_error.py:123

  • The comment math for the second-order commutator example is incorrect: sqrt(8) / sqrt(3! * 0.1) is about 3.65 (not 10), so ceil(...) = 4 but the intermediate value in the comment should be fixed to avoid confusion when maintaining these tests.
        # X and Z anticommute: commutator bound = 2 * 2**2 = 8
        # N = ceil(sqrt(8) * 1**(3/2) / (sqrt(3! * 0.1))) = ceil(10) = 4
        h = QubitHamiltonian(pauli_strings=["X", "Z"], coefficients=[1.0, 1.0])
        assert trotter_steps_commutator(h, 1.0, 0.1, order=2) == 4

python/tests/test_trotter_error.py:151

  • This test’s docstring says the step count “scales with t^3”, but the asserted scaling is t^(3/2) (since N ~ t^(1 + 1/order) for order=2). Please update the docstring/comment to match the actual scaling being tested.
    def test_time_scaling_second_order(self):
        """Test that step count scales with t^3."""
        h = QubitHamiltonian(pauli_strings=["X", "Z"], coefficients=[1.0, 1.0])
        n1 = trotter_steps_commutator(h, 1.0, 0.1, order=2)
        n2 = trotter_steps_commutator(h, 2.0, 0.1, order=2)
        # n2 should be approximately 2**1.5 * n1 (t^1.5 scaling)
        assert n2 >= math.ceil(2**1.5) * n1 - 1  # Allow for ceiling effects

python/tests/test_time_evolution_trotter.py:284

  • The comment says “error should scale as O(t^2) for second-order Trotter”, but the assertion uses atol=t**3, which corresponds to third-order error scaling for a second-order (Strang) formula. Please correct the comment so it matches the actual expected scaling being enforced.
        # Compare: the error should scale as O(t^2) for second-order Trotter
        assert np.allclose(u_trot, u_exact, atol=t**3)

python/tests/test_time_evolution_trotter.py:404

  • The inline derivation comments for the second-order commutator/naive step counts are inconsistent with the actual formulas and expected assertions (e.g., commutator bound for X+Z under the current implementation is 8, and the resulting N is 12; the naive bound comment also uses the wrong exponent/denominator). Please fix these comments to reflect the same calculation the code is testing, otherwise future updates will be error-prone.
    def test_target_accuracy_commutator_bound_second_order(self):
        """Test that target_accuracy with commutator bound computes correct step count."""
        # H = X + Z, X and Z anticommute -> commutator bound = 4
        # N = ceil(sqrt(4) * t^(3/2) / (sqrt(3! * eps))) = 17
        hamiltonian = QubitHamiltonian(pauli_strings=["X", "Z"], coefficients=[1.0, 1.0])
        builder = Trotter(target_accuracy=0.01, order=2)
        unitary = builder.run(hamiltonian, time=1.0)
        container = unitary.get_container()
        assert container.step_reps == 12

    def test_target_accuracy_naive_bound_second_order(self):
        """Test that target_accuracy with naive bound computes correct step count."""
        hamiltonian = QubitHamiltonian(pauli_strings=["X", "Z"], coefficients=[1.0, 1.0])
        builder = Trotter(target_accuracy=0.01, error_bound="naive", order=2)
        unitary = builder.run(hamiltonian, time=1.0)
        container = unitary.get_container()
        # one_norm = 2, N = ceil(2^1/2 / 0.01) = 29
        assert container.step_reps == 29

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copilot AI review requested due to automatic review settings March 2, 2026 23:29
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (11)

python/src/qdk_chemistry/utils/pauli_commutation.py:331

  • The second-order commutator-bound docstring has several math/notation issues (e.g., mixed indices P_i vs P_j, mismatched brackets, and t^3/(3!*N) which suggests 1/N scaling). Since the step estimator uses 1/N^2 scaling for order=2, update this docstring so the bound expression and how to apply it (including the N^2 dependence) are correct and unambiguous.
    r"""Compute the second-order Trotter commutator bound.

    For a Hamiltonian :math:`H = \sum_j \alpha_j P_j` the second-order
    (Lie-Trotter) product formula has error bounded by

    .. math::

        \lVert U(t) - S_2(t) \rVert \le
            \frac{t^3}{3!} \sum_{j < k < l}
            \lVert \lvert [\alpha_j P_i,\, [\alpha_j P_j,\, \alpha_k P_k] \rVert ] \rVert

    For Pauli strings the spectral norm of the commutator is

    * 0  if :math:`P_j` and :math:`P_k` commute, or
    * :math:`2 |\alpha_j| |\alpha_k|`  if they anticommute.

    This function returns
    :math:`\sum_{j < k < l}
            \lVert \lvert [\alpha_j P_i,\, [\alpha_j P_j,\, \alpha_k P_k] \rVert ] \rVert`,
    so the user can multiply by :math:`t^{3} / (3! * N)` to get the per-step
    error.

python/src/qdk_chemistry/algorithms/time_evolution/builder/trotter.py:153

  • This method’s docstring still describes first-order Trotter decomposition only, but it is now used for both order 1 and order 2. Update the docstring to reflect second-order (Strang) splitting behavior, or split into two clearly documented methods.
    def _first_or_second_order_trotter(self, qubit_hamiltonian: QubitHamiltonian, time: float) -> TimeEvolutionUnitary:
        r"""Construct the time evolution unitary using first-order Trotter decomposition.

        The First Order Trotter method approximates the time evolution operator :math:`e^{-iHt}`
        by decomposing the Hamiltonian H into a sum of terms and using the product formula:
        :math:`e^{-iHt} \approx \left[\prod_i e^{-iH_i t/n}\right]^n`, where n is the number of divisions.

python/src/qdk_chemistry/algorithms/time_evolution/builder/trotter.py:223

  • The _decompose_trotter_step docstring lists an order argument, but the function signature does not accept order (it is read from settings instead). Please remove/adjust this docstring entry to match the actual API.
    def _decompose_trotter_step(
        self, qubit_hamiltonian: QubitHamiltonian, time: float, *, atol: float = 1e-12
    ) -> list[ExponentiatedPauliTerm]:
        """Decompose a single Trotter step into exponentiated Pauli terms.

        Args:
            qubit_hamiltonian: The qubit Hamiltonian to be decomposed.
            time: The evolution time for the single step.
            order: The order of the Trotter decomposition.
            atol: Absolute tolerance for filtering small coefficients.

python/src/qdk_chemistry/algorithms/time_evolution/builder/trotter.py:145

  • _run_impl duplicates the same call for order == 1 and order == 2. This can be simplified to a single membership check (e.g., if order in {1, 2}) to avoid drift if behavior changes in the future.
        if self._settings.get("order") == 1:
            return self._first_or_second_order_trotter(qubit_hamiltonian, time)
        if self._settings.get("order") == 2:
            return self._first_or_second_order_trotter(qubit_hamiltonian, time)
        raise NotImplementedError("Only orders 1 or 2 are currently supported.")

python/tests/test_trotter_error.py:144

  • The test says “step count scales with t^3”, but the assertion/comment below uses t^1.5 scaling (which is what you’d expect when N ~ t^(3/2) from an O(t^3/N^2) error). Update the docstring/comment so they’re consistent with the actual scaling being tested.
    def test_time_scaling_second_order(self):
        """Test that step count scales with t^3."""
        h = QubitHamiltonian(pauli_strings=["X", "Z"], coefficients=[1.0, 1.0])
        n1 = trotter_steps_commutator(h, 1.0, 0.1, order=2)
        n2 = trotter_steps_commutator(h, 2.0, 0.1, order=2)
        # n2 should be approximately 2**1.5 * n1 (t^1.5 scaling)
        assert n2 >= math.ceil(2**1.5) * n1 - 1  # Allow for ceiling effects

python/src/qdk_chemistry/utils/pauli_commutation.py:43

  • commutator_bound_second_order is now part of the module’s public surface (imported by other code/tests) but it isn’t exported in __all__, unlike commutator_bound_first_order. Consider adding it to __all__ for consistency.
__all__: list[str] = [
    "commutator_bound_first_order",
    "do_pauli_labels_commute",
    "do_pauli_labels_qw_commute",
    "do_pauli_maps_commute",
    "do_pauli_maps_qw_commute",
    "does_nested_commutator_vanish",
    "get_commutation_checker",
]

python/src/qdk_chemistry/utils/pauli_commutation.py:352

  • This nested-loop structure iterates k from i+1 independently of j, so it includes cases like k == j and counts both (j,k) and (k,j). If the intent is a redundancy-free sum over distinct triples (as the docstring says), the loop bounds should be tightened (e.g., i < j < k). If the redundancy is intentional for the bound, the docstring should be updated to describe the exact summation being computed.
    for i in range(n):
        for j in range(i + 1, n):
            for k in range(i + 1, n):
                if not does_nested_commutator_vanish(pauli_labels[k], pauli_labels[j], pauli_labels[i]):
                    total_term1 += 2.0**2 * abs(coefficients[i]) * abs(coefficients[j]) * abs(coefficients[k])

python/tests/test_time_evolution_trotter.py:403

  • The explanatory comments compute a commutator bound / expected N that doesn’t match the asserted step_reps (comment says bound=4 and N=17, assertion expects 9). Please fix the comment so it reflects the actual bound and step-count formula being used.
    def test_target_accuracy_commutator_bound_second_order(self):
        """Test that target_accuracy with commutator bound computes correct step count."""
        # H = X + Z, X and Z anticommute -> commutator bound = 4
        # N = ceil(sqrt(4) * t^(3/2) / (sqrt(3! * eps))) = 17
        hamiltonian = QubitHamiltonian(pauli_strings=["X", "Z"], coefficients=[1.0, 1.0])
        builder = Trotter(target_accuracy=0.01, order=2)
        unitary = builder.run(hamiltonian, time=1.0)
        container = unitary.get_container()
        assert container.step_reps == 9

python/tests/test_time_evolution_trotter.py:412

  • This comment has a math typo: for second-order naive scaling you expect N ~ one_norm^(3/2) * t^(3/2) / sqrt(eps), but the comment currently says ceil(2^1/2 / 0.01). Update the comment to the correct exponent/scaling (the asserted value 29 looks consistent with 2^(3/2)/0.1).
        unitary = builder.run(hamiltonian, time=1.0)
        container = unitary.get_container()
        # one_norm = 2, N = ceil(2^1/2 / 0.01) = 29
        assert container.step_reps == 29

python/src/qdk_chemistry/algorithms/time_evolution/builder/trotter_error.py:87

  • trotter_steps_naive now supports order=2 (see order not in {1,2} and the generalized power-law), but the docstring above still documents only the first-order t^2/ε scaling. Please update the docstring’s math to cover both orders (or explicitly state it’s the order=1 formula).
    if order not in {1, 2}:
        raise NotImplementedError(
            f"Trotter step estimation for order {order} is not yet implemented. "
            "Only orders 1 or 2 are currently supported."
        )
    real_terms = hamiltonian.get_real_coefficients(tolerance=weight_threshold)
    one_norm = sum(abs(coeff) for _, coeff in real_terms)
    return max(1, math.ceil((one_norm ** (1 + 1 / order) * time ** (1 + 1 / order)) / (target_accuracy ** (1 / order))))

python/src/qdk_chemistry/algorithms/time_evolution/builder/trotter_error.py:110

  • The docstring currently mixes a ceil-expression for N_1 with a raw error-term expression for N_2, and the nested-commutator expression has inconsistent indices/brackets. Since this function returns an N (step count), the math section should present the solved N formula for order=2 (including the expected 1/N^2 scaling for second-order) to avoid misleading readers.
    .. math::

        N_1 = \left\lceil \frac{t^2}{2\epsilon}
            \sum_{j<k} \lVert [\alpha_j P_j,\, \alpha_k P_k] \rVert
        \right\rceil

        N_2 = \frac{t^3}{3!} \sum_{j < k < l}
            \lVert \lvert [\alpha_j P_l,\, [\alpha_j P_j,\, \alpha_k P_k] \rVert ] \rVert


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@wavefunction91 wavefunction91 changed the title implemented 2nd order Trotter and corresponding error bounds 2nd order Trotter and Corresponding Error Bounds Mar 5, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.

Comments suppressed due to low confidence (2)

python/src/qdk_chemistry/algorithms/time_evolution/builder/trotter.py:152

  • The method now handles both order=1 and order=2, but the docstring still describes only first-order Trotter and gives the first-order product formula. Please update this docstring to describe that the implementation supports orders 1 and 2 (and document the Strang/symmetric construction for order=2), or split into separate methods with accurate docstrings.
    def _trotter(self, qubit_hamiltonian: QubitHamiltonian, time: float) -> TimeEvolutionUnitary:
        r"""Construct the time evolution unitary using first-order Trotter decomposition.

        The First Order Trotter method approximates the time evolution operator :math:`e^{-iHt}`
        by decomposing the Hamiltonian H into a sum of terms and using the product formula:
        :math:`e^{-iHt} \approx \left[\prod_i e^{-iH_i t/n}\right]^n`, where n is the number of divisions.

python/src/qdk_chemistry/algorithms/time_evolution/builder/trotter_error.py:1

  • The newly added N_2 math block appears malformed (mismatched \\lVert, \\lvert, brackets) and the indices/term structure look inconsistent. Since this docstring is user-facing, please rewrite the second-order bound section with a correct and readable formula, and ideally align it with how commutator_bound_second_order() is defined (including the t^3/(12 N^2) scaling used in the implementation).
r"""Trotter error bound estimation for accuracy-aware parameterization.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@v-agamshayit v-agamshayit marked this pull request as draft March 5, 2026 20:46
v-agamshayit and others added 2 commits March 5, 2026 20:58
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@wavefunction91 wavefunction91 added this to the Release 1.1 milestone Mar 10, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (1)

python/src/qdk_chemistry/algorithms/time_evolution/builder/trotter.py:153

  • The _trotter method docstring still describes only the first-order product formula, but the method now also implements second-order decomposition depending on the order setting (via _decompose_trotter_step). Please update the docstring to reflect that this method supports orders 1 and 2 (and describe the second-order/Strang form) so callers reading docs aren't misled.
    def _trotter(self, qubit_hamiltonian: QubitHamiltonian, time: float) -> TimeEvolutionUnitary:
        r"""Construct the time evolution unitary using first-order Trotter decomposition.

        The First Order Trotter method approximates the time evolution operator :math:`e^{-iHt}`
        by decomposing the Hamiltonian H into a sum of terms and using the product formula:
        :math:`e^{-iHt} \approx \left[\prod_i e^{-iH_i t/n}\right]^n`, where n is the number of divisions.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

v-agamshayit and others added 2 commits March 11, 2026 11:24
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@v-agamshayit v-agamshayit marked this pull request as ready for review March 11, 2026 18:55
Copilot AI review requested due to automatic review settings March 11, 2026 18:55
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Comments suppressed due to low confidence (1)

python/src/qdk_chemistry/algorithms/time_evolution/builder/trotter.py:152

  • _trotter is now used for both order=1 and order=2 (see _run_impl), but its docstring still describes only first-order Trotter and the first-order product formula. Update the docstring (and any referenced formula text) to reflect that this method constructs the configured order (1 or 2), or split into separate order-specific helpers with matching docstrings.
        r"""Construct the time evolution unitary using first-order Trotter decomposition.

        The First Order Trotter method approximates the time evolution operator :math:`e^{-iHt}`
        by decomposing the Hamiltonian H into a sum of terms and using the product formula:
        :math:`e^{-iHt} \approx \left[\prod_i e^{-iH_i t/n}\right]^n`, where n is the number of divisions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Copilot AI review requested due to automatic review settings March 13, 2026 22:48
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.

Comments suppressed due to low confidence (1)

python/src/qdk_chemistry/algorithms/time_evolution/builder/trotter.py:150

  • Trotter now accepts order 1 or 2, but _trotter’s docstring still describes first-order decomposition and the S_1 formula. Update the docstring (and any referenced formula) to describe order-dependent behavior or rename the method/commentary accordingly so users aren’t misled.
    def _trotter(self, qubit_hamiltonian: QubitHamiltonian, time: float) -> TimeEvolutionUnitary:
        r"""Construct the time evolution unitary using first-order Trotter decomposition.

        The First Order Trotter method approximates the time evolution operator :math:`e^{-iHt}`
        by decomposing the Hamiltonian H into a sum of terms and using the product formula:
        :math:`e^{-iHt} \approx \left[\prod_i e^{-iH_i t/n}\right]^n`, where n is the number of divisions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 13, 2026 22:58
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.

Comments suppressed due to low confidence (1)

python/src/qdk_chemistry/algorithms/time_evolution/builder/trotter.py:149

  • _trotter is now used for both order 1 and order 2 (via _decompose_trotter_step reading settings), but its docstring still says “first-order Trotter decomposition” and shows only the first-order product formula. Update this docstring to reflect order-dependent behavior (first-order vs second-order/Strang splitting).
    def _trotter(self, qubit_hamiltonian: QubitHamiltonian, time: float) -> TimeEvolutionUnitary:
        r"""Construct the time evolution unitary using first-order Trotter decomposition.

        The First Order Trotter method approximates the time evolution operator :math:`e^{-iHt}`
        by decomposing the Hamiltonian H into a sum of terms and using the product formula:

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants