From 8142676c3bd4d99a18c54fa1be4eb29d3c5ed5f2 Mon Sep 17 00:00:00 2001 From: to24toro Date: Fri, 26 Sep 2025 13:46:01 +0900 Subject: [PATCH 01/25] Add CI --- .github/ISSUE_TEMPLATE/BUG_REPORT.yaml | 50 ---------- .github/ISSUE_TEMPLATE/FEATURE_REQUEST.yaml | 14 --- .github/PULL_REQUEST_TEMPLATE.md | 19 ---- .github/dependabot.yml | 13 +++ .github/workflows/coverage.yml | 65 ++++++++++++ .github/workflows/lint.yml | 50 ++++++++++ .../workflows/test_development_versions.yml | 77 +++++++++++++++ .github/workflows/test_latest_versions.yml | 98 +++++++++++++++++++ .../test_without_exceptions_rtti.yml | 61 ++++++++++++ README.md | 2 +- 10 files changed, 365 insertions(+), 84 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/BUG_REPORT.yaml delete mode 100644 .github/ISSUE_TEMPLATE/FEATURE_REQUEST.yaml delete mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/coverage.yml create mode 100644 .github/workflows/lint.yml create mode 100644 .github/workflows/test_development_versions.yml create mode 100644 .github/workflows/test_latest_versions.yml create mode 100644 .github/workflows/test_without_exceptions_rtti.yml diff --git a/.github/ISSUE_TEMPLATE/BUG_REPORT.yaml b/.github/ISSUE_TEMPLATE/BUG_REPORT.yaml deleted file mode 100644 index 1c12d53..0000000 --- a/.github/ISSUE_TEMPLATE/BUG_REPORT.yaml +++ /dev/null @@ -1,50 +0,0 @@ -name: 🐛 Bug report -description: Create a report to help us improve 🤔. -labels: ["bug"] - -body: - - type: markdown - attributes: - value: Thank you for reporting! Please also use the search to see if there are any other relevant issues or pull requests. - - - type: textarea - attributes: - label: Environment - description: For the version of Qiskit, please give the actual version number (_e.g._ 0.45.2) if you are using a release version, or the first 7-8 characters of the commit hash if you have installed from `git`. If anything else is relevant, you can add it to the list. - # The trailing spaces on the following lines are to make filling the form - # in easier. The type is 'textarea' rather than three separate 'input's - # to make the resulting issue body less noisy with headings. - value: | - - **Direct Access Client version**: - - **Python version**: - - **Operating system**: - validations: - required: true - - - type: textarea - attributes: - label: What is happening? - description: A short description of what is going wrong, in words. - validations: - required: true - - - type: textarea - attributes: - label: How can we reproduce the issue? - description: Give some steps that show the bug. A [minimal working example](https://stackoverflow.com/help/minimal-reproducible-example) of code with output is best. If you are copying in code, please remember to enclose it in triple backticks (` ``` [multiline code goes here] ``` `) so that it [displays correctly](https://docs.github.com/en/github/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax). - validations: - required: true - - - type: textarea - attributes: - label: What should happen? - description: A short description, including about the expected output of any code in the previous section. - validations: - required: true - - - type: textarea - attributes: - label: Any suggestions? - description: Not required, but if you have suggestions for how a contributor should fix this, or any problems we should be aware of, let us know. - validations: - required: false diff --git a/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yaml b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yaml deleted file mode 100644 index 4b66a76..0000000 --- a/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yaml +++ /dev/null @@ -1,14 +0,0 @@ -name: 🚀 Feature request -description: Suggest an idea for this project 💡! -labels: ["type: feature request"] - -body: - - type: markdown - attributes: - value: Please make sure to browse the opened and closed issues to make sure that this idea has not previously been discussed. - - - type: textarea - attributes: - label: What should we add? - validations: - required: true diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 3beea1e..0000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,19 +0,0 @@ - - -### Summary - - - -### Details and comments - - diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..7141543 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,13 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + labels: ["dependencies"] + schedule: + interval: "weekly" + - package-ecosystem: "pip" + directory: "/" + labels: ["dependencies"] + versioning-strategy: increase + schedule: + interval: "monthly" diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 0000000..caf81ce --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,65 @@ +name: Coverage + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + coverage: + name: C++ coverage (${{ matrix.os }}) + runs-on: ${{ matrix.os }} + timeout-minutes: 30 + strategy: + matrix: + os: [ubuntu-latest] + python-version: ["3.13"] + steps: + - uses: actions/checkout@v5 + with: + submodules: true + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v6 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies (Linux) + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y g++ clang cmake ninja-build + - name: Install tox + run: | + python -m pip install --upgrade pip + pip install gcovr + - name: Configure CMake + run: cmake -S . -B build -G Ninja -DCMAKE_CXX_FLAGS="-DUSE_RANDOM_SHOTS=1" + + - name: Build + run: ninja -C build + + - name: Run tests + run: | + cd build + ./capi-demo \ + --fcidump ../data/fcidump_Fe4S4_MO.txt \ + --tolerance 1.0e-3 \ + --max_time 600 \ + --recovery 1 \ + --number_of_samples 300 \ + --num_shots 1000 + - name: Convert to json for coveralls + if: always() + run: >- + gcovr --coveralls coveralls.json --root . + --exclude build + --exclude deps + --exclude benchmark + - name: Upload report to Coveralls + if: always() + uses: coverallsapp/github-action@v2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + file: coveralls.json diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..9cb2ae5 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,50 @@ +name: Lint + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + lint: + name: lint check + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v5 + with: + submodules: true + fetch-depth: 0 + + - name: Enable LLVM ppa + shell: bash + run: | + wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | sudo tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc + cat </dev/null | gpg --dearmor - | sudo tee /usr/share/keyrings/kitware-archive-keyring.gpg >/dev/null + echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ noble main' | sudo tee /etc/apt/sources.list.d/kitware.list >/dev/null + - name: Install dependencies (Linux) + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y g++ clang cmake ninja-build + - name: Configure CMake + run: >- + cmake -S . -B build + -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON + ${{ matrix.compiler != 'MSVC' && '-G Ninja' || '' }} + ${{ matrix.compiler && format('-DCMAKE_CXX_COMPILER={0}', matrix.compiler) }} + ${{ matrix.cxx_standard && format('-DCMAKE_CXX_STANDARD={0}', matrix.cxx_standard) }} + -DCMAKE_CXX_FLAGS="-DUSE_RANDOM_SHOTS=1" + - name: CMake Build + run: >- + cmake --build build -j4 + ${{ matrix.compiler == 'MSVC' && '--config Release' || '' }} + - name: Copy build/Release/*.exe to build/ (MSVC) + if: matrix.compiler == 'MSVC' + run: | + cp build/Release/*.exe build/ + - name: Run tests + run: | + cd build + ./capi-demo \ + --fcidump ../data/fcidump_Fe4S4_MO.txt \ + --tolerance 1.0e-3 \ + --max_time 600 \ + --recovery 1 \ + --number_of_samples 300 \ + --num_shots 1000 diff --git a/.github/workflows/test_latest_versions.yml b/.github/workflows/test_latest_versions.yml new file mode 100644 index 0000000..702e067 --- /dev/null +++ b/.github/workflows/test_latest_versions.yml @@ -0,0 +1,98 @@ +name: Tests + +on: + push: + branches: + - main + pull_request: + branches: + - main + schedule: + - cron: '0 1 * * *' + +jobs: + tests: + name: latest version tests (C++${{ matrix.cxx_standard }}, ${{ matrix.os }}, ${{ matrix.compiler }}) + runs-on: ${{ matrix.os }} + timeout-minutes: 30 + strategy: + fail-fast: false + matrix: + include: + # Linux x86_64 + - os: ubuntu-22.04 + compiler: g++ + cxx_standard: 17 + - os: ubuntu-22.04 + compiler: clang++ + - os: ubuntu-latest + compiler: g++ + - os: ubuntu-latest + compiler: g++ + cxx_standard: 20 + - os: ubuntu-latest + compiler: g++ + cxx_standard: 23 + - os: ubuntu-latest + compiler: clang++ + - os: ubuntu-latest + compiler: clang++ + cxx_standard: 20 + - os: ubuntu-latest + compiler: clang++ + cxx_standard: 23 + # Linux ARM + - os: ubuntu-22.04-arm + compiler: g++ + - os: ubuntu-22.04-arm + compiler: clang++ + # macOS x86_64 + - os: macos-13 + compiler: clang++ + # macOS ARM + - os: macos-latest + compiler: clang++ + # Windows + - os: windows-latest + compiler: MSVC + - os: windows-latest + compiler: MSVC + cxx_standard: 20 + - os: windows-latest + compiler: MSVC + cxx_standard: 23 + steps: + - uses: actions/checkout@v5 + with: + submodules: true + - name: Install dependencies (Linux) + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y g++ clang cmake ninja-build + - name: Configure CMake + run: >- + cmake -S . -B build + -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON + ${{ matrix.compiler != 'MSVC' && '-G Ninja' || '' }} + ${{ matrix.compiler && format('-DCMAKE_CXX_COMPILER={0}', matrix.compiler) }} + ${{ matrix.cxx_standard && format('-DCMAKE_CXX_STANDARD={0}', matrix.cxx_standard) }} + -DCMAKE_CXX_FLAGS="-DUSE_RANDOM_SHOTS=1" + - name: CMake Build + run: >- + cmake --build build -j4 + ${{ matrix.compiler == 'MSVC' && '--config Release' || '' }} + - name: Copy build/Release/*.exe to build/ (MSVC) + if: matrix.compiler == 'MSVC' + run: | + cp build/Release/*.exe build/ + - name: Run tests + run: | + cd build + ./capi-demo \ + --fcidump ../data/fcidump_Fe4S4_MO.txt \ + --tolerance 1.0e-3 \ + --max_time 600 \ + --recovery 1 \ + --number_of_samples 300 \ + --num_shots 1000 diff --git a/.github/workflows/test_without_exceptions_rtti.yml b/.github/workflows/test_without_exceptions_rtti.yml new file mode 100644 index 0000000..5a699d6 --- /dev/null +++ b/.github/workflows/test_without_exceptions_rtti.yml @@ -0,0 +1,61 @@ +name: Tests + +on: + push: + branches: + - main + pull_request: + branches: + - main + schedule: + - cron: '0 1 * * *' + +jobs: + tests: + name: without exceptions or RTTI (C++${{ matrix.cxx_standard }}, ${{ matrix.os }}, ${{ matrix.compiler }}) + runs-on: ${{ matrix.os }} + timeout-minutes: 30 + strategy: + fail-fast: false + matrix: + include: + # Linux x86_64 + - os: ubuntu-latest + compiler: g++ + steps: + - uses: actions/checkout@v5 + with: + submodules: true + - name: Install dependencies (Linux) + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y g++ clang cmake ninja-build + - name: Configure CMake + run: >- + cmake -S . -B build + -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON + -DCMAKE_CXX_FLAGS="-fno-rtti -fno-exceptions -DQKA_SQD_DISABLE_EXCEPTIONS=1 -DDOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS" + ${{ matrix.compiler != 'MSVC' && '-G Ninja' || '' }} + ${{ matrix.compiler && format('-DCMAKE_CXX_COMPILER={0}', matrix.compiler) }} + ${{ matrix.cxx_standard && format('-DCMAKE_CXX_STANDARD={0}', matrix.cxx_standard) }} + -DCMAKE_CXX_FLAGS="-DUSE_RANDOM_SHOTS=1" + - name: CMake Build + run: >- + cmake --build build -j4 --target sqd_tests + ${{ matrix.compiler == 'MSVC' && '--config Release' || '' }} + - name: Copy build/Release/*.exe to build/ (MSVC) + if: matrix.compiler == 'MSVC' + run: | + cp build/Release/*.exe build/ + - name: Run tests + run: | + cd build + ./capi-demo \ + --fcidump ../data/fcidump_Fe4S4_MO.txt \ + --tolerance 1.0e-3 \ + --max_time 600 \ + --recovery 1 \ + --number_of_samples 300 \ + --num_shots 1000 + diff --git a/README.md b/README.md index a9f6c59..d66c2ab 100644 --- a/README.md +++ b/README.md @@ -170,7 +170,7 @@ The following command-line options are available when running capi-demo. These c |------------------------------|--------------------------------------------------------------------|---------------| | --fcidump | Path to FCIDUMP file containing molecular integrals. | "" | | --iteration | Maximum number of Davidson iterations. | 1 | -| --block | Maximum size of Litz vector space. | 10 | +| --block | Maximum size of Ritz vector space. | 10 | | --tolerance | Convergence tolerance for diagonalization. | 1.0e-12 | | --max_time | Maximum allowed time (in seconds) for diagonalization. | 600.0 | | --adet_comm_size | Number of nodes used to split the alpha-determinants. | 1 | From 3218f6b7024646e56ed999ee491aa0b6798d82f2 Mon Sep 17 00:00:00 2001 From: to24toro Date: Fri, 26 Sep 2025 13:46:20 +0900 Subject: [PATCH 02/25] format src/* --- src/main.cpp | 47 +++++++++++++++++++++++++--------------- src/sbd_helper.hpp | 53 +++++++--------------------------------------- src/sqd_helper.hpp | 42 ++++++++++++++---------------------- 3 files changed, 54 insertions(+), 88 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index b1ced01..1e5aeb7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -48,7 +48,7 @@ using Sampler = BackendSamplerV2; // with Bernoulli(p=0.5) and aggregate into counts (bitstring -> occurrences). // Use this when a real backend/simulator is unavailable (debugging). std::unordered_map -generate_counts_uniform(int num_samples, int num_bits, +generate_counts_uniform(int num_samples, int num_bits, // NOLINT(bugprone-easily-swappable-parameters) std::optional seed = std::nullopt) { std::mt19937 rng(seed.value_or(std::random_device{}())); @@ -70,8 +70,8 @@ generate_counts_uniform(int num_samples, int num_bits, } // Convert an array of boost::dynamic_bitset<> to string-based BitString objects. -static auto -bitsets_to_bitstrings(const std::vector>& bitsets) -> std::vector +static auto bitsets_to_bitstrings(const std::vector>& bitsets) + -> std::vector { std::vector bitstrings; bitstrings.reserve(bitsets.size()); @@ -117,8 +117,8 @@ std::array, 2> load_initial_occupancies(const std::string& f } const auto half_size = init_occupancy.size() / 2; - std::vector alpha_occupancy(init_occupancy.begin(), init_occupancy.begin() + half_size); - std::vector beta_occupancy(init_occupancy.begin() + half_size, init_occupancy.end()); + std::vector alpha_occupancy(init_occupancy.begin(), init_occupancy.begin() + static_cast(half_size)); + std::vector beta_occupancy(init_occupancy.begin() + static_cast(half_size), init_occupancy.end()); std::reverse(alpha_occupancy.begin(), alpha_occupancy.end()); std::reverse(beta_occupancy.begin(), beta_occupancy.end()); @@ -129,7 +129,7 @@ std::array, 2> load_initial_occupancies(const std::string& f // Utility: normalize counts (occurrences) into probabilities in [0,1]. // Empty input returns an empty map (no exception). std::unordered_map -_normalize_counts_dict(const std::unordered_map& counts) +normalize_counts_dict(const std::unordered_map& counts) { // Check if the input map is empty if (counts.empty()) @@ -146,7 +146,7 @@ _normalize_counts_dict(const std::unordered_map& counts) std::unordered_map probabilities; for (const auto& [key, value] : counts) { - probabilities[key] = static_cast(value) / total_counts; + probabilities[key] = static_cast(value) / static_cast(total_counts); } return probabilities; @@ -164,7 +164,7 @@ counts_to_arrays(const std::unordered_map& counts) return {bs_mat, freq_arr}; // Normalize the counts to probabilities - auto prob_dict = _normalize_counts_dict(counts); + auto prob_dict = normalize_counts_dict(counts); // Convert bitstrings to a 2D boolean matrix for (const auto& [bitstring, _] : prob_dict) @@ -186,7 +186,9 @@ using namespace ffsim; int main(int argc, char* argv[]) { - // ===== MPI initialization ===== + try + { + // ===== MPI initialization ===== // This workflow assumes MPI. Request FUNNELED (only main thread calls MPI). int provided; int mpi_init_error = MPI_Init_thread(&argc, &argv, MPI_THREAD_FUNNELED, &provided); @@ -211,7 +213,7 @@ int main(int argc, char* argv[]) sqd_data.comm = MPI_COMM_WORLD; MPI_Comm_rank(sqd_data.comm, &sqd_data.mpi_rank); MPI_Comm_size(sqd_data.comm, &sqd_data.mpi_size); - int message_size = sqd_data.run_id.size(); + int message_size = static_cast(sqd_data.run_id.size()); MPI_Bcast(&message_size, 1, MPI_INT, 0, MPI_COMM_WORLD); if (sqd_data.mpi_rank != 0) { @@ -228,7 +230,6 @@ int main(int argc, char* argv[]) std::mt19937 rc_rng(rng()); // Batch sizing for SBD input (alpha-determinant groups). uint64_t samples_per_batch = sqd_data.samples_per_batch; - uint64_t n_batches = sqd_data.n_batches; // Read initial parameters (norb, nelec, params for lucj) from JSON. const std::string input_file_path = "../data/parameters_fe4s4.json"; @@ -257,7 +258,6 @@ int main(int argc, char* argv[]) log(sqd_data, {"initial parameters are loaded. param_length=", std::to_string(init_params.size())}); } - int node_per_member = sqd_data.mpi_size; // Measurement results: (bitstring -> counts). Produced on rank 0, then array-ified // later. @@ -279,7 +279,7 @@ int main(int argc, char* argv[]) Eigen::VectorXcd params(params_size); for (size_t i = 0; i < params_size; ++i) { - params(i) = init_params[i]; + params(static_cast(i)) = init_params[i]; } std::optional t1 = std::nullopt; // 'interaction_pairs' allows passing (alpha-alpha, alpha-beta/beta-beta) @@ -378,7 +378,7 @@ int main(int argc, char* argv[]) std::vector> bs_mat_tmp; std::vector probs_arr_tmp; std::array, 2> latest_occupancies, initial_occupancies; - int n_recovery = sqd_data.n_recovery; + int n_recovery = static_cast(sqd_data.n_recovery); try { @@ -451,8 +451,21 @@ int main(int argc, char* argv[]) } } - // Synchronize and tear down MPI. No MPI calls are allowed beyond this point. - MPI_Finalize(); + // Synchronize and tear down MPI. No MPI calls are allowed beyond this point. + MPI_Finalize(); - return 0; + return 0; + } + catch (const std::exception& e) + { + std::cerr << "Unhandled exception in main: " << e.what() << std::endl; + MPI_Finalize(); + return 1; + } + catch (...) + { + std::cerr << "Unknown exception in main" << std::endl; + MPI_Finalize(); + return 1; + } } diff --git a/src/sbd_helper.hpp b/src/sbd_helper.hpp index 20e9c77..02d12ca 100644 --- a/src/sbd_helper.hpp +++ b/src/sbd_helper.hpp @@ -12,8 +12,8 @@ # that they have been altered from the originals. */ -#ifndef __sbd_helper_hpp__ -#define __sbd_helper_hpp__ +#ifndef SBD_HELPER_HPP_ +#define SBD_HELPER_HPP_ #include #include @@ -26,7 +26,7 @@ #include #endif -#define _USE_MATH_DEFINES +#define USE_MATH_DEFINES #include #include "mpi.h" @@ -119,8 +119,6 @@ std::tuple> sbd_main(const MPI_Comm& comm, const SBD int adet_comm_size = sbd_data.adet_comm_size; int bdet_comm_size = sbd_data.bdet_comm_size; int base_comm_size; - int h_comm_size = sbd_data.h_comm_size; - int L; int N; @@ -138,7 +136,7 @@ std::tuple> sbd_main(const MPI_Comm& comm, const SBD std::string fcidumpfile = sbd_data.fcidumpfile; base_comm_size = adet_comm_size * bdet_comm_size * task_comm_size; - h_comm_size = mpi_size / base_comm_size; + int h_comm_size = mpi_size / base_comm_size; if (mpi_size != base_comm_size * h_comm_size) { @@ -188,16 +186,10 @@ std::tuple> sbd_main(const MPI_Comm& comm, const SBD sbd::TaskCommunicator(comm, h_comm_size, adet_comm_size, bdet_comm_size, task_comm_size, h_comm, b_comm, t_comm); - auto time_start_help = std::chrono::high_resolution_clock::now(); sbd::MakeHelpers(adet, bdet, bit_length, L, helper, sharedMemory, h_comm, b_comm, t_comm, adet_comm_size, bdet_comm_size); sbd::RemakeHelpers(adet, bdet, bit_length, L, helper, sharedMemory, h_comm, b_comm, t_comm, adet_comm_size, bdet_comm_size); - auto time_end_help = std::chrono::high_resolution_clock::now(); - auto elapsed_help_count = - std::chrono::duration_cast(time_end_help - time_start_help) - .count(); - double elapsed_help = 0.000001 * elapsed_help_count; int mpi_rank_h; MPI_Comm_rank(h_comm, &mpi_rank_h); @@ -215,37 +207,24 @@ std::tuple> sbd_main(const MPI_Comm& comm, const SBD /** Initialize/Load wave function */ - auto time_start_init = std::chrono::high_resolution_clock::now(); std::vector W; sbd::BasisInitVector(W, adet, bdet, adet_comm_size, bdet_comm_size, h_comm, b_comm, t_comm, init); - auto time_end_init = std::chrono::high_resolution_clock::now(); - auto elapsed_init_count = - std::chrono::duration_cast(time_end_init - time_start_init) - .count(); - double elapsed_init = 1.0e-6 * elapsed_init_count; - /** Diagonalization */ std::vector hii; auto time_start_diag = std::chrono::high_resolution_clock::now(); - auto time_start_davidson = std::chrono::high_resolution_clock::now(); sbd::makeQChamDiagTerms(adet, bdet, bit_length, L, helper, I0, I1, I2, hii, h_comm, b_comm, t_comm); sbd::Davidson(hii, W, adet, bdet, bit_length, static_cast(L), adet_comm_size, bdet_comm_size, helper, I0, I1, I2, h_comm, b_comm, t_comm, max_it, max_nb, eps, max_time); - auto time_end_davidson = std::chrono::high_resolution_clock::now(); - auto elapsed_davidson_count = std::chrono::duration_cast( - time_end_davidson - time_start_davidson) - .count(); - double elapsed_davidson = 0.000001 * elapsed_davidson_count; auto time_end_diag = std::chrono::high_resolution_clock::now(); auto elapsed_diag_count = std::chrono::duration_cast(time_end_diag - time_start_diag) .count(); - double elapsed_diag = 0.000001 * elapsed_diag_count; + double elapsed_diag = 0.000001 * static_cast(elapsed_diag_count); if (mpi_rank == 0) std::cout << " Elapsed time for diagonalization " << elapsed_diag << " (sec) " << std::endl; @@ -255,15 +234,9 @@ std::tuple> sbd_main(const MPI_Comm& comm, const SBD std::vector C(W.size(), 0.0); - auto time_start_mult = std::chrono::high_resolution_clock::now(); sbd::mult(hii, W, C, adet, bdet, bit_length, static_cast(L), adet_comm_size, bdet_comm_size, helper, I0, I1, I2, h_comm, b_comm, t_comm); - auto time_end_mult = std::chrono::high_resolution_clock::now(); - auto elapsed_mult_count = - std::chrono::duration_cast(time_end_mult - time_start_mult) - .count(); - double elapsed_mult = 0.000001 * elapsed_mult_count; sbd::InnerProduct(W, C, E, b_comm); if (energy_target != 0.0 && std::abs(E - energy_target) > energy_variance) @@ -279,7 +252,6 @@ std::tuple> sbd_main(const MPI_Comm& comm, const SBD /** Evaluation of single-particle occupation density */ - auto time_start_meas = std::chrono::high_resolution_clock::now(); int p_size = mpi_size_t * mpi_size_h; int p_rank = mpi_rank_h * mpi_size_t + mpi_rank_t; size_t o_start = 0; @@ -291,9 +263,9 @@ std::tuple> sbd_main(const MPI_Comm& comm, const SBD std::vector res_density; sbd::OccupationDensity(oIdx, W, adet, bdet, bit_length, adet_comm_size, bdet_comm_size, b_comm, res_density); - std::vector density_rank(2 * L, 0.0); - std::vector density_group(2 * L, 0.0); - std::vector density(2 * L, 0.0); + std::vector density_rank(static_cast(2 * L), 0.0); + std::vector density_group(static_cast(2 * L), 0.0); + std::vector density(static_cast(2 * L), 0.0); for (size_t io = o_start; io < o_end; io++) { density_rank[2 * io] = res_density[2 * (io - o_start)]; @@ -301,15 +273,6 @@ std::tuple> sbd_main(const MPI_Comm& comm, const SBD } MPI_Allreduce(density_rank.data(), density_group.data(), 2 * L, MPI_DOUBLE, MPI_SUM, t_comm); MPI_Allreduce(density_group.data(), density.data(), 2 * L, MPI_DOUBLE, MPI_SUM, h_comm); - auto time_end_meas = std::chrono::high_resolution_clock::now(); - auto elapsed_meas_count = - std::chrono::duration_cast(time_end_meas - time_start_meas) - .count(); - double elapsed_meas = 0.000001 * elapsed_meas_count; - double threshold = 1.0e-2; - if (sbd_data.threshold != 0.0) - threshold = sbd_data.threshold; - std::vector> rdet; FreeHelpers(helper); return {E, density}; diff --git a/src/sqd_helper.hpp b/src/sqd_helper.hpp index 196182a..73f1358 100644 --- a/src/sqd_helper.hpp +++ b/src/sqd_helper.hpp @@ -12,8 +12,8 @@ # that they have been altered from the originals. */ -#ifndef __sqd_helper_hpp__ -#define __sqd_helper_hpp__ +#ifndef SQD_HELPER_HPP_ +#define SQD_HELPER_HPP_ #include #include @@ -24,7 +24,7 @@ #include -#define _USE_MATH_DEFINES +#define USE_MATH_DEFINES #include #include "mpi.h" @@ -55,7 +55,7 @@ struct UArrayString size_t nbits; const static size_t REG_SIZE = 64; - static size_t _VEC_SIZE(size_t nbits) + static size_t VEC_SIZE(size_t nbits) { return nbits / REG_SIZE + ((nbits % REG_SIZE) == 0 ? 0 : 1); } @@ -111,7 +111,7 @@ struct UArrayString inline bool operator[](const size_t idx) const { return get(idx); } }; -UArrayString::UArrayString(uint64_t src, size_t nbits_) : data({src}), nbits(nbits_) +UArrayString::UArrayString(uint64_t src, size_t nbits_) : data({src}), nbits(nbits_) // NOLINT(bugprone-easily-swappable-parameters) { if (nbits_ > 1) data.resize(nbits_, 0UL); @@ -123,13 +123,13 @@ UArrayString::UArrayString(const std::vector& src, const size_t nbits_ } UArrayString::UArrayString(const std::vector& src) - : data(_VEC_SIZE(src.size())), nbits(src.size()) + : data(VEC_SIZE(src.size())), nbits(src.size()) { for (size_t i = 0; i < src.size(); ++i) set(i, src[i]); } -UArrayString::UArrayString(const std::string& src) : data(_VEC_SIZE(src.size())), nbits(src.size()) +UArrayString::UArrayString(const std::string& src) : data(VEC_SIZE(src.size())), nbits(src.size()) { for (size_t i = 0; i < src.size(); ++i) set(i, src[i] == '1'); @@ -139,7 +139,7 @@ UArrayString::UArrayString(std::initializer_list init) { std::vector src(init); nbits = src.size(); - data = std::vector(_VEC_SIZE(src.size())); + data = std::vector(VEC_SIZE(src.size())); for (size_t i = 0; i < src.size(); ++i) set(i, src[i]); } @@ -190,7 +190,7 @@ std::vector UArrayString::to_vector(void) const return ret; } -size_t UArrayString::get_counts(const size_t from, const size_t until, const bool value) const +size_t UArrayString::get_counts(const size_t from, const size_t until, const bool value) const // NOLINT(bugprone-easily-swappable-parameters) { size_t ret = 0; for (size_t i = from; i < until; ++i) @@ -199,7 +199,7 @@ size_t UArrayString::get_counts(const size_t from, const size_t until, const boo return ret; } -std::vector UArrayString::get_indices(const size_t from, const size_t until, +std::vector UArrayString::get_indices(const size_t from, const size_t until, // NOLINT(bugprone-easily-swappable-parameters) const bool value) const { std::vector ret; @@ -304,17 +304,6 @@ void error(const SQD& sqd_data, const std::vector& messages) } } -std::vector split_string(const std::string& str) -{ - std::vector result; - std::stringstream ss(str); - std::string token; - - while (std::getline(ss, token, ',')) - result.push_back(token); - - return result; -} SQD generate_sqd_data(int argc, char* argv[]) { @@ -354,7 +343,7 @@ SQD generate_sqd_data(int argc, char* argv[]) return sqd; } -std::vector integer_to_bytes(uint64_t n, int norb) +std::vector integer_to_bytes(uint64_t n, int norb) // NOLINT(bugprone-easily-swappable-parameters) { int num_bytes = (norb + 7) / 8; std::vector result(num_bytes); @@ -371,6 +360,7 @@ std::vector integer_to_bytes(uint64_t n, int norb) std::vector> ci_strs_to_bytes(const std::vector& ci_strs, int norb) { std::vector> bytes; + bytes.reserve(ci_strs.size()); for (uint64_t ci_str : ci_strs) { bytes.push_back(integer_to_bytes(ci_str, norb)); @@ -406,15 +396,15 @@ void write_bytestrings_to_file(const std::vector>& byte_str for (const auto& byte_string : byte_strings) { - output_file.write(reinterpret_cast(byte_string.data()), byte_string.size()); + output_file.write(reinterpret_cast(byte_string.data()), static_cast(byte_string.size())); } output_file.close(); } -std::string write_alphadets_file(const SQD& sqd_data, const size_t norb, const size_t num_elec, +std::string write_alphadets_file(const SQD& sqd_data, const size_t norb, const size_t num_elec, // NOLINT(bugprone-easily-swappable-parameters) const std::vector& batch, - const size_t maximum_numbers_of_ctrs, const size_t i_recovery) + const size_t maximum_numbers_of_ctrs, const size_t i_recovery) // NOLINT(bugprone-easily-swappable-parameters) { log(sqd_data, {"number of items in a batch: ", std::to_string(batch.size())}); bool open_shell = false; @@ -436,7 +426,7 @@ std::string write_alphadets_file(const SQD& sqd_data, const size_t norb, const s log(sqd_data, {"number of unique ci_strs:", std::to_string(unique_ci_strs.size()), ", truncated:", std::to_string(truncated)}); } - auto bytestrings = ci_strs_to_bytes(unique_ci_strs, norb); + auto bytestrings = ci_strs_to_bytes(unique_ci_strs, static_cast(norb)); std::string alphadets_bin_file = "AlphaDets_" + sqd_data.run_id + "_" + std::to_string(i_recovery) + "_cpp.bin"; write_bytestrings_to_file(bytestrings, alphadets_bin_file); From 0ac6430b7037c3debe4a90fa684ab25da442c2af Mon Sep 17 00:00:00 2001 From: to24toro Date: Sun, 28 Sep 2025 18:37:47 +0900 Subject: [PATCH 03/25] format ffsim --- .github/workflows/coverage.yml | 1 - .github/workflows/lint.yml | 4 +- README.md | 2 +- ffsim/include/ffsim/diag_coulomb_jw.hpp | 38 ++--- ffsim/include/ffsim/gates/diag_coulomb.hpp | 140 +++++++++--------- ffsim/include/ffsim/gates/gates.hpp | 6 +- .../include/ffsim/gates/orbital_rotation.hpp | 43 +++--- ffsim/include/ffsim/gates/phase_shift.hpp | 2 +- .../ffsim/linalg/double_factorized_decomp.hpp | 38 ++--- ffsim/include/ffsim/linalg/givens.hpp | 28 ++-- ffsim/include/ffsim/orbital_rotation_jw.hpp | 8 +- ffsim/include/ffsim/random_unitary.hpp | 6 +- ffsim/include/ffsim/slater_determinant.hpp | 22 +-- ffsim/include/ffsim/ucj.hpp | 6 +- ffsim/include/ffsim/ucjop_spinbalanced.hpp | 52 ++++--- ffsim/include/ffsim/utils.hpp | 36 +++-- src/main.cpp | 2 +- 17 files changed, 231 insertions(+), 203 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index caf81ce..7776aa6 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -56,7 +56,6 @@ jobs: gcovr --coveralls coveralls.json --root . --exclude build --exclude deps - --exclude benchmark - name: Upload report to Coveralls if: always() uses: coverallsapp/github-action@v2 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 9cb2ae5..cc348f0 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -38,7 +38,7 @@ jobs: - name: Run clang-format check run: | - fd '\.(cpp|hpp|h|c)$' src \ + fd '\.(cpp|hpp|h|c)$' src ffsim/include/ffsim \ --exec clang-format --dry-run -Werror - name: Configure CMake (for compile_commands.json) @@ -46,5 +46,5 @@ jobs: - name: Run clang-tidy run: | - fd '\.(cpp|hpp|h|c)$' src \ + fd '\.(cpp|hpp|h|c)$' src ffsim/include/ffsim \ --exec-batch clang-tidy -p build --extra-arg=-Wno-error=missing-headers {} + diff --git a/README.md b/README.md index d66c2ab..ef32d65 100644 --- a/README.md +++ b/README.md @@ -198,6 +198,6 @@ new ones. ## Contributing -The source code is available [on GitHub]. +The source code is available [on GitHub](https://github.com/qiskit-community/qiskit-capi-demo). By participating, you are expected to uphold Qiskit's [code of conduct](https://github.com/Qiskit/qiskit/blob/main/CODE_OF_CONDUCT.md). diff --git a/ffsim/include/ffsim/diag_coulomb_jw.hpp b/ffsim/include/ffsim/diag_coulomb_jw.hpp index 8542e2d..79fee5e 100644 --- a/ffsim/include/ffsim/diag_coulomb_jw.hpp +++ b/ffsim/include/ffsim/diag_coulomb_jw.hpp @@ -99,9 +99,9 @@ class DiagCoulombEvolutionJW } else { - return std::make_tuple(mat.triple[0].value_or(MatrixXcd::Zero(norb, norb)), - mat.triple[1].value_or(MatrixXcd::Zero(norb, norb)), - mat.triple[2].value_or(MatrixXcd::Zero(norb, norb))); + return std::make_tuple(mat.triple[0].value_or(MatrixXcd::Zero(static_cast(norb), static_cast(norb))), + mat.triple[1].value_or(MatrixXcd::Zero(static_cast(norb), static_cast(norb))), + mat.triple[2].value_or(MatrixXcd::Zero(static_cast(norb), static_cast(norb)))); } }(); @@ -110,26 +110,26 @@ class DiagCoulombEvolutionJW const auto& this_mat = (sigma == 0) ? mat_aa : mat_bb; for (size_t i = 0; i < norb; ++i) { - if (std::abs(this_mat(i, i).real()) > 1e-12 || - std::abs(this_mat(i, i).imag()) > 1e-12) + if (std::abs(this_mat(static_cast(i), static_cast(i)).real()) > 1e-12 || + std::abs(this_mat(static_cast(i), static_cast(i)).imag()) > 1e-12) { instructions.push_back( {"rz", {static_cast(qubits[i + sigma * norb])}, {}, - std::vector{-0.5 * this_mat(i, i).real() * time}}); + std::vector{-0.5 * this_mat(static_cast(i), static_cast(i)).real() * time}}); } for (size_t j = i + 1; j < norb; ++j) { - if (std::abs(this_mat(i, j).real()) > 1e-12 || - std::abs(this_mat(i, j).imag()) > 1e-12) + if (std::abs(this_mat(static_cast(i), static_cast(j)).real()) > 1e-12 || + std::abs(this_mat(static_cast(i), static_cast(j)).imag()) > 1e-12) { instructions.push_back( {"cp", {static_cast(qubits[i + sigma * norb]), static_cast(qubits[j + sigma * norb])}, {}, - std::vector{-1.0 * this_mat(i, j).real() * time}}); + std::vector{-1.0 * this_mat(static_cast(i), static_cast(j)).real() * time}}); } } } @@ -137,33 +137,33 @@ class DiagCoulombEvolutionJW for (size_t i = 0; i < norb; ++i) { - if (std::abs(mat_ab(i, i).real()) > 1e-12 || std::abs(mat_ab(i, i).imag()) > 1e-12) + if (std::abs(mat_ab(static_cast(i), static_cast(i)).real()) > 1e-12 || std::abs(mat_ab(static_cast(i), static_cast(i)).imag()) > 1e-12) { instructions.push_back({"cp", {static_cast(qubits[i]), static_cast(qubits[i + norb])}, {}, - std::vector{-1.0 * mat_ab(i, i).real() * time}}); + std::vector{-1.0 * mat_ab(static_cast(i), static_cast(i)).real() * time}}); } for (size_t j = i + 1; j < norb; ++j) { - if (std::abs(mat_ab(i, j).real()) > 1e-12 || std::abs(mat_ab(i, j).imag()) > 1e-12) + if (std::abs(mat_ab(static_cast(i), static_cast(j)).real()) > 1e-12 || std::abs(mat_ab(static_cast(i), static_cast(j)).imag()) > 1e-12) { instructions.push_back( {"cp", {static_cast(qubits[i]), static_cast(qubits[j + norb])}, {}, - std::vector{-1.0 * mat_ab(i, j).real() * time}}); + std::vector{-1.0 * mat_ab(static_cast(i), static_cast(j)).real() * time}}); } - if (std::abs(mat_ab(j, i).real()) > 1e-12 || std::abs(mat_ab(j, i).imag()) > 1e-12) + if (std::abs(mat_ab(static_cast(j), static_cast(i)).real()) > 1e-12 || std::abs(mat_ab(static_cast(j), static_cast(i)).imag()) > 1e-12) { instructions.push_back( {"cp", {static_cast(qubits[j]), static_cast(qubits[i + norb])}, {}, - std::vector{-1.0 * mat_ab(j, i).real() * time}}); + std::vector{-1.0 * mat_ab(static_cast(j), static_cast(i)).real() * time}}); } } } @@ -186,9 +186,9 @@ class DiagCoulombEvolutionJW } else { - return std::make_tuple(mat.triple[0].value_or(MatrixXcd::Zero(norb, norb)), - mat.triple[1].value_or(MatrixXcd::Zero(norb, norb)), - mat.triple[2].value_or(MatrixXcd::Zero(norb, norb))); + return std::make_tuple(mat.triple[0].value_or(MatrixXcd::Zero(static_cast(norb), static_cast(norb))), + mat.triple[1].value_or(MatrixXcd::Zero(static_cast(norb), static_cast(norb))), + mat.triple[2].value_or(MatrixXcd::Zero(static_cast(norb), static_cast(norb)))); } }(); @@ -201,7 +201,7 @@ class DiagCoulombEvolutionJW const MatrixXcd this_mat = (i < norb && j < norb) ? mat_aa : (i >= norb && j >= norb) ? mat_bb : mat_ab; - const auto val = this_mat(i % norb, j % norb); + const auto val = this_mat(static_cast(i % norb), static_cast(j % norb)); if (std::abs(val.real()) > 1e-12 || std::abs(val.imag()) > 1e-12) { instructions.push_back({"rzz", diff --git a/ffsim/include/ffsim/gates/diag_coulomb.hpp b/ffsim/include/ffsim/gates/diag_coulomb.hpp index a645326..53695fc 100644 --- a/ffsim/include/ffsim/gates/diag_coulomb.hpp +++ b/ffsim/include/ffsim/gates/diag_coulomb.hpp @@ -18,7 +18,9 @@ #include "ffsim/linalg/givens.hpp" #include "orbital_rotation.hpp" #include +#include #include +#include #include #include @@ -36,7 +38,7 @@ using namespace Eigen; * - Single: Represents a single matrix. * - Triple: Represents a set of three matrices. */ -enum class MatType +enum class MatType : std::uint8_t { Single, ///< Represents a single matrix for all orbitals. Triple, ///< Represents a set of three matrices for (aa, ab, bb) orbitals. @@ -57,9 +59,18 @@ struct Mat std::array, 3> triple; ///< Three matrices (used when type is Triple). }; -std::tuple -get_mat_exp(const Mat& mat, double time, uint64_t norb, bool z_representation, - MatrixXcd& mat_exp_aa, MatrixXcd& mat_exp_ab, MatrixXcd& mat_exp_bb) +/** + * @brief Matrix exponentials for diagonal Coulomb evolution. + * @details This structure holds the matrix exponentials to avoid parameter confusion. + */ +struct MatExp +{ + MatrixXcd aa; // Matrix exponential for alpha-alpha interactions. + MatrixXcd ab; // Matrix exponential for alpha-beta interactions. + MatrixXcd bb; // Matrix exponential for beta-beta interactions. +}; + +MatExp get_mat_exp(const Mat& mat, uint64_t norb, bool z_representation, double time) { const Complex I(0.0, 1.0); if (mat.type == MatType::Single) @@ -68,7 +79,7 @@ get_mat_exp(const Mat& mat, double time, uint64_t norb, bool z_representation, MatrixXcd mat_ab = mat.single; for (size_t i = 0; i < norb; ++i) { - mat_aa(i, i) *= 0.5; + mat_aa(static_cast(i), static_cast(i)) *= 0.5; } if (z_representation) { @@ -76,63 +87,64 @@ get_mat_exp(const Mat& mat, double time, uint64_t norb, bool z_representation, mat_ab *= 0.25; } - mat_exp_aa = (-I * time * mat_aa.array()).exp().matrix(); - mat_exp_ab = (-I * time * mat_ab.array()).exp().matrix(); - mat_exp_bb = mat_exp_aa; + MatExp result; + result.aa = (-I * time * mat_aa.array()).exp().matrix(); + result.ab = (-I * time * mat_ab.array()).exp().matrix(); + result.bb = result.aa; - return {mat_exp_aa, mat_exp_ab, mat_exp_bb}; + return result; } else { - if (mat.triple[0].has_value()) + MatExp result; + if (const auto& opt_mat = mat.triple[0]; opt_mat.has_value()) { - MatrixXcd mat_aa = mat.triple[0].value(); + MatrixXcd mat_aa = opt_mat.value(); for (size_t i = 0; i < norb; ++i) { - mat_aa(i, i) *= 0.5; + mat_aa(static_cast(i), static_cast(i)) *= 0.5; } if (z_representation) { mat_aa *= 0.25; } - mat_exp_aa = (-I * time * mat_aa.array()).exp().matrix(); + result.aa = (-I * time * mat_aa.array()).exp().matrix(); } else { - mat_exp_aa = MatrixXcd::Identity(norb, norb); + result.aa = MatrixXcd::Identity(static_cast(norb), static_cast(norb)); } - - if (mat.triple[1].has_value()) + if (const auto& opt_mat = mat.triple[1]; opt_mat.has_value()) { - MatrixXcd mat_ab = mat.triple[1].value(); + MatrixXcd mat_ab = opt_mat.value(); if (z_representation) { mat_ab *= 0.25; } - mat_exp_ab = (-I * time * mat_ab.array()).exp().matrix(); + result.ab = (-I * time * mat_ab.array()).exp().matrix(); } else { - mat_exp_ab = MatrixXcd::Identity(norb, norb); + result.ab = MatrixXcd::Identity(static_cast(norb), static_cast(norb)); } - if (mat.triple[2].has_value()) + if (const auto& opt_mat = mat.triple[2]; opt_mat.has_value()) { - MatrixXcd mat_bb = mat.triple[2].value(); + MatrixXcd mat_bb = opt_mat.value(); for (size_t i = 0; i < norb; ++i) { - mat_bb(i, i) *= 0.5; + mat_bb(static_cast(i), static_cast(i)) *= 0.5; } if (z_representation) { mat_bb *= 0.25; } - mat_exp_bb = (-I * time * mat_bb.array()).exp().matrix(); + result.bb = (-I * time * mat_bb.array()).exp().matrix(); } else { - mat_exp_bb = MatrixXcd::Identity(norb, norb); + result.bb = MatrixXcd::Identity(static_cast(norb), static_cast(norb)); } - return {mat_exp_aa, mat_exp_ab, mat_exp_bb}; + return result; } } @@ -149,9 +161,9 @@ OrbitalRotation conjugate_orbital_rotation(const OrbitalRotation& orb_rot) std::array, 2> spinfull_conj; for (int i = 0; i < 2; ++i) { - if (orb_rot.spinfull[i].has_value()) + if (const auto& opt_spinfull = orb_rot.spinfull[i]; opt_spinfull.has_value()) { - spinfull_conj[i] = orb_rot.spinfull[i].value().adjoint(); + spinfull_conj[i] = opt_spinfull.value().adjoint(); } else { @@ -163,8 +175,7 @@ OrbitalRotation conjugate_orbital_rotation(const OrbitalRotation& orb_rot) } void apply_diag_coulomb_evolution_in_place_num_rep( - MatrixXcd& vec, const MatrixXcd& mat_exp_aa, const MatrixXcd& mat_exp_ab, - const MatrixXcd& mat_exp_bb, uint64_t norb, + MatrixXcd& vec, uint64_t norb, const MatExp& mat_exp, const std::vector>& occupations_a, const std::vector>& occupations_b) { @@ -173,9 +184,9 @@ void apply_diag_coulomb_evolution_in_place_num_rep( const size_t n_alpha = occupations_a.empty() ? 0 : occupations_a[0].size(); const size_t n_beta = occupations_b.empty() ? 0 : occupations_b[0].size(); - ArrayXcd alpha_phases = ArrayXcd::Zero(dim_a); - ArrayXcd beta_phases = ArrayXcd::Zero(dim_b); - ArrayXXcd phase_map = ArrayXXcd::Ones(dim_a, dim_b); + ArrayXcd alpha_phases = ArrayXcd::Zero(static_cast(dim_a)); + ArrayXcd beta_phases = ArrayXcd::Zero(static_cast(dim_b)); + ArrayXXcd phase_map = ArrayXXcd::Ones(static_cast(dim_a), static_cast(dim_b)); for (size_t i = 0; i < dim_b; ++i) { @@ -186,10 +197,10 @@ void apply_diag_coulomb_evolution_in_place_num_rep( for (size_t k = j; k < n_beta; ++k) { size_t orb_2 = occupations_b[i][k]; - phase *= mat_exp_bb(orb_1, orb_2); + phase *= mat_exp.bb(static_cast(orb_1), static_cast(orb_2)); } } - beta_phases(i) = phase; + beta_phases(static_cast(i)) = phase; } for (size_t i = 0; i < dim_a; ++i) { @@ -197,46 +208,45 @@ void apply_diag_coulomb_evolution_in_place_num_rep( for (size_t j = 0; j < n_alpha; ++j) { size_t orb_1 = occupations_a[i][j]; - phase_map.row(i) = phase_map.row(i).array() * mat_exp_ab.row(orb_1).array(); + phase_map.row(static_cast(i)) = phase_map.row(static_cast(i)).array() * mat_exp.ab.row(static_cast(orb_1)).array(); for (size_t k = j; k < n_alpha; ++k) { size_t orb_2 = occupations_a[i][k]; - phase *= mat_exp_aa(orb_1, orb_2); + phase *= mat_exp.aa(static_cast(orb_1), static_cast(orb_2)); } } - alpha_phases(i) = phase; + alpha_phases(static_cast(i)) = phase; } for (size_t i = 0; i < dim_a; ++i) { for (size_t j = 0; j < dim_b; ++j) { - Complex phase = alpha_phases(i) * beta_phases(j); + Complex phase = alpha_phases(static_cast(i)) * beta_phases(static_cast(j)); for (size_t k = 0; k < n_beta; ++k) { size_t orb = occupations_b[j][k]; - phase *= phase_map(i, orb); + phase *= phase_map(static_cast(i), static_cast(orb)); } - vec(i, j) *= phase; + vec(static_cast(i), static_cast(j)) *= phase; } } } -void apply_diag_coulomb_evolution_in_place_z_rep(MatrixXcd& vec, MatrixXcd& mat_exp_aa, - MatrixXcd& mat_exp_ab, MatrixXcd& mat_exp_bb, - uint64_t norb, +void apply_diag_coulomb_evolution_in_place_z_rep(MatrixXcd& vec, uint64_t norb, + MatExp& mat_exp, const std::vector& strings_a, const std::vector& strings_b) { - MatrixXcd mat_exp_aa_conj = mat_exp_aa.conjugate(); - MatrixXcd mat_exp_ab_conj = mat_exp_ab.conjugate(); - MatrixXcd mat_exp_bb_conj = mat_exp_bb.conjugate(); + MatrixXcd mat_exp_aa_conj = mat_exp.aa.conjugate(); + MatrixXcd mat_exp_ab_conj = mat_exp.ab.conjugate(); + MatrixXcd mat_exp_bb_conj = mat_exp.bb.conjugate(); size_t dim_a = vec.rows(); size_t dim_b = vec.cols(); - ArrayXcd alpha_phases = ArrayXcd::Zero(dim_a); - ArrayXcd beta_phases = ArrayXcd::Zero(dim_b); - ArrayXXcd phase_map = ArrayXXcd::Ones(dim_a, norb); + ArrayXcd alpha_phases = ArrayXcd::Zero(static_cast(dim_a)); + ArrayXcd beta_phases = ArrayXcd::Zero(static_cast(dim_b)); + ArrayXXcd phase_map = ArrayXXcd::Ones(static_cast(dim_a), static_cast(norb)); for (size_t i = 0; i < dim_b; ++i) { @@ -248,11 +258,11 @@ void apply_diag_coulomb_evolution_in_place_z_rep(MatrixXcd& vec, MatrixXcd& mat_ for (size_t k = j + 1; k < norb; ++k) { bool sign_k = (str0 >> k) & 1; - Complex this_phase = (sign_j ^ sign_k) ? mat_exp_bb_conj(j, k) : mat_exp_bb(j, k); + Complex this_phase = (sign_j ^ sign_k) ? mat_exp_bb_conj(static_cast(j), static_cast(k)) : mat_exp.bb(static_cast(j), static_cast(k)); phase *= this_phase; } } - beta_phases(i) = phase; + beta_phases(static_cast(i)) = phase; } for (size_t i = 0; i < dim_a; ++i) @@ -262,34 +272,34 @@ void apply_diag_coulomb_evolution_in_place_z_rep(MatrixXcd& vec, MatrixXcd& mat_ for (size_t j = 0; j < norb; ++j) { bool sign_j = (str0 >> j) & 1; - auto this_row = sign_j ? mat_exp_ab_conj.row(j) : mat_exp_ab.row(j); + auto this_row = sign_j ? mat_exp_ab_conj.row(static_cast(j)) : mat_exp.ab.row(static_cast(j)); for (size_t k = 0; k < norb; ++k) { - phase_map(i, k) *= this_row(k); + phase_map(static_cast(i), static_cast(k)) *= this_row(static_cast(k)); } for (size_t k = j + 1; k < norb; ++k) { bool sign_k = (str0 >> k) & 1; - Complex this_phase = (sign_j ^ sign_k) ? mat_exp_aa_conj(j, k) : mat_exp_aa(j, k); + Complex this_phase = (sign_j ^ sign_k) ? mat_exp_aa_conj(static_cast(j), static_cast(k)) : mat_exp.aa(static_cast(j), static_cast(k)); phase *= this_phase; } } - alpha_phases(i) = phase; + alpha_phases(static_cast(i)) = phase; } for (size_t i = 0; i < dim_a; ++i) { for (size_t j = 0; j < dim_b; ++j) { - Complex phase = alpha_phases(i) * beta_phases(j); + Complex phase = alpha_phases(static_cast(i)) * beta_phases(static_cast(j)); int64_t str0 = strings_b[j]; for (size_t k = 0; k < norb; ++k) { bool sign = (str0 >> k) & 1; - phase *= sign ? std::conj(phase_map(i, k)) : phase_map(i, k); + phase *= sign ? std::conj(phase_map(static_cast(i), static_cast(k))) : phase_map(static_cast(i), static_cast(k)); } - vec(i, j) *= phase; + vec(static_cast(i), static_cast(j)) *= phase; } } } @@ -298,9 +308,7 @@ VectorXcd apply_diag_coulomb_evolution_spinfull( VectorXcd vec, const Mat& mat, double time, uint64_t norb, std::pair nelec, const std::optional& orbital_rotation, bool z_representation) { - MatrixXcd mat_exp_aa, mat_exp_ab, mat_exp_bb; - std::tie(mat_exp_aa, mat_exp_ab, mat_exp_bb) = - get_mat_exp(mat, time, norb, z_representation, mat_exp_aa, mat_exp_ab, mat_exp_bb); + MatExp mat_exp = get_mat_exp(mat, norb, z_representation, time); size_t n_alpha = nelec.first; size_t n_beta = nelec.second; @@ -313,25 +321,25 @@ VectorXcd apply_diag_coulomb_evolution_spinfull( vec = apply_orbital_rotation(vec, conj_rot, norb, Electron{ElectronType::Spinfull, 0, {n_alpha, n_beta}}); } - MatrixXcd vec_reshaped = Map(vec.data(), dim_a, dim_b); + MatrixXcd vec_reshaped = Map(vec.data(), static_cast(dim_a), static_cast(dim_b)); std::vector orb_list(norb); std::iota(orb_list.begin(), orb_list.end(), 0); if (z_representation) { auto strings_a = make_strings(orb_list, n_alpha); auto strings_b = make_strings(orb_list, n_beta); - apply_diag_coulomb_evolution_in_place_z_rep(vec_reshaped, mat_exp_aa, mat_exp_ab, - mat_exp_bb, norb, strings_a, strings_b); + apply_diag_coulomb_evolution_in_place_z_rep(vec_reshaped, norb, mat_exp, + strings_a, strings_b); } else { auto occupations_a = gen_occslst(orb_list, n_alpha); auto occupations_b = gen_occslst(orb_list, n_beta); apply_diag_coulomb_evolution_in_place_num_rep( - vec_reshaped, mat_exp_aa, mat_exp_ab, mat_exp_bb, norb, occupations_a, occupations_b); + vec_reshaped, norb, mat_exp, occupations_a, occupations_b); } - VectorXcd vec_flat = Map(vec_reshaped.data(), dim_a * dim_b); + VectorXcd vec_flat = Map(vec_reshaped.data(), static_cast(dim_a * dim_b)); if (orbital_rotation.has_value()) { diff --git a/ffsim/include/ffsim/gates/gates.hpp b/ffsim/include/ffsim/gates/gates.hpp index 0ca0a65..7c81aa7 100644 --- a/ffsim/include/ffsim/gates/gates.hpp +++ b/ffsim/include/ffsim/gates/gates.hpp @@ -15,8 +15,8 @@ #ifndef GATES_HPP #define GATES_HPP -#include "gates/diag_coulomb.hpp" -#include "gates/orbital_rotation.hpp" -#include "gates/phase_shift.hpp" +#include "diag_coulomb.hpp" +#include "orbital_rotation.hpp" +#include "phase_shift.hpp" #endif // GATES_HPP \ No newline at end of file diff --git a/ffsim/include/ffsim/gates/orbital_rotation.hpp b/ffsim/include/ffsim/gates/orbital_rotation.hpp index 7fa0b05..d4cc8b8 100644 --- a/ffsim/include/ffsim/gates/orbital_rotation.hpp +++ b/ffsim/include/ffsim/gates/orbital_rotation.hpp @@ -56,6 +56,7 @@ std::vector shifted_orbitals(uint64_t norb, const std::vector& t std::iota(orbitals.begin(), orbitals.end(), 0); std::vector> values; + values.reserve(target_orbs.size()); for (size_t i = 0; i < target_orbs.size(); ++i) { @@ -66,7 +67,7 @@ std::vector shifted_orbitals(uint64_t norb, const std::vector& t for (const auto& [idx, val] : values) { - orbitals.insert(orbitals.begin() + idx, val); + orbitals.insert(orbitals.begin() + static_cast(idx), val); } return orbitals; @@ -90,6 +91,7 @@ std::vector make_strings(const std::vector& orb_list, size_t ne if (nelec == 1) { std::vector res; + res.reserve(orb_list.size()); for (auto i : orb_list) res.push_back(1LL << i); return res; @@ -131,7 +133,7 @@ std::vector zero_one_subspace_indices(uint64_t norb, size_t nocc, size_t n00 = binomial(norb - 2, nocc); size_t n11 = (nocc >= 2) ? binomial(norb - 2, nocc - 2) : 0; - return std::vector(indices.begin() + n00, indices.end() - n11); + return std::vector(indices.begin() + static_cast(n00), indices.end() - static_cast(n11)); } std::vector one_subspace_indices(uint64_t norb, size_t nocc, @@ -151,7 +153,7 @@ std::vector one_subspace_indices(uint64_t norb, size_t nocc, n0 -= binomial(norb - target_orbs.size(), nocc - target_orbs.size()); } - return std::vector(indices.begin() + n0, indices.end()); + return std::vector(indices.begin() + static_cast(n0), indices.end()); } /** @@ -160,7 +162,7 @@ std::vector one_subspace_indices(uint64_t norb, size_t nocc, * - Spinless: One matrix for both spin-up and spin-down orbitals. * - Spinfull: Separate matrices for spin-up and spin-down orbitals. */ -enum class OrbitalRotationType +enum class OrbitalRotationType : std::uint8_t { Spinless, ///< Shared matrix for both spin components. Spinfull ///< Separate matrices for each spin component. @@ -172,7 +174,7 @@ enum class OrbitalRotationType * - Spinless: One spin sector. * - Spinfull: Two separate spin sectors. */ -enum class ElectronType +enum class ElectronType : std::uint8_t { Spinless, ///< Single spin type. Spinfull, ///< Spin-resolved. @@ -215,13 +217,13 @@ get_givens_decomposition(const OrbitalRotation& mat) else { std::optional, VectorXcd>> decomp_a, decomp_b; - if (mat.spinfull[0].has_value()) + if (const auto& opt_mat_0 = mat.spinfull[0]; opt_mat_0.has_value()) { - decomp_a = linalg::givens_decomposition(mat.spinfull[0].value()); + decomp_a = linalg::givens_decomposition(opt_mat_0.value()); } - if (mat.spinfull[1].has_value()) + if (const auto& opt_mat_1 = mat.spinfull[1]; opt_mat_1.has_value()) { - decomp_b = linalg::givens_decomposition(mat.spinfull[1].value()); + decomp_b = linalg::givens_decomposition(opt_mat_1.value()); } return {decomp_a, decomp_b}; } @@ -231,7 +233,7 @@ void apply_givens_rotation_in_place(MatrixXcd& vec, double c, Complex s, const std::vector& slice1, const std::vector& slice2) { - int dim_b = vec.cols(); + auto dim_b = vec.cols(); double s_abs = std::abs(s); double angle = std::arg(s); Complex phase(std::cos(angle), std::sin(angle)); @@ -241,8 +243,8 @@ void apply_givens_rotation_in_place(MatrixXcd& vec, double c, Complex s, { size_t i = slice1[k]; size_t j = slice2[k]; - VectorXcd row_i = vec.row(i); - VectorXcd row_j = vec.row(j); + VectorXcd row_i = vec.row(static_cast(i)); + VectorXcd row_j = vec.row(static_cast(j)); // altanative method: zscal -> zdrot -> zscal row_i *= phase_conj; @@ -255,8 +257,8 @@ void apply_givens_rotation_in_place(MatrixXcd& vec, double c, Complex s, } row_i *= phase; - vec.row(i) = row_i; - vec.row(j) = row_j; + vec.row(static_cast(i)) = row_i; + vec.row(static_cast(j)) = row_j; } } @@ -270,8 +272,8 @@ void apply_orbital_rotation_adjacent_spin_inplace(MatrixXcd& vec, double c, Comp std::vector indices = one_subspace_indices(norb, nelec, {i, j}); size_t half = indices.size() / 2; - std::vector silce1(indices.begin(), indices.begin() + half); - std::vector slice2(indices.begin() + half, indices.end()); + std::vector silce1(indices.begin(), indices.begin() + static_cast(half)); + std::vector slice2(indices.begin() + static_cast(half), indices.end()); apply_givens_rotation_in_place(vec, c, s, silce1, slice2); } @@ -292,7 +294,7 @@ VectorXcd apply_orbital_rotation_spinless(VectorXcd& vec, const MatrixXcd& mat, for (size_t i = 0; i < phase_shifts.size(); ++i) { auto indices = one_subspace_indices(norb, nelec, {i}); - apply_phase_shift_in_place(reshaped, phase_shifts(i), indices); + apply_phase_shift_in_place(reshaped, phase_shifts(static_cast(i)), indices); } return Map(reshaped.data(), vec.size()); @@ -309,7 +311,7 @@ VectorXcd apply_orbital_rotation_spinfull(VectorXcd& vec, size_t dim_b = binomial(norb, n_beta); MatrixXcd reshaped = vec; - reshaped.resize(dim_a, dim_b); + reshaped.resize(static_cast(dim_a), static_cast(dim_b)); OrbitalRotation rot; rot.type = OrbitalRotationType::Spinfull; @@ -329,7 +331,7 @@ VectorXcd apply_orbital_rotation_spinfull(VectorXcd& vec, for (size_t i = 0; i < phase_shifts_a.size(); ++i) { auto indices = one_subspace_indices(norb, n_alpha, {i}); - apply_phase_shift_in_place(reshaped, phase_shifts_a(i), indices); + apply_phase_shift_in_place(reshaped, phase_shifts_a(static_cast(i)), indices); } } if (decomp_b) @@ -345,7 +347,7 @@ VectorXcd apply_orbital_rotation_spinfull(VectorXcd& vec, for (size_t i = 0; i < phase_shifts_b.size(); ++i) { auto indices = one_subspace_indices(norb, n_beta, {i}); - apply_phase_shift_in_place(transposed, phase_shifts_b(i), indices); + apply_phase_shift_in_place(transposed, phase_shifts_b(static_cast(i)), indices); } reshaped = transposed.transpose(); } @@ -410,6 +412,7 @@ std::vector> gen_occslst(const std::vector& orb_list if (n == 1) { std::vector> res; + res.reserve(list.size()); for (auto i : list) { res.push_back({i}); diff --git a/ffsim/include/ffsim/gates/phase_shift.hpp b/ffsim/include/ffsim/gates/phase_shift.hpp index 20f7680..3d23801 100644 --- a/ffsim/include/ffsim/gates/phase_shift.hpp +++ b/ffsim/include/ffsim/gates/phase_shift.hpp @@ -37,7 +37,7 @@ void apply_phase_shift_in_place(MatrixXcd& mat, const Complex& phase, { for (size_t row : indices) { - mat.row(row) *= phase; + mat.row(static_cast(row)) *= phase; } } diff --git a/ffsim/include/ffsim/linalg/double_factorized_decomp.hpp b/ffsim/include/ffsim/linalg/double_factorized_decomp.hpp index 82e887b..3a0dbdb 100644 --- a/ffsim/include/ffsim/linalg/double_factorized_decomp.hpp +++ b/ffsim/include/ffsim/linalg/double_factorized_decomp.hpp @@ -73,8 +73,8 @@ double_factorized_t2(const Tensor& t2_amplitudes, double tol, { const auto dims = t2_amplitudes.dimensions(); - const int nocc = dims[0]; - const int nvrt = dims[2]; + const int nocc = static_cast(dims[0]); + const int nvrt = static_cast(dims[2]); const int norb = nocc + nvrt; const int n_pairs = nocc * nvrt; @@ -114,14 +114,14 @@ double_factorized_t2(const Tensor& t2_amplitudes, double tol, std::vector indices(eigs.size()); std::iota(indices.begin(), indices.end(), 0); std::sort(indices.begin(), indices.end(), - [&](size_t i, size_t j) { return std::abs(eigs[j]) < std::abs(eigs[i]); }); + [&](size_t i, size_t j) { return std::abs(eigs[static_cast(j)]) < std::abs(eigs[static_cast(i)]); }); VectorXcd eigs_sorted(eigs.size()); MatrixXcd vecs_sorted(vecs.rows(), vecs.cols()); for (size_t i = 0; i < indices.size(); ++i) { - eigs_sorted(i) = eigs(indices[i]); - vecs_sorted.col(i) = vecs.col(indices[i]); + eigs_sorted(static_cast(i)) = eigs(static_cast(indices[i])); + vecs_sorted.col(static_cast(i)) = vecs.col(static_cast(indices[i])); } double acc = 0.0; @@ -142,14 +142,14 @@ double_factorized_t2(const Tensor& t2_amplitudes, double tol, n_vecs = std::min(n_vecs, max_vecs.value()); } - Tensor one_body_tensors(n_vecs, 2, norb, norb); + Tensor one_body_tensors(static_cast(n_vecs), 2, static_cast(norb), static_cast(norb)); one_body_tensors.setZero(); for (size_t k = 0; k < n_vecs; ++k) { MatrixXcd mat = MatrixXcd::Zero(norb, norb); for (int idx = 0; idx < n_pairs; ++idx) { - mat(row[idx], col[idx]) = vecs_sorted(idx, k); + mat(row[idx], col[idx]) = vecs_sorted(idx, static_cast(k)); } MatrixXcd Qp = quadrature(mat, 1); MatrixXcd Qm = quadrature(mat, -1); @@ -158,15 +158,15 @@ double_factorized_t2(const Tensor& t2_amplitudes, double tol, { for (int j = 0; j < norb; ++j) { - one_body_tensors(k, 0, i, j) = Qp(i, j); - one_body_tensors(k, 1, i, j) = Qm(i, j); + one_body_tensors(static_cast(k), 0, i, j) = Qp(i, j); + one_body_tensors(static_cast(k), 1, i, j) = Qm(i, j); } } } - Tensor orbital_rotations(n_vecs, 2, norb, norb); + Tensor orbital_rotations(static_cast(n_vecs), 2, static_cast(norb), static_cast(norb)); orbital_rotations.setZero(); - Tensor eigs_tensor(n_vecs, 2, norb); + Tensor eigs_tensor(static_cast(n_vecs), 2, static_cast(norb)); for (size_t k = 0; k < n_vecs; ++k) { @@ -177,7 +177,7 @@ double_factorized_t2(const Tensor& t2_amplitudes, double tol, { for (int j = 0; j < norb; ++j) { - tensor_mat(i, j) = one_body_tensors(k, s, i, j); + tensor_mat(i, j) = one_body_tensors(static_cast(k), s, i, j); } } @@ -187,20 +187,20 @@ double_factorized_t2(const Tensor& t2_amplitudes, double tol, for (int i = 0; i < norb; ++i) { - eigs_tensor(k, s, i) = evals(i); + eigs_tensor(static_cast(k), s, static_cast(i)) = evals(i); } for (int i = 0; i < norb; ++i) { for (int j = 0; j < norb; ++j) { - orbital_rotations(k, s, i, j) = evecs(i, j); + orbital_rotations(static_cast(k), s, i, j) = evecs(i, j); } } } } - Tensor diag_coulomb(n_vecs, 2, norb, norb); + Tensor diag_coulomb(static_cast(n_vecs), 2, static_cast(norb), static_cast(norb)); for (size_t i = 0; i < n_vecs; ++i) { for (int s = 0; s < 2; ++s) @@ -210,14 +210,14 @@ double_factorized_t2(const Tensor& t2_amplitudes, double tol, { for (int b = 0; b < norb; ++b) { - diag_coulomb(i, s, a, b) = sign_coeff * eigs_tensor(i, s, a) * - eigs_tensor(i, s, b) * eigs_sorted(i).real(); + diag_coulomb(static_cast(i), s, a, b) = sign_coeff * eigs_tensor(static_cast(i), s, a) * + eigs_tensor(static_cast(i), s, b) * eigs_sorted(static_cast(i)).real(); } } } } - Tensor diag_coulomb_out(n_vecs, 2, norb, norb); + Tensor diag_coulomb_out(static_cast(n_vecs), 2, static_cast(norb), static_cast(norb)); diag_coulomb_out.setZero(); for (size_t i = 0; i < n_vecs; ++i) { @@ -227,7 +227,7 @@ double_factorized_t2(const Tensor& t2_amplitudes, double tol, { for (int b = 0; b < norb; ++b) { - diag_coulomb_out(i, s, a, b) = Complex(diag_coulomb(i, s, a, b), 0.0); + diag_coulomb_out(static_cast(i), s, a, b) = Complex(diag_coulomb(static_cast(i), s, a, b), 0.0); } } } diff --git a/ffsim/include/ffsim/linalg/givens.hpp b/ffsim/include/ffsim/linalg/givens.hpp index 796e004..3a2da67 100644 --- a/ffsim/include/ffsim/linalg/givens.hpp +++ b/ffsim/include/ffsim/linalg/givens.hpp @@ -16,6 +16,7 @@ #define GIVENS_HPP #include +#include #include #include @@ -79,7 +80,7 @@ std::tuple zrotg(Complex ca, Complex cb); */ inline void zrot(VectorXcd& x, VectorXcd& y, double c, Complex s) { - int n = std::min(x.size(), y.size()); + int n = static_cast(std::min(x.size(), y.size())); for (int i = 0; i < n; ++i) { Complex temp = c * x[i] + s * y[i]; @@ -105,10 +106,11 @@ struct GivensRotation * @brief Constructs a Givens rotation object. * @param c Cosine coefficient * @param s Sine coefficient - * @param i First index involved - * @param j Second index involved + * @param first_index First index involved + * @param second_index Second index involved */ - GivensRotation(double c, Complex s, size_t i, size_t j) : c(c), s(s), i(i), j(j) {} + GivensRotation(double c, Complex s, size_t first_index, size_t second_index) : c(c), s(s), i(first_index), j(second_index) { + } }; /** @@ -130,7 +132,7 @@ struct GivensRotation std::pair, VectorXcd> givens_decomposition(const MatrixXcd& mat) { - int n = mat.rows(); + int n = static_cast(mat.rows()); MatrixXcd current_matrix = mat; std::vector left_rotations; @@ -184,23 +186,23 @@ std::pair, VectorXcd> givens_decomposition(const Mat for (const auto& rot : left_rotations) { double c = rot.c; - Complex s = std::conj(rot.s) * current_matrix(rot.i, rot.i); - auto [new_c, new_s, _] = zrotg(c * current_matrix(rot.j, rot.j), s); + Complex s = std::conj(rot.s) * current_matrix(static_cast(rot.i), static_cast(rot.i)); + auto [new_c, new_s, _] = zrotg(c * current_matrix(static_cast(rot.j), static_cast(rot.j)), s); right_rotations.emplace_back(new_c, -std::conj(new_s), rot.i, rot.j); Matrix2cd givens_mat; givens_mat << new_c, -new_s, std::conj(new_s), new_c; - givens_mat(0, 0) *= current_matrix(rot.i, rot.i); - givens_mat(1, 0) *= current_matrix(rot.i, rot.i); - givens_mat(0, 1) *= current_matrix(rot.j, rot.j); - givens_mat(1, 1) *= current_matrix(rot.j, rot.j); + givens_mat(0, 0) *= current_matrix(static_cast(rot.i), static_cast(rot.i)); + givens_mat(1, 0) *= current_matrix(static_cast(rot.i), static_cast(rot.i)); + givens_mat(0, 1) *= current_matrix(static_cast(rot.j), static_cast(rot.j)); + givens_mat(1, 1) *= current_matrix(static_cast(rot.j), static_cast(rot.j)); auto [c2, s2, _2] = zrotg(givens_mat(1, 1), givens_mat(1, 0)); Matrix2cd givens_mat2; givens_mat2 << c2, s2, -std::conj(s2), c2; Matrix2cd final_mat = givens_mat * givens_mat2; - current_matrix(rot.i, rot.i) = final_mat(0, 0); - current_matrix(rot.j, rot.j) = final_mat(1, 1); + current_matrix(static_cast(rot.i), static_cast(rot.i)) = final_mat(0, 0); + current_matrix(static_cast(rot.j), static_cast(rot.j)) = final_mat(1, 1); } return {right_rotations, current_matrix.diagonal()}; } diff --git a/ffsim/include/ffsim/orbital_rotation_jw.hpp b/ffsim/include/ffsim/orbital_rotation_jw.hpp index cec2772..351ac3e 100644 --- a/ffsim/include/ffsim/orbital_rotation_jw.hpp +++ b/ffsim/include/ffsim/orbital_rotation_jw.hpp @@ -56,7 +56,7 @@ std::vector orbital_rotation_jw(const std::vector& for (size_t i = 0; i < phase_shifts.size(); ++i) { - double theta = std::arg(phase_shifts(i)); + double theta = std::arg(phase_shifts(static_cast(i))); instructions.push_back( {"rz", {static_cast(qubits[i])}, {}, std::vector{theta}}); } @@ -100,9 +100,9 @@ class OrbitalRotationJW else { orbital_rotation_a = - orbital_rotation.spinfull[0].value_or(MatrixXcd::Identity(norb, norb)); + orbital_rotation.spinfull[0].value_or(MatrixXcd::Identity(static_cast(norb), static_cast(norb))); orbital_rotation_b = - orbital_rotation.spinfull[1].value_or(MatrixXcd::Identity(norb, norb)); + orbital_rotation.spinfull[1].value_or(MatrixXcd::Identity(static_cast(norb), static_cast(norb))); } } @@ -115,7 +115,7 @@ class OrbitalRotationJW */ std::vector instructions(const std::vector& qubits) const { - uint64_t norb_tmp = qubits.size() / 2; + auto norb_tmp = static_cast(qubits.size() / 2); std::vector alpha_qubits(qubits.begin(), qubits.begin() + norb_tmp); std::vector beta_qubits(qubits.begin() + norb_tmp, qubits.end()); diff --git a/ffsim/include/ffsim/random_unitary.hpp b/ffsim/include/ffsim/random_unitary.hpp index 1a63405..f757542 100644 --- a/ffsim/include/ffsim/random_unitary.hpp +++ b/ffsim/include/ffsim/random_unitary.hpp @@ -16,9 +16,13 @@ #define RANDOM_UNITARY_HPP #include +#include +#include namespace ffsim { +using namespace Eigen; +using Complex = std::complex; /** * @brief Generates a random unitary matrix of size N x N. @@ -29,7 +33,7 @@ namespace ffsim * @param N The size of the unitary matrix. * @return A random unitary matrix of size N x N. */ -Eigen::MatrixXcd random_unitary(int N) +MatrixXcd random_unitary(int N) { std::random_device rd; std::mt19937 gen(rd()); diff --git a/ffsim/include/ffsim/slater_determinant.hpp b/ffsim/include/ffsim/slater_determinant.hpp index 5c44397..b23874a 100644 --- a/ffsim/include/ffsim/slater_determinant.hpp +++ b/ffsim/include/ffsim/slater_determinant.hpp @@ -67,9 +67,9 @@ std::vector givens_decomposition_slater(const MatrixXcd& orbital { for (int j = static_cast(n - m + i); j > static_cast(i); --j) { - if (std::norm(mat(i, j)) > 0.0) + if (std::norm(mat(static_cast(i), static_cast(j))) > 0.0) { - auto [c, s, _] = zrotg(mat(i, j - 1), mat(i, j)); + auto [c, s, _] = zrotg(mat(static_cast(i), static_cast(j - 1)), mat(static_cast(i), static_cast(j))); rotations.emplace_back(c, s, j, j - 1); VectorXcd col1 = mat.col(j - 1).transpose(); VectorXcd col2 = mat.col(j).transpose(); @@ -100,6 +100,8 @@ std::vector prepare_slater_determinant_jw(const std::vector< size_t m = orbital_coeffs.rows(); size_t n = orbital_coeffs.cols(); + instructions.reserve(m); + for (size_t i = 0; i < m; ++i) { instructions.push_back({"x", {static_cast(qubits[i])}, {}, {}}); @@ -170,15 +172,15 @@ class PrepareSlaterDeterminantJW else { orbital_rotation_a_ = - orbital_rotation.value().spinfull[0].value_or(MatrixXcd::Identity(norb, norb)); + orbital_rotation.value().spinfull[0].value_or(MatrixXcd::Identity(static_cast(norb), static_cast(norb))); orbital_rotation_b_ = - orbital_rotation.value().spinfull[1].value_or(MatrixXcd::Identity(norb, norb)); + orbital_rotation.value().spinfull[1].value_or(MatrixXcd::Identity(static_cast(norb), static_cast(norb))); } } else { - orbital_rotation_a_ = MatrixXcd::Identity(norb, norb); - orbital_rotation_b_ = MatrixXcd::Identity(norb, norb); + orbital_rotation_a_ = MatrixXcd::Identity(static_cast(norb), static_cast(norb)); + orbital_rotation_b_ = MatrixXcd::Identity(static_cast(norb), static_cast(norb)); } } @@ -190,12 +192,12 @@ class PrepareSlaterDeterminantJW std::vector instructions() const { uint64_t norb = qubits.size() / 2; - std::vector alpha_qubits(qubits.begin(), qubits.begin() + norb); - std::vector beta_qubits(qubits.begin() + norb, qubits.end()); + std::vector alpha_qubits(qubits.begin(), qubits.begin() + static_cast(norb)); + std::vector beta_qubits(qubits.begin() + static_cast(norb), qubits.end()); std::vector instructions; const auto& occ_a = occupied_orbitals.first; const auto& occ_b = occupied_orbitals.second; - if (orbital_rotation_a_.isApprox(MatrixXcd::Identity(norb, norb), 1e-12)) + if (orbital_rotation_a_.isApprox(MatrixXcd::Identity(static_cast(norb), static_cast(norb)), 1e-12)) { for (auto a : occ_a) { @@ -208,7 +210,7 @@ class PrepareSlaterDeterminantJW auto slater_instr_a = prepare_slater_determinant_jw(alpha_qubits, orb_a_t); instructions.insert(instructions.end(), slater_instr_a.begin(), slater_instr_a.end()); } - if (orbital_rotation_b_.isApprox(MatrixXcd::Identity(norb, norb), 1e-12)) + if (orbital_rotation_b_.isApprox(MatrixXcd::Identity(static_cast(norb), static_cast(norb)), 1e-12)) { for (auto b : occ_b) { diff --git a/ffsim/include/ffsim/ucj.hpp b/ffsim/include/ffsim/ucj.hpp index 2efab4b..85f221c 100644 --- a/ffsim/include/ffsim/ucj.hpp +++ b/ffsim/include/ffsim/ucj.hpp @@ -59,7 +59,7 @@ slater_determinant_instruction(const std::vector& qubits, const size_t size_t nela = nelec.first; - MatrixXcd Kmat = MatrixXcd::Zero(norb, norb); + MatrixXcd Kmat = MatrixXcd::Zero(static_cast(norb), static_cast(norb)); int idx = 0; for (int i = 0; i < nela; ++i) { @@ -68,7 +68,7 @@ slater_determinant_instruction(const std::vector& qubits, const size_t double real_part = params(idx++).real(); double imag_part = params(idx++).real(); // assume params are all real std::complex val(real_part, imag_part); - Kmat(i, j + nela) = val; + Kmat(static_cast(i), static_cast(j + nela)) = val; } } @@ -257,7 +257,7 @@ hf_and_ucj_op_spin_balanced_jw(const std::vector& qubits, { for (uint64_t j = 0; j < norb; ++j) { - orbital_rotation(i, j) = + orbital_rotation(static_cast(i), static_cast(j)) = std::conj(ucj_op.orbital_rotations(0, static_cast(j), static_cast(i))); } } diff --git a/ffsim/include/ffsim/ucjop_spinbalanced.hpp b/ffsim/include/ffsim/ucjop_spinbalanced.hpp index 02fe157..714b1f3 100644 --- a/ffsim/include/ffsim/ucjop_spinbalanced.hpp +++ b/ffsim/include/ffsim/ucjop_spinbalanced.hpp @@ -183,10 +183,14 @@ struct UCJOpSpinBalanced validate_interaction_pairs(interaction_pairs[1], false); size_t n_triu = norb * (norb + 1) / 2; - size_t n_params_aa = - interaction_pairs[0].has_value() ? interaction_pairs[0]->size() : n_triu; - size_t n_params_ab = - interaction_pairs[1].has_value() ? interaction_pairs[1]->size() : n_triu; + size_t n_params_aa = n_triu; + if (const auto& pairs_aa_opt = interaction_pairs[0]; pairs_aa_opt.has_value()) { + n_params_aa = pairs_aa_opt.value().size(); + } + size_t n_params_ab = n_triu; + if (const auto& pairs_ab_opt = interaction_pairs[1]; pairs_ab_opt.has_value()) { + n_params_ab = pairs_ab_opt.value().size(); + } return n_reps * (n_params_aa + n_params_ab + norb * norb) + (with_final_orbital_rotation ? norb * norb : 0); @@ -239,13 +243,13 @@ struct UCJOpSpinBalanced for (size_t rep = 0; rep < n_reps; ++rep) { MatrixXcd orbital_rotation = - orbital_rotation_from_parameters(params.segment(index, norb * norb), norb, false); + orbital_rotation_from_parameters(params.segment(static_cast(index), static_cast(norb * norb)), static_cast(norb), false); index += norb * norb; for (int i = 0; i < norb; ++i) { for (int j = 0; j < norb; ++j) { - orbital_rotations(rep, i, j) = orbital_rotation(i, j); + orbital_rotations(static_cast(rep), i, j) = orbital_rotation(i, j); } } for (int t = 0; t < 2; ++t) @@ -253,9 +257,9 @@ struct UCJOpSpinBalanced const auto& pairs = (t == 0) ? pairs_aa : pairs_ab; for (const auto& [i, j] : pairs) { - Complex val = params(index++); - diag_coulomb_mats(rep, t, static_cast(i), static_cast(j)) = val; - diag_coulomb_mats(rep, t, static_cast(j), static_cast(i)) = val; + Complex val = params(static_cast(index++)); + diag_coulomb_mats(static_cast(rep), t, static_cast(i), static_cast(j)) = val; + diag_coulomb_mats(static_cast(rep), t, static_cast(j), static_cast(i)) = val; } } } @@ -265,7 +269,7 @@ struct UCJOpSpinBalanced if (with_final_orbital_rotation) { final_orbital_rotation = - orbital_rotation_from_parameters(params.segment(index, norb * norb), norb, false); + orbital_rotation_from_parameters(params.segment(static_cast(index), static_cast(norb * norb)), static_cast(norb), false); } return UCJOpSpinBalanced(diag_coulomb_mats, orbital_rotations, final_orbital_rotation, true, @@ -309,7 +313,7 @@ struct UCJOpSpinBalanced orb_rot(i, j) = orbital_rotations(rep, i, j); } } - params.segment(index, norb * norb) = orbital_rotation_to_parameters(orb_rot, false); + params.segment(static_cast(index), static_cast(norb * norb)) = orbital_rotation_to_parameters(orb_rot, false); index += norb * norb; for (int t = 0; t < 2; ++t) @@ -317,7 +321,7 @@ struct UCJOpSpinBalanced const auto& pairs = (t == 0) ? pairs_aa : pairs_ab; for (const auto& [i, j] : pairs) { - params(index++) = + params(static_cast(index++)) = diag_coulomb_mats(rep, t, static_cast(i), static_cast(j)); } } @@ -325,7 +329,7 @@ struct UCJOpSpinBalanced if (final_orbital_rotation) { - params.segment(index, norb * norb) = + params.segment(static_cast(index), static_cast(norb * norb)) = orbital_rotation_to_parameters(final_orbital_rotation.value(), false); } @@ -359,10 +363,10 @@ struct UCJOpSpinBalanced linalg::double_factorized_t2(t2, tol, std::nullopt); size_t n_vecs = diag_coulomb_mats.size() / (norb * norb); size_t orb_vecs = orbital_rotations.size() / (norb * norb); - Eigen::DSizes diag_shape_3d(n_vecs, static_cast(norb), - static_cast(norb)); - Eigen::DSizes orb_shape_3d(orb_vecs, static_cast(norb), - static_cast(norb)); + Eigen::DSizes diag_shape_3d(static_cast(n_vecs), static_cast(norb), + static_cast(norb)); + Eigen::DSizes orb_shape_3d(static_cast(orb_vecs), static_cast(norb), + static_cast(norb)); Tensor diag_coulomb_mats_reshaped = diag_coulomb_mats.reshape(diag_shape_3d); Tensor orbital_rotations_reshaped = orbital_rotations.reshape(orb_shape_3d); @@ -410,13 +414,13 @@ struct UCJOpSpinBalanced if (n_reps.has_value() && n_vecs < n_reps.value()) { size_t pad = n_reps.value() - n_vecs; - Tensor diag_coulomb_mats_pad(pad, 2, static_cast(norb), + Tensor diag_coulomb_mats_pad(static_cast(pad), 2, static_cast(norb), static_cast(norb)); diag_coulomb_mats_pad.setZero(); diag_coulomb_mats_stacked = diag_coulomb_mats_stacked.concatenate(diag_coulomb_mats_pad, 0); - Tensor orbital_rotations_pad(pad, static_cast(norb), + Tensor orbital_rotations_pad(static_cast(pad), static_cast(norb), static_cast(norb)); orbital_rotations_pad.setZero(); for (int p = 0; p < pad; ++p) @@ -433,10 +437,10 @@ struct UCJOpSpinBalanced std::optional final_orbital_rotation = std::nullopt; if (t1.has_value()) { - MatrixXcd t1_mat = t1.value(); - MatrixXcd final_orbital_rotation_generator = MatrixXcd::Zero(norb, norb); - final_orbital_rotation_generator.block(0, nocc, nocc, nvrt) = t1_mat; - final_orbital_rotation_generator.block(nocc, 0, nvrt, nocc) = -t1_mat.adjoint(); + const MatrixXcd& t1_mat = t1.value(); + MatrixXcd final_orbital_rotation_generator = MatrixXcd::Zero(static_cast(norb), static_cast(norb)); + final_orbital_rotation_generator.block(0, static_cast(nocc), static_cast(nocc), static_cast(nvrt)) = t1_mat; + final_orbital_rotation_generator.block(static_cast(nocc), 0, static_cast(nvrt), static_cast(nocc)) = -t1_mat.adjoint(); final_orbital_rotation = linalg::expm(final_orbital_rotation_generator); } @@ -463,7 +467,7 @@ struct UCJOpSpinBalanced { if (!mask[i][j]) { - tensor(v, index, i, j) = Complex(0.0, 0.0); + tensor(v, static_cast(index), i, j) = Complex(0.0, 0.0); } } } diff --git a/ffsim/include/ffsim/utils.hpp b/ffsim/include/ffsim/utils.hpp index 95696dd..16a39ed 100644 --- a/ffsim/include/ffsim/utils.hpp +++ b/ffsim/include/ffsim/utils.hpp @@ -55,7 +55,7 @@ VectorXd orbital_rotation_to_parameters(const MatrixXcd& orbital_rotation, bool } } - int norb = orbital_rotation.rows(); + int norb = static_cast(orbital_rotation.rows()); std::vector> triu_indices_no_diag; for (int i = 0; i < norb; ++i) @@ -73,7 +73,7 @@ VectorXd orbital_rotation_to_parameters(const MatrixXcd& orbital_rotation, bool for (size_t idx = 0; idx < triu_indices_no_diag.size(); ++idx) { auto [i, j] = triu_indices_no_diag[idx]; - params(idx) = mat(i, j).real(); + params(static_cast(idx)) = mat(static_cast(i), static_cast(j)).real(); } if (!real) @@ -89,7 +89,7 @@ VectorXd orbital_rotation_to_parameters(const MatrixXcd& orbital_rotation, bool for (size_t idx = 0; idx < triu_indices.size(); ++idx) { auto [i, j] = triu_indices[idx]; - params(idx + triu_indices_no_diag.size()) = mat(i, j).imag(); + params(static_cast(idx + triu_indices_no_diag.size())) = mat(static_cast(i), static_cast(j)).imag(); } } @@ -131,18 +131,18 @@ MatrixXcd orbital_rotation_from_parameters(const VectorXcd& params, int norb, bo for (size_t idx = 0; idx < triu_indices.size(); ++idx) { auto [i, j] = triu_indices[idx]; - Complex imag_param_val = params[idx + triu_indices_no_diag.size()]; - generator(i, j) = Complex(0.0, imag_param_val.real()); - generator(j, i) = Complex(0.0, imag_param_val.real()); + Complex imag_param_val = params[static_cast(idx + triu_indices_no_diag.size())]; + generator(static_cast(i), static_cast(j)) = Complex(0.0, imag_param_val.real()); + generator(static_cast(j), static_cast(i)) = Complex(0.0, imag_param_val.real()); } } for (size_t idx = 0; idx < triu_indices_no_diag.size(); ++idx) { auto [i, j] = triu_indices_no_diag[idx]; - Complex param_val = params[idx]; - generator(i, j) += Complex(param_val.real(), 0.0); - generator(j, i) -= Complex(param_val.real(), 0.0); + Complex param_val = params[static_cast(idx)]; + generator(static_cast(i), static_cast(j)) += Complex(param_val.real(), 0.0); + generator(static_cast(j), static_cast(i)) -= Complex(param_val.real(), 0.0); } return linalg::expm(generator); }; @@ -190,15 +190,21 @@ void validate_orbital_rotation(const OrbitalRotation& mat, double rtol, double a } else { - if (mat.spinfull[0].has_value() && !linalg::is_unitary(mat.spinfull[0].value(), rtol, atol)) + if (const auto& matrix0_opt = mat.spinfull[0]; matrix0_opt.has_value()) { - throw std::runtime_error( - "The input orbital rotation matrix for spin alpha was not unitary."); + if (!linalg::is_unitary(matrix0_opt.value(), rtol, atol)) + { + throw std::runtime_error( + "The input orbital rotation matrix for spin alpha was not unitary."); + } } - if (mat.spinfull[1].has_value() && !linalg::is_unitary(mat.spinfull[1].value(), rtol, atol)) + if (const auto& matrix1_opt = mat.spinfull[1]; matrix1_opt.has_value()) { - throw std::runtime_error( - "The input orbital rotation matrix for spin beta was not unitary."); + if (!linalg::is_unitary(matrix1_opt.value(), rtol, atol)) + { + throw std::runtime_error( + "The input orbital rotation matrix for spin beta was not unitary."); + } } } } diff --git a/src/main.cpp b/src/main.cpp index 1e5aeb7..e72a206 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -188,7 +188,7 @@ int main(int argc, char* argv[]) { try { - // ===== MPI initialization ===== + // ===== MPI initialization ===== // This workflow assumes MPI. Request FUNNELED (only main thread calls MPI). int provided; int mpi_init_error = MPI_Init_thread(&argc, &argv, MPI_THREAD_FUNNELED, &provided); From 8a79e918116d560ed4d0e28b6ba73939f2183144 Mon Sep 17 00:00:00 2001 From: to24toro Date: Sun, 28 Sep 2025 23:49:02 +0900 Subject: [PATCH 04/25] format again --- .clang-format | 295 ++++++++++- ffsim/include/ffsim/circuit_instruction.hpp | 3 +- ffsim/include/ffsim/diag_coulomb_jw.hpp | 220 +++++--- ffsim/include/ffsim/linalg/givens.hpp | 4 +- ffsim/include/ffsim/orbital_rotation_jw.hpp | 67 ++- ffsim/include/ffsim/random_unitary.hpp | 6 +- ffsim/include/ffsim/slater_determinant.hpp | 172 +++--- ffsim/include/ffsim/ucj.hpp | 174 +++--- ffsim/include/ffsim/ucjop_spinbalanced.hpp | 421 ++++++++------- ffsim/include/ffsim/utils.hpp | 136 +++-- src/load_parameters.hpp | 45 +- src/main.cpp | 560 ++++++++++---------- src/sbd_helper.hpp | 121 +++-- src/sqd_helper.hpp | 222 ++++---- 14 files changed, 1441 insertions(+), 1005 deletions(-) diff --git a/.clang-format b/.clang-format index 53f519d..2f7655b 100644 --- a/.clang-format +++ b/.clang-format @@ -1,7 +1,288 @@ -BasedOnStyle: LLVM -IndentWidth: 4 -ColumnLimit: 100 -BreakBeforeBraces: Allman -AllowShortIfStatementsOnASingleLine: false -PointerAlignment: Left -SortIncludes: true \ No newline at end of file +--- +Language: Cpp +AccessModifierOffset: -2 +AlignAfterOpenBracket: BlockIndent +AlignArrayOfStructures: None +AlignConsecutiveAssignments: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionDeclarations: false + AlignFunctionPointers: false + PadOperators: true +AlignConsecutiveBitFields: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionDeclarations: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveDeclarations: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionDeclarations: true + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveMacros: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionDeclarations: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveShortCaseStatements: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCaseArrows: false + AlignCaseColons: false +AlignConsecutiveTableGenBreakingDAGArgColons: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionDeclarations: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveTableGenCondOperatorColons: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionDeclarations: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveTableGenDefinitionColons: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionDeclarations: false + AlignFunctionPointers: false + PadOperators: false +AlignEscapedNewlines: Right +AlignOperands: Align +AlignTrailingComments: + Kind: Always + OverEmptyLines: 0 +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowBreakBeforeNoexceptSpecifier: Never +AllowShortBlocksOnASingleLine: Never +AllowShortCaseExpressionOnASingleLine: true +AllowShortCaseLabelsOnASingleLine: false +AllowShortCompoundRequirementOnASingleLine: true +AllowShortEnumsOnASingleLine: true +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: None +AllowShortLoopsOnASingleLine: false +AllowShortNamespacesOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AttributeMacros: + - __capability +BinPackArguments: true +BinPackParameters: BinPack +BitFieldColonSpacing: Both +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterExternBlock: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakAdjacentStringLiterals: true +BreakAfterAttributes: Leave +BreakAfterJavaFieldAnnotations: false +BreakAfterReturnType: None +BreakArrays: true +BreakBeforeBinaryOperators: None +BreakBeforeConceptDeclarations: Always +BreakBeforeBraces: Linux +BreakBeforeInlineASMColon: OnlyMultiline +BreakBeforeTernaryOperators: true +BreakBinaryOperations: Never +BreakConstructorInitializers: BeforeColon +BreakFunctionDefinitionParameters: false +BreakInheritanceList: BeforeColon +BreakStringLiterals: true +BreakTemplateDeclarations: Yes +ColumnLimit: 88 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerIndentWidth: 2 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IfMacros: + - KJ_IF_MAYBE +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + CaseSensitive: false + - Regex: '.*' + Priority: 1 + SortPriority: 0 + CaseSensitive: false +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentAccessModifiers: false +IndentCaseBlocks: false +IndentCaseLabels: false +IndentExportBlock: true +IndentExternBlock: AfterExternBlock +IndentGotoLabels: true +IndentPPDirectives: None +IndentRequiresClause: true +IndentWidth: 4 +IndentWrappedFunctionNames: false +InsertBraces: false +InsertNewlineAtEOF: false +InsertTrailingCommas: None +IntegerLiteralSeparator: + Binary: 0 + BinaryMinDigits: 0 + Decimal: 0 + DecimalMinDigits: 0 + Hex: 0 + HexMinDigits: 0 +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLines: + AtEndOfFile: false + AtStartOfBlock: true + AtStartOfFile: true +KeepFormFeed: false +LambdaBodyIndentation: Signature +LineEnding: DeriveLF +MacroBlockBegin: '' +MacroBlockEnd: '' +MainIncludeChar: Quote +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 4 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PackConstructorInitializers: BinPack +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakBeforeMemberAccess: 150 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakOpenParenthesis: 0 +PenaltyBreakScopeResolution: 500 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyIndentedWhitespace: 0 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Right +PPIndentWidth: -1 +QualifierAlignment: Leave +ReferenceAlignment: Pointer +ReflowComments: Always +RemoveBracesLLVM: false +RemoveEmptyLinesInUnwrappedLines: false +RemoveParentheses: Leave +RemoveSemicolon: false +RequiresClausePosition: OwnLine +RequiresExpressionIndentation: OuterScope +SeparateDefinitionBlocks: Leave +ShortNamespaceLines: 1 +SkipMacroDefinitionBody: false +SortIncludes: CaseSensitive +SortJavaStaticImport: Before +SortUsingDeclarations: LexicographicNumeric +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceAroundPointerQualifiers: Default +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeJsonColon: false +SpaceBeforeParens: ControlStatements +SpaceBeforeParensOptions: + AfterControlStatements: true + AfterForeachMacros: true + AfterFunctionDefinitionName: false + AfterFunctionDeclarationName: false + AfterIfMacros: true + AfterOverloadedOperator: false + AfterPlacementOperator: true + AfterRequiresInClause: false + AfterRequiresInExpression: false + BeforeNonEmptyParentheses: false +SpaceBeforeRangeBasedForLoopColon: true +SpaceBeforeSquareBrackets: false +SpaceInEmptyBlock: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: Never +SpacesInContainerLiterals: true +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: -1 +SpacesInParens: Never +SpacesInParensOptions: + ExceptDoubleParentheses: false + InCStyleCasts: false + InConditionalStatements: false + InEmptyParentheses: false + Other: false +SpacesInSquareBrackets: false +Standard: Latest +StatementAttributeLikeMacros: + - Q_EMIT +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TableGenBreakInsideDAGArg: DontBreak +TabWidth: 8 +UseTab: Never +VerilogBreakBetweenInstancePorts: true +WhitespaceSensitiveMacros: + - BOOST_PP_STRINGIZE + - CF_SWIFT_NAME + - NS_SWIFT_NAME + - PP_STRINGIZE + - STRINGIZE +WrapNamespaceBodyWithEmptyLines: Leave +... + diff --git a/ffsim/include/ffsim/circuit_instruction.hpp b/ffsim/include/ffsim/circuit_instruction.hpp index d67218f..d4c74f6 100644 --- a/ffsim/include/ffsim/circuit_instruction.hpp +++ b/ffsim/include/ffsim/circuit_instruction.hpp @@ -34,8 +34,7 @@ namespace ffsim * @param params Parameters associated with the gate. * @return A CircuitInstruction object representing the gate operation. */ -struct CircuitInstruction -{ +struct CircuitInstruction { std::string gate; std::vector qubits; std::optional> clbits; diff --git a/ffsim/include/ffsim/diag_coulomb_jw.hpp b/ffsim/include/ffsim/diag_coulomb_jw.hpp index 79fee5e..668d4bb 100644 --- a/ffsim/include/ffsim/diag_coulomb_jw.hpp +++ b/ffsim/include/ffsim/diag_coulomb_jw.hpp @@ -36,9 +36,9 @@ using namespace gates; class DiagCoulombEvolutionJW { public: - uint64_t norb; ///< Number of orbitals - Mat mat; ///< Representation of the Coulomb matrix (single or triple form) - double time; ///< Time evolution parameter + uint64_t norb; ///< Number of orbitals + Mat mat; ///< Representation of the Coulomb matrix (single or triple form) + double time; ///< Time evolution parameter bool z_representation; ///< Whether to use the Z basis (Pauli-Z representation) /** @@ -49,8 +49,10 @@ class DiagCoulombEvolutionJW * @param time Time evolution parameter * @param z_representation Whether to use Z-basis representation */ - DiagCoulombEvolutionJW(uint64_t norb, const Mat& mat, double time, bool z_representation) - : norb(norb), mat(mat), time(time), z_representation(z_representation) + DiagCoulombEvolutionJW( + uint64_t norb, const Mat &mat, double time, bool z_representation + ) + : norb(norb), mat(mat), time(time), z_representation(z_representation) { } @@ -66,14 +68,12 @@ class DiagCoulombEvolutionJW * orbitals) * @return Vector of circuit instructions */ - std::vector instructions(const std::vector& qubits) const + std::vector + instructions(const std::vector &qubits) const { - if (z_representation) - { + if (z_representation) { return diag_coulomb_evolution_z_rep_jw(qubits); - } - else - { + } else { return diag_coulomb_evolution_num_rep_jw(qubits); } } @@ -87,83 +87,135 @@ class DiagCoulombEvolutionJW * @return Quantum circuit as vector of circuit instructions */ std::vector - diag_coulomb_evolution_num_rep_jw(const std::vector& qubits) const + diag_coulomb_evolution_num_rep_jw(const std::vector &qubits) const { std::vector instructions; - auto [mat_aa, mat_ab, mat_bb] = [&]() - { - if (mat.type == MatType::Single) - { + auto [mat_aa, mat_ab, mat_bb] = [&]() { + if (mat.type == MatType::Single) { return std::make_tuple(mat.single, mat.single, mat.single); - } - else - { - return std::make_tuple(mat.triple[0].value_or(MatrixXcd::Zero(static_cast(norb), static_cast(norb))), - mat.triple[1].value_or(MatrixXcd::Zero(static_cast(norb), static_cast(norb))), - mat.triple[2].value_or(MatrixXcd::Zero(static_cast(norb), static_cast(norb)))); + } else { + return std::make_tuple( + mat.triple[0].value_or( + MatrixXcd::Zero( + static_cast(norb), + static_cast(norb) + ) + ), + mat.triple[1].value_or( + MatrixXcd::Zero( + static_cast(norb), + static_cast(norb) + ) + ), + mat.triple[2].value_or( + MatrixXcd::Zero( + static_cast(norb), + static_cast(norb) + ) + ) + ); } }(); - for (int sigma = 0; sigma < 2; ++sigma) - { - const auto& this_mat = (sigma == 0) ? mat_aa : mat_bb; - for (size_t i = 0; i < norb; ++i) - { - if (std::abs(this_mat(static_cast(i), static_cast(i)).real()) > 1e-12 || - std::abs(this_mat(static_cast(i), static_cast(i)).imag()) > 1e-12) - { + for (int sigma = 0; sigma < 2; ++sigma) { + const auto &this_mat = (sigma == 0) ? mat_aa : mat_bb; + for (size_t i = 0; i < norb; ++i) { + if (std::abs( + this_mat(static_cast(i), static_cast(i)).real() + ) > 1e-12 || + std::abs( + this_mat(static_cast(i), static_cast(i)).imag() + ) > 1e-12) { instructions.push_back( {"rz", {static_cast(qubits[i + sigma * norb])}, {}, - std::vector{-0.5 * this_mat(static_cast(i), static_cast(i)).real() * time}}); + std::vector{ + -0.5 * + this_mat(static_cast(i), static_cast(i)) + .real() * + time + }} + ); } - for (size_t j = i + 1; j < norb; ++j) - { - if (std::abs(this_mat(static_cast(i), static_cast(j)).real()) > 1e-12 || - std::abs(this_mat(static_cast(i), static_cast(j)).imag()) > 1e-12) - { + for (size_t j = i + 1; j < norb; ++j) { + if (std::abs(this_mat(static_cast(i), static_cast(j)) + .real()) > 1e-12 || + std::abs(this_mat(static_cast(i), static_cast(j)) + .imag()) > 1e-12) { instructions.push_back( {"cp", {static_cast(qubits[i + sigma * norb]), static_cast(qubits[j + sigma * norb])}, {}, - std::vector{-1.0 * this_mat(static_cast(i), static_cast(j)).real() * time}}); + std::vector{ + -1.0 * + this_mat(static_cast(i), static_cast(j)) + .real() * + time + }} + ); } } } } - for (size_t i = 0; i < norb; ++i) - { - if (std::abs(mat_ab(static_cast(i), static_cast(i)).real()) > 1e-12 || std::abs(mat_ab(static_cast(i), static_cast(i)).imag()) > 1e-12) - { - instructions.push_back({"cp", - {static_cast(qubits[i]), - static_cast(qubits[i + norb])}, - {}, - std::vector{-1.0 * mat_ab(static_cast(i), static_cast(i)).real() * time}}); + for (size_t i = 0; i < norb; ++i) { + if (std::abs(mat_ab(static_cast(i), static_cast(i)).real()) > + 1e-12 || + std::abs(mat_ab(static_cast(i), static_cast(i)).imag()) > + 1e-12) { + instructions.push_back( + {"cp", + {static_cast(qubits[i]), + static_cast(qubits[i + norb])}, + {}, + std::vector{ + -1.0 * + mat_ab(static_cast(i), static_cast(i)).real() * + time + }} + ); } - for (size_t j = i + 1; j < norb; ++j) - { - if (std::abs(mat_ab(static_cast(i), static_cast(j)).real()) > 1e-12 || std::abs(mat_ab(static_cast(i), static_cast(j)).imag()) > 1e-12) - { + for (size_t j = i + 1; j < norb; ++j) { + if (std::abs( + mat_ab(static_cast(i), static_cast(j)).real() + ) > 1e-12 || + std::abs( + mat_ab(static_cast(i), static_cast(j)).imag() + ) > 1e-12) { instructions.push_back( {"cp", {static_cast(qubits[i]), static_cast(qubits[j + norb])}, {}, - std::vector{-1.0 * mat_ab(static_cast(i), static_cast(j)).real() * time}}); + std::vector{ + -1.0 * + mat_ab(static_cast(i), static_cast(j)) + .real() * + time + }} + ); } - if (std::abs(mat_ab(static_cast(j), static_cast(i)).real()) > 1e-12 || std::abs(mat_ab(static_cast(j), static_cast(i)).imag()) > 1e-12) - { + if (std::abs( + mat_ab(static_cast(j), static_cast(i)).real() + ) > 1e-12 || + std::abs( + mat_ab(static_cast(j), static_cast(i)).imag() + ) > 1e-12) { instructions.push_back( {"cp", {static_cast(qubits[j]), static_cast(qubits[i + norb])}, {}, - std::vector{-1.0 * mat_ab(static_cast(j), static_cast(i)).real() * time}}); + std::vector{ + -1.0 * + mat_ab(static_cast(j), static_cast(i)) + .real() * + time + }} + ); } } } @@ -176,39 +228,53 @@ class DiagCoulombEvolutionJW * @return Quantum circuit as vector of circuit instructions */ std::vector - diag_coulomb_evolution_z_rep_jw(const std::vector& qubits) const + diag_coulomb_evolution_z_rep_jw(const std::vector &qubits) const { - auto [mat_aa, mat_ab, mat_bb] = [&]() - { - if (mat.type == MatType::Single) - { + auto [mat_aa, mat_ab, mat_bb] = [&]() { + if (mat.type == MatType::Single) { return std::make_tuple(mat.single, mat.single, mat.single); - } - else - { - return std::make_tuple(mat.triple[0].value_or(MatrixXcd::Zero(static_cast(norb), static_cast(norb))), - mat.triple[1].value_or(MatrixXcd::Zero(static_cast(norb), static_cast(norb))), - mat.triple[2].value_or(MatrixXcd::Zero(static_cast(norb), static_cast(norb)))); + } else { + return std::make_tuple( + mat.triple[0].value_or( + MatrixXcd::Zero( + static_cast(norb), + static_cast(norb) + ) + ), + mat.triple[1].value_or( + MatrixXcd::Zero( + static_cast(norb), + static_cast(norb) + ) + ), + mat.triple[2].value_or( + MatrixXcd::Zero( + static_cast(norb), + static_cast(norb) + ) + ) + ); } }(); std::vector instructions; - for (size_t i = 0; i < 2 * norb; ++i) - { - for (size_t j = i + 1; j < 2 * norb; ++j) - { + for (size_t i = 0; i < 2 * norb; ++i) { + for (size_t j = i + 1; j < 2 * norb; ++j) { const MatrixXcd this_mat = (i < norb && j < norb) ? mat_aa : (i >= norb && j >= norb) ? mat_bb : mat_ab; - const auto val = this_mat(static_cast(i % norb), static_cast(j % norb)); - if (std::abs(val.real()) > 1e-12 || std::abs(val.imag()) > 1e-12) - { - instructions.push_back({"rzz", - {static_cast(qubits[i]), - static_cast(qubits[j])}, - {}, - std::vector{-1.0 * val.real() * time}}); + const auto val = this_mat( + static_cast(i % norb), static_cast(j % norb) + ); + if (std::abs(val.real()) > 1e-12 || std::abs(val.imag()) > 1e-12) { + instructions.push_back( + {"rzz", + {static_cast(qubits[i]), + static_cast(qubits[j])}, + {}, + std::vector{-1.0 * val.real() * time}} + ); } } } diff --git a/ffsim/include/ffsim/linalg/givens.hpp b/ffsim/include/ffsim/linalg/givens.hpp index 3a2da67..1a94748 100644 --- a/ffsim/include/ffsim/linalg/givens.hpp +++ b/ffsim/include/ffsim/linalg/givens.hpp @@ -109,8 +109,8 @@ struct GivensRotation * @param first_index First index involved * @param second_index Second index involved */ - GivensRotation(double c, Complex s, size_t first_index, size_t second_index) : c(c), s(s), i(first_index), j(second_index) { - } + GivensRotation(double c, Complex s, size_t first_index, size_t second_index) : c(c), s(s), i(first_index), j(second_index) // NOLINT(bugprone-easily-swappable-parameters) + {} }; /** diff --git a/ffsim/include/ffsim/orbital_rotation_jw.hpp b/ffsim/include/ffsim/orbital_rotation_jw.hpp index 351ac3e..61c365d 100644 --- a/ffsim/include/ffsim/orbital_rotation_jw.hpp +++ b/ffsim/include/ffsim/orbital_rotation_jw.hpp @@ -36,29 +36,35 @@ using namespace gates; * @param orbital_rotation Orbital rotation matrix * @return Vector of `CircuitInstruction` objects implementing the rotation */ -std::vector orbital_rotation_jw(const std::vector& qubits, - const MatrixXcd& orbital_rotation) +std::vector orbital_rotation_jw( + const std::vector &qubits, const MatrixXcd &orbital_rotation +) { - auto [givens_rotations, phase_shifts] = linalg::givens_decomposition(orbital_rotation); + auto [givens_rotations, phase_shifts] = + linalg::givens_decomposition(orbital_rotation); std::vector instructions; - for (const auto& rotation : givens_rotations) - { + for (const auto &rotation : givens_rotations) { double c = round_for_acos(rotation.c); double theta = 2.0 * std::acos(c); double beta = std::arg(rotation.s) - 0.5 * M_PI; - instructions.push_back({"xx_plus_yy", - {static_cast(qubits[rotation.i]), - static_cast(qubits[rotation.j])}, - {}, - std::vector{theta, beta}}); + instructions.push_back( + {"xx_plus_yy", + {static_cast(qubits[rotation.i]), + static_cast(qubits[rotation.j])}, + {}, + std::vector{theta, beta}} + ); } - for (size_t i = 0; i < phase_shifts.size(); ++i) - { + for (size_t i = 0; i < phase_shifts.size(); ++i) { double theta = std::arg(phase_shifts(static_cast(i))); instructions.push_back( - {"rz", {static_cast(qubits[i])}, {}, std::vector{theta}}); + {"rz", + {static_cast(qubits[i])}, + {}, + std::vector{theta}} + ); } return instructions; @@ -84,25 +90,25 @@ class OrbitalRotationJW * * @throws std::runtime_error if validation fails */ - OrbitalRotationJW(uint64_t norb, const OrbitalRotation& orbital_rotation, bool validate = true, - double rtol = 1e-5, double atol = 1e-8) - : norb(norb) + OrbitalRotationJW( + uint64_t norb, const OrbitalRotation &orbital_rotation, bool validate = true, + double rtol = 1e-5, double atol = 1e-8 + ) + : norb(norb) { - if (validate) - { + if (validate) { validate_orbital_rotation(orbital_rotation, rtol, atol); } - if (orbital_rotation.type == OrbitalRotationType::Spinless) - { + if (orbital_rotation.type == OrbitalRotationType::Spinless) { orbital_rotation_a = orbital_rotation.spinless; orbital_rotation_b = orbital_rotation.spinless; - } - else - { - orbital_rotation_a = - orbital_rotation.spinfull[0].value_or(MatrixXcd::Identity(static_cast(norb), static_cast(norb))); - orbital_rotation_b = - orbital_rotation.spinfull[1].value_or(MatrixXcd::Identity(static_cast(norb), static_cast(norb))); + } else { + orbital_rotation_a = orbital_rotation.spinfull[0].value_or( + MatrixXcd::Identity(static_cast(norb), static_cast(norb)) + ); + orbital_rotation_b = orbital_rotation.spinfull[1].value_or( + MatrixXcd::Identity(static_cast(norb), static_cast(norb)) + ); } } @@ -113,7 +119,8 @@ class OrbitalRotationJW * orbitals) * @return Vector of `CircuitInstruction` objects encoding the gate sequence */ - std::vector instructions(const std::vector& qubits) const + std::vector + instructions(const std::vector &qubits) const { auto norb_tmp = static_cast(qubits.size() / 2); std::vector alpha_qubits(qubits.begin(), qubits.begin() + norb_tmp); @@ -121,7 +128,9 @@ class OrbitalRotationJW auto instructions = orbital_rotation_jw(alpha_qubits, orbital_rotation_a); auto beta_instructions = orbital_rotation_jw(beta_qubits, orbital_rotation_b); - instructions.insert(instructions.end(), beta_instructions.begin(), beta_instructions.end()); + instructions.insert( + instructions.end(), beta_instructions.begin(), beta_instructions.end() + ); return instructions; } diff --git a/ffsim/include/ffsim/random_unitary.hpp b/ffsim/include/ffsim/random_unitary.hpp index f757542..bbdd2f9 100644 --- a/ffsim/include/ffsim/random_unitary.hpp +++ b/ffsim/include/ffsim/random_unitary.hpp @@ -40,10 +40,8 @@ MatrixXcd random_unitary(int N) std::normal_distribution dist(0.0, 1.0); MatrixXcd A = MatrixXcd::Zero(N, N); - for (int i = 0; i < N; ++i) - { - for (int j = 0; j < N; ++j) - { + for (int i = 0; i < N; ++i) { + for (int j = 0; j < N; ++j) { A(i, j) = Complex(dist(gen), dist(gen)); } } diff --git a/ffsim/include/ffsim/slater_determinant.hpp b/ffsim/include/ffsim/slater_determinant.hpp index b23874a..35bf2e1 100644 --- a/ffsim/include/ffsim/slater_determinant.hpp +++ b/ffsim/include/ffsim/slater_determinant.hpp @@ -39,19 +39,16 @@ using CircuitInstruction = ffsim::CircuitInstruction; * @param orbital_coeffs Matrix representing occupied orbitals * @return List of Givens rotations that diagonalize the matrix */ -std::vector givens_decomposition_slater(const MatrixXcd& orbital_coeffs) +std::vector givens_decomposition_slater(const MatrixXcd &orbital_coeffs) { size_t m = orbital_coeffs.rows(); size_t n = orbital_coeffs.cols(); MatrixXcd mat = orbital_coeffs; std::vector rotations; - for (int j = static_cast(n - 1); j >= static_cast(n - m + 1); --j) - { - for (int i = 0; i < static_cast(m - n + j); ++i) - { - if (std::norm(mat(i, j)) > 0.0) - { + for (int j = static_cast(n - 1); j >= static_cast(n - m + 1); --j) { + for (int i = 0; i < static_cast(m - n + j); ++i) { + if (std::norm(mat(i, j)) > 0.0) { auto [c, s, _] = zrotg(mat(i + 1, j), mat(i, j)); VectorXcd row1 = mat.row(i + 1).transpose(); @@ -63,13 +60,13 @@ std::vector givens_decomposition_slater(const MatrixXcd& orbital } } - for (size_t i = 0; i < m; ++i) - { - for (int j = static_cast(n - m + i); j > static_cast(i); --j) - { - if (std::norm(mat(static_cast(i), static_cast(j))) > 0.0) - { - auto [c, s, _] = zrotg(mat(static_cast(i), static_cast(j - 1)), mat(static_cast(i), static_cast(j))); + for (size_t i = 0; i < m; ++i) { + for (int j = static_cast(n - m + i); j > static_cast(i); --j) { + if (std::norm(mat(static_cast(i), static_cast(j))) > 0.0) { + auto [c, s, _] = zrotg( + mat(static_cast(i), static_cast(j - 1)), + mat(static_cast(i), static_cast(j)) + ); rotations.emplace_back(c, s, j, j - 1); VectorXcd col1 = mat.col(j - 1).transpose(); VectorXcd col2 = mat.col(j).transpose(); @@ -93,8 +90,9 @@ std::vector givens_decomposition_slater(const MatrixXcd& orbital * @return List of Jordan-Wigner circuit instructions implementing the state * preparation */ -std::vector prepare_slater_determinant_jw(const std::vector& qubits, - const MatrixXcd& orbital_coeffs) +std::vector prepare_slater_determinant_jw( + const std::vector &qubits, const MatrixXcd &orbital_coeffs +) { std::vector instructions; size_t m = orbital_coeffs.rows(); @@ -102,8 +100,7 @@ std::vector prepare_slater_determinant_jw(const std::vector< instructions.reserve(m); - for (size_t i = 0; i < m; ++i) - { + for (size_t i = 0; i < m; ++i) { instructions.push_back({"x", {static_cast(qubits[i])}, {}, {}}); } @@ -112,16 +109,17 @@ std::vector prepare_slater_determinant_jw(const std::vector< auto givens_rotation = givens_decomposition_slater(orbital_coeffs); - for (const auto& rotation : givens_rotation) - { + for (const auto &rotation : givens_rotation) { double c = round_for_acos(rotation.c); double theta = 2.0 * std::acos(c); double beta = std::arg(rotation.s) - 0.5 * M_PI; - instructions.push_back({"xx_plus_yy", - {static_cast(qubits[rotation.i]), - static_cast(qubits[rotation.j])}, - {}, - {theta, beta}}); + instructions.push_back( + {"xx_plus_yy", + {static_cast(qubits[rotation.i]), + static_cast(qubits[rotation.j])}, + {}, + {theta, beta}} + ); } return instructions; } @@ -148,39 +146,41 @@ class PrepareSlaterDeterminantJW */ PrepareSlaterDeterminantJW( uint64_t norb, - const std::pair, std::vector>& occupied_orbitals, - const std::optional& orbital_rotation, const std::vector& qubits, - bool validate, double rtol, double atol) - : norb(norb), occupied_orbitals(occupied_orbitals), qubits(qubits) + const std::pair, std::vector> + &occupied_orbitals, + const std::optional &orbital_rotation, + const std::vector &qubits, bool validate, double rtol, double atol + ) + : norb(norb), occupied_orbitals(occupied_orbitals), qubits(qubits) { - if (qubits.size() != 2 * norb) - { + if (qubits.size() != 2 * norb) { throw std::runtime_error("Qubits sizew must be equal to 2 * norb"); } - if (orbital_rotation.has_value()) - { - if (validate) - { + if (orbital_rotation.has_value()) { + if (validate) { validate_orbital_rotation(orbital_rotation.value(), rtol, atol); } - if (orbital_rotation->type == OrbitalRotationType::Spinless) - { + if (orbital_rotation->type == OrbitalRotationType::Spinless) { orbital_rotation_a_ = orbital_rotation.value().spinless; orbital_rotation_b_ = orbital_rotation.value().spinless; + } else { + orbital_rotation_a_ = orbital_rotation.value().spinfull[0].value_or( + MatrixXcd::Identity( + static_cast(norb), static_cast(norb) + ) + ); + orbital_rotation_b_ = orbital_rotation.value().spinfull[1].value_or( + MatrixXcd::Identity( + static_cast(norb), static_cast(norb) + ) + ); } - else - { - orbital_rotation_a_ = - orbital_rotation.value().spinfull[0].value_or(MatrixXcd::Identity(static_cast(norb), static_cast(norb))); - orbital_rotation_b_ = - orbital_rotation.value().spinfull[1].value_or(MatrixXcd::Identity(static_cast(norb), static_cast(norb))); - } - } - else - { - orbital_rotation_a_ = MatrixXcd::Identity(static_cast(norb), static_cast(norb)); - orbital_rotation_b_ = MatrixXcd::Identity(static_cast(norb), static_cast(norb)); + } else { + orbital_rotation_a_ = + MatrixXcd::Identity(static_cast(norb), static_cast(norb)); + orbital_rotation_b_ = + MatrixXcd::Identity(static_cast(norb), static_cast(norb)); } } @@ -192,36 +192,46 @@ class PrepareSlaterDeterminantJW std::vector instructions() const { uint64_t norb = qubits.size() / 2; - std::vector alpha_qubits(qubits.begin(), qubits.begin() + static_cast(norb)); - std::vector beta_qubits(qubits.begin() + static_cast(norb), qubits.end()); + std::vector alpha_qubits( + qubits.begin(), qubits.begin() + static_cast(norb) + ); + std::vector beta_qubits( + qubits.begin() + static_cast(norb), qubits.end() + ); std::vector instructions; - const auto& occ_a = occupied_orbitals.first; - const auto& occ_b = occupied_orbitals.second; - if (orbital_rotation_a_.isApprox(MatrixXcd::Identity(static_cast(norb), static_cast(norb)), 1e-12)) - { - for (auto a : occ_a) - { - instructions.push_back({"x", {static_cast(alpha_qubits[a])}, {}, {}}); + const auto &occ_a = occupied_orbitals.first; + const auto &occ_b = occupied_orbitals.second; + if (orbital_rotation_a_.isApprox( + MatrixXcd::Identity(static_cast(norb), static_cast(norb)), + 1e-12 + )) { + for (auto a : occ_a) { + instructions.push_back( + {"x", {static_cast(alpha_qubits[a])}, {}, {}} + ); } - } - else - { + } else { MatrixXcd orb_a_t = orbital_rotation_a_(all, occ_a).transpose(); auto slater_instr_a = prepare_slater_determinant_jw(alpha_qubits, orb_a_t); - instructions.insert(instructions.end(), slater_instr_a.begin(), slater_instr_a.end()); + instructions.insert( + instructions.end(), slater_instr_a.begin(), slater_instr_a.end() + ); } - if (orbital_rotation_b_.isApprox(MatrixXcd::Identity(static_cast(norb), static_cast(norb)), 1e-12)) - { - for (auto b : occ_b) - { - instructions.push_back({"x", {static_cast(beta_qubits[b])}, {}, {}}); + if (orbital_rotation_b_.isApprox( + MatrixXcd::Identity(static_cast(norb), static_cast(norb)), + 1e-12 + )) { + for (auto b : occ_b) { + instructions.push_back( + {"x", {static_cast(beta_qubits[b])}, {}, {}} + ); } - } - else - { + } else { MatrixXcd orb_b_t = orbital_rotation_b_(all, occ_b).transpose(); auto slater_instr_b = prepare_slater_determinant_jw(beta_qubits, orb_b_t); - instructions.insert(instructions.end(), slater_instr_b.begin(), slater_instr_b.end()); + instructions.insert( + instructions.end(), slater_instr_b.begin(), slater_instr_b.end() + ); } return instructions; @@ -232,14 +242,20 @@ class PrepareSlaterDeterminantJW * spin. * @return Mutable reference to the orbital rotation matrix for alpha spin */ - MatrixXcd& orbital_rotation_a() { return orbital_rotation_a_; } + MatrixXcd &orbital_rotation_a() + { + return orbital_rotation_a_; + } /** * @brief Returns a mutable reference to the orbital rotation matrix for beta * spin. * @return Mutable reference to the orbital rotation matrix for beta spin */ - MatrixXcd& orbital_rotation_b() { return orbital_rotation_b_; } + MatrixXcd &orbital_rotation_b() + { + return orbital_rotation_b_; + } private: uint64_t norb; ///< Number of spatial orbitals @@ -266,7 +282,7 @@ class PrepareHatreeFockJW * @param nelec Number of electrons as a pair (alpha, beta) */ PrepareHatreeFockJW(uint64_t norb, std::pair nelec) - : norb(norb), nelec(nelec) + : norb(norb), nelec(nelec) { } @@ -277,14 +293,16 @@ class PrepareHatreeFockJW * orbitals) * @return List of Jordan-Wigner-based circuit instructions */ - std::vector instructions(const std::vector& qubits) const + std::vector + instructions(const std::vector &qubits) const { std::vector n_alpha(nelec.first); std::iota(n_alpha.begin(), n_alpha.end(), 0); std::vector n_beta(nelec.second); std::iota(n_beta.begin(), n_beta.end(), 0); - return PrepareSlaterDeterminantJW(norb, {n_alpha, n_beta}, std::nullopt, qubits, true, 1e-5, - 1e-8) + return PrepareSlaterDeterminantJW( + norb, {n_alpha, n_beta}, std::nullopt, qubits, true, 1e-5, 1e-8 + ) .instructions(); } diff --git a/ffsim/include/ffsim/ucj.hpp b/ffsim/include/ffsim/ucj.hpp index 85f221c..f33c381 100644 --- a/ffsim/include/ffsim/ucj.hpp +++ b/ffsim/include/ffsim/ucj.hpp @@ -43,12 +43,12 @@ namespace ffsim * * @throws std::runtime_error if the length of `qubits` is not equal to 2 * norb. */ -std::vector -slater_determinant_instruction(const std::vector& qubits, const size_t norb, - const std::pair& nelec, const VectorXcd& params) +std::vector slater_determinant_instruction( + const std::vector &qubits, const size_t norb, + const std::pair &nelec, const VectorXcd ¶ms +) { - if (qubits.size() != 2 * norb) - { + if (qubits.size() != 2 * norb) { throw std::runtime_error("The length of `qubits` must be (norb * 2)"); } @@ -59,12 +59,11 @@ slater_determinant_instruction(const std::vector& qubits, const size_t size_t nela = nelec.first; - MatrixXcd Kmat = MatrixXcd::Zero(static_cast(norb), static_cast(norb)); + MatrixXcd Kmat = + MatrixXcd::Zero(static_cast(norb), static_cast(norb)); int idx = 0; - for (int i = 0; i < nela; ++i) - { - for (int j = 0; j < (norb - nela); ++j) - { + for (int i = 0; i < nela; ++i) { + for (int j = 0; j < (norb - nela); ++j) { double real_part = params(idx++).real(); double imag_part = params(idx++).real(); // assume params are all real std::complex val(real_part, imag_part); @@ -77,9 +76,12 @@ slater_determinant_instruction(const std::vector& qubits, const size_t PrepareSlaterDeterminantJW slater_determinant( norb, {n_alpha, n_beta}, - OrbitalRotation{OrbitalRotationType::Spinless, orbital_rotation, - std::array, 2>{std::nullopt, std::nullopt}}, - qubits, true, 1e-5, 1e-8); + OrbitalRotation{ + OrbitalRotationType::Spinless, orbital_rotation, + std::array, 2>{std::nullopt, std::nullopt} + }, + qubits, true, 1e-5, 1e-8 + ); std::vector slater_inst = slater_determinant.instructions(); @@ -96,40 +98,39 @@ slater_determinant_instruction(const std::vector& qubits, const size_t * @param ucj_op The UCJOpSpinBalanced operator. * @return A vector of CircuitInstruction objects implementing the UCJ operator. */ -std::vector ucj_op_spin_balanced_jw(const std::vector& qubits, - const UCJOpSpinBalanced& ucj_op) +std::vector ucj_op_spin_balanced_jw( + const std::vector &qubits, const UCJOpSpinBalanced &ucj_op +) { std::vector instructions; uint64_t norb = ucj_op.norb(); size_t n_reps = ucj_op.n_reps(); - for (int rep = 0; rep < n_reps; ++rep) - { + for (int rep = 0; rep < n_reps; ++rep) { MatrixXcd diag_coulomb_mat_aa(norb, norb); MatrixXcd diag_coulomb_mat_ab(norb, norb); - for (int i = 0; i < norb; ++i) - { - for (int j = 0; j < norb; ++j) - { + for (int i = 0; i < norb; ++i) { + for (int j = 0; j < norb; ++j) { diag_coulomb_mat_aa(i, j) = ucj_op.diag_coulomb_mats(rep, 0, i, j); diag_coulomb_mat_ab(i, j) = ucj_op.diag_coulomb_mats(rep, 1, i, j); } } MatrixXcd orbital_rotation(norb, norb); - for (int i = 0; i < norb; ++i) - { - for (int j = 0; j < norb; ++j) - { + for (int i = 0; i < norb; ++i) { + for (int j = 0; j < norb; ++j) { orbital_rotation(i, j) = std::conj(ucj_op.orbital_rotations(rep, j, i)); } } auto rot1 = OrbitalRotationJW( norb, - OrbitalRotation{OrbitalRotationType::Spinless, orbital_rotation, - std::array, 2>{std::nullopt, std::nullopt}}, - true, 1e-5, 1e-8); + OrbitalRotation{ + OrbitalRotationType::Spinless, orbital_rotation, + std::array, 2>{std::nullopt, std::nullopt} + }, + true, 1e-5, 1e-8 + ); auto inst1 = rot1.instructions(qubits); instructions.insert(instructions.end(), inst1.begin(), inst1.end()); @@ -138,34 +139,38 @@ std::vector ucj_op_spin_balanced_jw(const std::vector, 2>{std::nullopt, std::nullopt}}, - true, 1e-5, 1e-8); + OrbitalRotation{ + OrbitalRotationType::Spinless, orbital_rotation2, + std::array, 2>{std::nullopt, std::nullopt} + }, + true, 1e-5, 1e-8 + ); auto inst3 = rot2.instructions(qubits); instructions.insert(instructions.end(), inst3.begin(), inst3.end()); } - if (ucj_op.final_orbital_rotation.has_value()) - { + if (ucj_op.final_orbital_rotation.has_value()) { auto final_orbital_rotation = OrbitalRotationJW( norb, - OrbitalRotation{OrbitalRotationType::Spinless, ucj_op.final_orbital_rotation.value(), - std::array, 2>{std::nullopt, std::nullopt}}, - true, 1e-5, 1e-8); + OrbitalRotation{ + OrbitalRotationType::Spinless, ucj_op.final_orbital_rotation.value(), + std::array, 2>{std::nullopt, std::nullopt} + }, + true, 1e-5, 1e-8 + ); auto inst4 = final_orbital_rotation.instructions(qubits); instructions.insert(instructions.end(), inst4.begin(), inst4.end()); } @@ -189,7 +194,9 @@ class UCJOpSpinBalancedJW * * @param ucj_op_ The UCJOpSpinBalanced operator to be applied. */ - explicit UCJOpSpinBalancedJW(const UCJOpSpinBalanced& ucj_op_) : ucj_op(ucj_op_) {} + explicit UCJOpSpinBalancedJW(const UCJOpSpinBalanced &ucj_op_) : ucj_op(ucj_op_) + { + } /** * @brief Generate the quantum circuit instructions that implement the UCJ @@ -201,11 +208,11 @@ class UCJOpSpinBalancedJW * * @throws std::runtime_error if the number of qubits is incorrect. */ - std::vector instructions(const std::vector& qubits) const + std::vector + instructions(const std::vector &qubits) const { size_t required_length = ucj_op.norb() * 2; - if (qubits.size() != required_length) - { + if (qubits.size() != required_length) { throw std::runtime_error("The length of `qubits` must be (norb * 2)"); } return ucj_op_spin_balanced_jw(qubits, ucj_op); @@ -229,16 +236,15 @@ class UCJOpSpinBalancedJW * @return A vector of CircuitInstruction objects implementing the Hartree-Fock * state preparation and the UCJ operator. */ -std::vector -hf_and_ucj_op_spin_balanced_jw(const std::vector& qubits, - const std::pair& nelec, - const UCJOpSpinBalanced& ucj_op) +std::vector hf_and_ucj_op_spin_balanced_jw( + const std::vector &qubits, const std::pair &nelec, + const UCJOpSpinBalanced &ucj_op +) { std::vector instructions; uint64_t norb = ucj_op.norb(); - if (qubits.size() != 2 * norb) - { + if (qubits.size() != 2 * norb) { throw std::runtime_error("The length of `qubits` must be (norb * 2)"); } @@ -249,24 +255,26 @@ hf_and_ucj_op_spin_balanced_jw(const std::vector& qubits, const size_t n_reps = ucj_op.n_reps(); - PrepareSlaterDeterminantJW slater_determinant(norb, {n_alpha, n_beta}, std::nullopt, qubits, - true, 1e-5, 1e-8); + PrepareSlaterDeterminantJW slater_determinant( + norb, {n_alpha, n_beta}, std::nullopt, qubits, true, 1e-5, 1e-8 + ); MatrixXcd orbital_rotation = MatrixXcd(norb, norb); - for (uint64_t i = 0; i < norb; ++i) - { - for (uint64_t j = 0; j < norb; ++j) - { - orbital_rotation(static_cast(i), static_cast(j)) = - std::conj(ucj_op.orbital_rotations(0, static_cast(j), static_cast(i))); + for (uint64_t i = 0; i < norb; ++i) { + for (uint64_t j = 0; j < norb; ++j) { + orbital_rotation(static_cast(i), static_cast(j)) = std::conj( + ucj_op.orbital_rotations(0, static_cast(j), static_cast(i)) + ); } } MatrixXcd orbital_rotation_a = orbital_rotation; MatrixXcd orbital_rotation_b = orbital_rotation; - MatrixXcd combined_mat_a = orbital_rotation_a * slater_determinant.orbital_rotation_a(); - MatrixXcd combined_mat_b = orbital_rotation_b * slater_determinant.orbital_rotation_b(); + MatrixXcd combined_mat_a = + orbital_rotation_a * slater_determinant.orbital_rotation_a(); + MatrixXcd combined_mat_b = + orbital_rotation_b * slater_determinant.orbital_rotation_b(); slater_determinant.orbital_rotation_a() = combined_mat_a; slater_determinant.orbital_rotation_b() = combined_mat_b; @@ -274,14 +282,11 @@ hf_and_ucj_op_spin_balanced_jw(const std::vector& qubits, std::vector slater_inst = slater_determinant.instructions(); instructions.insert(instructions.end(), slater_inst.begin(), slater_inst.end()); - for (int rep = 0; rep < n_reps; ++rep) - { + for (int rep = 0; rep < n_reps; ++rep) { MatrixXcd diag_coulomb_mat_aa(norb, norb); MatrixXcd diag_coulomb_mat_ab(norb, norb); - for (int i = 0; i < norb; ++i) - { - for (int j = 0; j < norb; ++j) - { + for (int i = 0; i < norb; ++i) { + for (int j = 0; j < norb; ++j) { diag_coulomb_mat_aa(i, j) = ucj_op.diag_coulomb_mats(rep, 0, i, j); diag_coulomb_mat_ab(i, j) = ucj_op.diag_coulomb_mats(rep, 1, i, j); } @@ -292,40 +297,43 @@ hf_and_ucj_op_spin_balanced_jw(const std::vector& qubits, Mat{MatType::Triple, MatrixXcd(), {diag_coulomb_mat_aa, diag_coulomb_mat_ab, diag_coulomb_mat_aa}}, - -1.0, false); + -1.0, false + ); auto inst2 = diag.instructions(qubits); instructions.insert(instructions.end(), inst2.begin(), inst2.end()); - if (rep == n_reps - 1) - { + if (rep == n_reps - 1) { MatrixXcd orbital_rotation2(norb, norb); - for (int i = 0; i < norb; ++i) - { - for (int j = 0; j < norb; ++j) - { + for (int i = 0; i < norb; ++i) { + for (int j = 0; j < norb; ++j) { orbital_rotation2(i, j) = ucj_op.orbital_rotations(rep, i, j); } } - if (ucj_op.final_orbital_rotation.has_value()) - { + if (ucj_op.final_orbital_rotation.has_value()) { auto rot2 = OrbitalRotationJW( norb, OrbitalRotation{ OrbitalRotationType::Spinless, ucj_op.final_orbital_rotation.value() * orbital_rotation2, - std::array, 2>{std::nullopt, std::nullopt}}, - true, 1e-5, 1e-8); + std::array, 2>{ + std::nullopt, std::nullopt + } + }, + true, 1e-5, 1e-8 + ); auto inst3 = rot2.instructions(qubits); instructions.insert(instructions.end(), inst3.begin(), inst3.end()); - } - else - { + } else { auto rot2 = OrbitalRotationJW( norb, OrbitalRotation{ OrbitalRotationType::Spinless, orbital_rotation2, - std::array, 2>{std::nullopt, std::nullopt}}, - true, 1e-5, 1e-8); + std::array, 2>{ + std::nullopt, std::nullopt + } + }, + true, 1e-5, 1e-8 + ); auto inst3 = rot2.instructions(qubits); instructions.insert(instructions.end(), inst3.begin(), inst3.end()); } diff --git a/ffsim/include/ffsim/ucjop_spinbalanced.hpp b/ffsim/include/ffsim/ucjop_spinbalanced.hpp index 714b1f3..1134ad4 100644 --- a/ffsim/include/ffsim/ucjop_spinbalanced.hpp +++ b/ffsim/include/ffsim/ucjop_spinbalanced.hpp @@ -29,9 +29,9 @@ namespace std { -template <> struct hash<::std::pair> -{ - size_t operator()(const std::pair& p) const +template <> +struct hash<::std::pair> { + size_t operator()(const std::pair &p) const { return hash()(p.first) ^ (hash()(p.second) << 1); } @@ -48,25 +48,25 @@ namespace { inline void validate_interaction_pairs( - const std::optional>>& interaction_pairs, - bool ordered) + const std::optional>> &interaction_pairs, + bool ordered +) { if (!interaction_pairs) return; std::unordered_set> unique_pairs; - for (const auto& p : *interaction_pairs) - { - if (!unique_pairs.insert(p).second) - { + for (const auto &p : *interaction_pairs) { + if (!unique_pairs.insert(p).second) { throw std::runtime_error("Duplicate interaction pairs encountered."); } - if (!ordered && p.first > p.second) - { - throw std::runtime_error("When specifying alpha-alpha or beta-beta interaction pairs, " - "you must provide only upper triangular pairs. " - "Got (" + - std::to_string(p.first) + ", " + std::to_string(p.second) + - "), which is a lower triangular pair."); + if (!ordered && p.first > p.second) { + throw std::runtime_error( + "When specifying alpha-alpha or beta-beta interaction pairs, " + "you must provide only upper triangular pairs. " + "Got (" + + std::to_string(p.first) + ", " + std::to_string(p.second) + + "), which is a lower triangular pair." + ); } } } @@ -80,8 +80,7 @@ inline void validate_interaction_pairs( * UCJ operator, including diagonal Coulomb terms, orbital rotations, and * optional final orbital rotation. */ -struct UCJOpSpinBalanced -{ +struct UCJOpSpinBalanced { /// Diagonal Coulomb matrices (shape: n_reps × 2 × norb × norb) Tensor diag_coulomb_mats; @@ -101,35 +100,32 @@ struct UCJOpSpinBalanced * @param rtol Relative tolerance for validation * @param atol Absolute tolerance for validation */ - UCJOpSpinBalanced(const Tensor& diag_coulomb_mats, - const Tensor& orbital_rotations, - const std::optional& final_orbital_rotation, bool validate, - double rtol, double atol) - : diag_coulomb_mats(diag_coulomb_mats), orbital_rotations(orbital_rotations), - final_orbital_rotation(final_orbital_rotation) + UCJOpSpinBalanced( + const Tensor &diag_coulomb_mats, + const Tensor &orbital_rotations, + const std::optional &final_orbital_rotation, bool validate, + double rtol, double atol + ) + : diag_coulomb_mats(diag_coulomb_mats), orbital_rotations(orbital_rotations), + final_orbital_rotation(final_orbital_rotation) { - if (validate) - { - if (diag_coulomb_mats.dimension(1) != 2) - { + if (validate) { + if (diag_coulomb_mats.dimension(1) != 2) { throw std::runtime_error( - "diag_coulomb_mats should have shape (n_reps, 2, norb, norb)"); + "diag_coulomb_mats should have shape (n_reps, 2, norb, norb)" + ); } - if (diag_coulomb_mats.dimension(0) != orbital_rotations.dimension(0)) - { + if (diag_coulomb_mats.dimension(0) != orbital_rotations.dimension(0)) { throw std::runtime_error( - "diag_coulomb_mats and orbital_rotations must match in reps"); + "diag_coulomb_mats and orbital_rotations must match in reps" + ); } uint64_t norb = diag_coulomb_mats.dimension(3); MatrixXcd mat(norb, norb); - for (int i = 0; i < diag_coulomb_mats.dimension(0); ++i) - { - for (int j = 0; j < 2; ++j) - { - for (int a = 0; a < norb; ++a) - { - for (int b = 0; b < norb; ++b) - { + for (int i = 0; i < diag_coulomb_mats.dimension(0); ++i) { + for (int j = 0; j < 2; ++j) { + for (int a = 0; a < norb; ++a) { + for (int b = 0; b < norb; ++b) { mat(a, b) = diag_coulomb_mats(i, j, a, b); } } @@ -140,24 +136,19 @@ struct UCJOpSpinBalanced } } MatrixXcd orb_rot_tmp(norb, norb); - for (int i = 0; i < orbital_rotations.dimension(0); ++i) - { - for (int a = 0; a < norb; ++a) - { - for (int b = 0; b < norb; ++b) - { + for (int i = 0; i < orbital_rotations.dimension(0); ++i) { + for (int a = 0; a < norb; ++a) { + for (int b = 0; b < norb; ++b) { orb_rot_tmp(a, b) = orbital_rotations(i, a, b); } } - if (!linalg::is_unitary(orb_rot_tmp, rtol, atol)) - { + if (!linalg::is_unitary(orb_rot_tmp, rtol, atol)) { throw std::runtime_error("orbital_rotations must be unitary"); } } if (final_orbital_rotation.has_value() && - !linalg::is_unitary(final_orbital_rotation.value(), rtol, atol)) - { + !linalg::is_unitary(final_orbital_rotation.value(), rtol, atol)) { throw std::runtime_error("final_orbital_rotation must be unitary"); } } @@ -173,22 +164,23 @@ struct UCJOpSpinBalanced * included * @return Total number of real parameters */ - static size_t - n_params(uint64_t norb, size_t n_reps, - const std::array>>, 2>& - interaction_pairs, - bool with_final_orbital_rotation) + static size_t n_params( + uint64_t norb, size_t n_reps, + const std::array>>, 2> + &interaction_pairs, + bool with_final_orbital_rotation + ) { validate_interaction_pairs(interaction_pairs[0], false); validate_interaction_pairs(interaction_pairs[1], false); size_t n_triu = norb * (norb + 1) / 2; size_t n_params_aa = n_triu; - if (const auto& pairs_aa_opt = interaction_pairs[0]; pairs_aa_opt.has_value()) { + if (const auto &pairs_aa_opt = interaction_pairs[0]; pairs_aa_opt.has_value()) { n_params_aa = pairs_aa_opt.value().size(); } size_t n_params_ab = n_triu; - if (const auto& pairs_ab_opt = interaction_pairs[1]; pairs_ab_opt.has_value()) { + if (const auto &pairs_ab_opt = interaction_pairs[1]; pairs_ab_opt.has_value()) { n_params_ab = pairs_ab_opt.value().size(); } @@ -207,73 +199,87 @@ struct UCJOpSpinBalanced * rotation * @return UCJOpSpinBalanced instance */ - static UCJOpSpinBalanced - from_parameters(const VectorXcd& params, uint64_t norb, size_t n_reps, - const std::array>>, 2>& - interaction_pairs, - bool with_final_orbital_rotation) + static UCJOpSpinBalanced from_parameters( + const VectorXcd ¶ms, uint64_t norb, size_t n_reps, + const std::array>>, 2> + &interaction_pairs, + bool with_final_orbital_rotation + ) { auto expected_params = n_params(norb, n_reps, interaction_pairs, with_final_orbital_rotation); - if (params.size() != expected_params) - { - throw std::runtime_error("Expected " + std::to_string(expected_params) + - " parameters, but got " + std::to_string(params.size())); + if (params.size() != expected_params) { + throw std::runtime_error( + "Expected " + std::to_string(expected_params) + + " parameters, but got " + std::to_string(params.size()) + ); } std::vector> triu; - for (size_t i = 0; i < norb; ++i) - { - for (size_t j = i; j < norb; ++j) - { + for (size_t i = 0; i < norb; ++i) { + for (size_t j = i; j < norb; ++j) { triu.emplace_back(i, j); } } - const auto& pairs_aa = interaction_pairs[0].value_or(triu); - const auto& pairs_ab = interaction_pairs[1].value_or(triu); + const auto &pairs_aa = interaction_pairs[0].value_or(triu); + const auto &pairs_ab = interaction_pairs[1].value_or(triu); size_t index = 0; - Tensor diag_coulomb_mats(static_cast(n_reps), static_cast(2), - static_cast(norb), static_cast(norb)); + Tensor diag_coulomb_mats( + static_cast(n_reps), static_cast(2), static_cast(norb), + static_cast(norb) + ); diag_coulomb_mats.setZero(); - Tensor orbital_rotations(static_cast(n_reps), static_cast(norb), - static_cast(norb)); + Tensor orbital_rotations( + static_cast(n_reps), static_cast(norb), static_cast(norb) + ); orbital_rotations.setZero(); - for (size_t rep = 0; rep < n_reps; ++rep) - { - MatrixXcd orbital_rotation = - orbital_rotation_from_parameters(params.segment(static_cast(index), static_cast(norb * norb)), static_cast(norb), false); + for (size_t rep = 0; rep < n_reps; ++rep) { + MatrixXcd orbital_rotation = orbital_rotation_from_parameters( + params.segment( + static_cast(index), static_cast(norb * norb) + ), + static_cast(norb), false + ); index += norb * norb; - for (int i = 0; i < norb; ++i) - { - for (int j = 0; j < norb; ++j) - { - orbital_rotations(static_cast(rep), i, j) = orbital_rotation(i, j); + for (int i = 0; i < norb; ++i) { + for (int j = 0; j < norb; ++j) { + orbital_rotations(static_cast(rep), i, j) = + orbital_rotation(i, j); } } - for (int t = 0; t < 2; ++t) - { - const auto& pairs = (t == 0) ? pairs_aa : pairs_ab; - for (const auto& [i, j] : pairs) - { + for (int t = 0; t < 2; ++t) { + const auto &pairs = (t == 0) ? pairs_aa : pairs_ab; + for (const auto &[i, j] : pairs) { Complex val = params(static_cast(index++)); - diag_coulomb_mats(static_cast(rep), t, static_cast(i), static_cast(j)) = val; - diag_coulomb_mats(static_cast(rep), t, static_cast(j), static_cast(i)) = val; + diag_coulomb_mats( + static_cast(rep), t, static_cast(i), + static_cast(j) + ) = val; + diag_coulomb_mats( + static_cast(rep), t, static_cast(j), + static_cast(i) + ) = val; } } } std::optional final_orbital_rotation; - if (with_final_orbital_rotation) - { - final_orbital_rotation = - orbital_rotation_from_parameters(params.segment(static_cast(index), static_cast(norb * norb)), static_cast(norb), false); + if (with_final_orbital_rotation) { + final_orbital_rotation = orbital_rotation_from_parameters( + params.segment( + static_cast(index), static_cast(norb * norb) + ), + static_cast(norb), false + ); } - return UCJOpSpinBalanced(diag_coulomb_mats, orbital_rotations, final_orbital_rotation, true, - 1e-5, 1e-8); + return UCJOpSpinBalanced( + diag_coulomb_mats, orbital_rotations, final_orbital_rotation, true, 1e-5, + 1e-8 + ); } /** @@ -282,53 +288,50 @@ struct UCJOpSpinBalanced * @param interaction_pairs Optional interaction masks * @return Real-valued parameter vector */ - VectorXcd - to_parameters(const std::array>>, 2>& - interaction_pairs) const + VectorXcd to_parameters( + const std::array>>, 2> + &interaction_pairs + ) const { size_t n_reps = diag_coulomb_mats.dimension(0); uint64_t norb = diag_coulomb_mats.dimension(3); - auto total = n_params(norb, n_reps, interaction_pairs, final_orbital_rotation.has_value()); + auto total = n_params( + norb, n_reps, interaction_pairs, final_orbital_rotation.has_value() + ); VectorXcd params(total); std::vector> triu; - for (size_t i = 0; i < norb; ++i) - { - for (size_t j = i; j < norb; ++j) - { + for (size_t i = 0; i < norb; ++i) { + for (size_t j = i; j < norb; ++j) { triu.emplace_back(i, j); } } - const auto& pairs_aa = interaction_pairs[0].value_or(triu); - const auto& pairs_ab = interaction_pairs[1].value_or(triu); + const auto &pairs_aa = interaction_pairs[0].value_or(triu); + const auto &pairs_ab = interaction_pairs[1].value_or(triu); size_t index = 0; - for (int rep = 0; rep < n_reps; ++rep) - { + for (int rep = 0; rep < n_reps; ++rep) { MatrixXcd orb_rot(norb, norb); - for (int i = 0; i < norb; ++i) - { - for (int j = 0; j < norb; ++j) - { + for (int i = 0; i < norb; ++i) { + for (int j = 0; j < norb; ++j) { orb_rot(i, j) = orbital_rotations(rep, i, j); } } - params.segment(static_cast(index), static_cast(norb * norb)) = orbital_rotation_to_parameters(orb_rot, false); + params.segment(static_cast(index), static_cast(norb * norb)) = + orbital_rotation_to_parameters(orb_rot, false); index += norb * norb; - for (int t = 0; t < 2; ++t) - { - const auto& pairs = (t == 0) ? pairs_aa : pairs_ab; - for (const auto& [i, j] : pairs) - { - params(static_cast(index++)) = - diag_coulomb_mats(rep, t, static_cast(i), static_cast(j)); + for (int t = 0; t < 2; ++t) { + const auto &pairs = (t == 0) ? pairs_aa : pairs_ab; + for (const auto &[i, j] : pairs) { + params(static_cast(index++)) = diag_coulomb_mats( + rep, t, static_cast(i), static_cast(j) + ); } } } - if (final_orbital_rotation) - { + if (final_orbital_rotation) { params.segment(static_cast(index), static_cast(norb * norb)) = orbital_rotation_to_parameters(final_orbital_rotation.value(), false); } @@ -346,12 +349,13 @@ struct UCJOpSpinBalanced * @param tol Tolerance for truncating eigenvalue decomposition * @return UCJOpSpinBalanced instance */ - static UCJOpSpinBalanced - from_t_amplitudes(const Tensor& t2, const std::optional& t1, - std::optional n_reps, - const std::array>>, - 2>& interaction_pairs, - double tol) + static UCJOpSpinBalanced from_t_amplitudes( + const Tensor &t2, const std::optional &t1, + std::optional n_reps, + const std::array>>, 2> + &interaction_pairs, + double tol + ) { validate_interaction_pairs(interaction_pairs[0], false); validate_interaction_pairs(interaction_pairs[1], false); @@ -363,22 +367,32 @@ struct UCJOpSpinBalanced linalg::double_factorized_t2(t2, tol, std::nullopt); size_t n_vecs = diag_coulomb_mats.size() / (norb * norb); size_t orb_vecs = orbital_rotations.size() / (norb * norb); - Eigen::DSizes diag_shape_3d(static_cast(n_vecs), static_cast(norb), - static_cast(norb)); - Eigen::DSizes orb_shape_3d(static_cast(orb_vecs), static_cast(norb), - static_cast(norb)); - - Tensor diag_coulomb_mats_reshaped = diag_coulomb_mats.reshape(diag_shape_3d); - Tensor orbital_rotations_reshaped = orbital_rotations.reshape(orb_shape_3d); - if (n_reps.has_value()) - { + Eigen::DSizes diag_shape_3d( + static_cast(n_vecs), static_cast(norb), + static_cast(norb) + ); + Eigen::DSizes orb_shape_3d( + static_cast(orb_vecs), static_cast(norb), + static_cast(norb) + ); + + Tensor diag_coulomb_mats_reshaped = + diag_coulomb_mats.reshape(diag_shape_3d); + Tensor orbital_rotations_reshaped = + orbital_rotations.reshape(orb_shape_3d); + if (n_reps.has_value()) { size_t n_terms = std::min(n_reps.value(), n_vecs); - Eigen::DSizes slice_shape{static_cast(n_terms), - static_cast(norb), static_cast(norb)}; + Eigen::DSizes slice_shape{ + static_cast(n_terms), static_cast(norb), + static_cast(norb) + }; auto diag_slice = diag_coulomb_mats_reshaped.slice( array{0, 0, 0}, - array{static_cast(n_terms), static_cast(norb), - static_cast(norb)}); + array{ + static_cast(n_terms), static_cast(norb), + static_cast(norb) + } + ); Tensor diag_tmp(slice_shape); diag_tmp.setZero(); diag_tmp = diag_slice; @@ -386,8 +400,11 @@ struct UCJOpSpinBalanced auto orb_slice = orbital_rotations_reshaped.slice( array{0, 0, 0}, - array{static_cast(n_terms), static_cast(norb), - static_cast(norb)}); + array{ + static_cast(n_terms), static_cast(norb), + static_cast(norb) + } + ); Tensor orb_tmp(slice_shape); orb_tmp.setZero(); orb_tmp = orb_slice; @@ -396,14 +413,13 @@ struct UCJOpSpinBalanced n_vecs = n_terms; } Tensor diag_coulomb_mats_stacked( - static_cast(n_vecs), 2, static_cast(norb), static_cast(norb)); + static_cast(n_vecs), 2, static_cast(norb), + static_cast(norb) + ); diag_coulomb_mats_stacked.setZero(); - for (int i = 0; i < n_vecs; ++i) - { - for (int j = 0; j < norb; ++j) - { - for (int k = 0; k < norb; ++k) - { + for (int i = 0; i < n_vecs; ++i) { + for (int j = 0; j < norb; ++j) { + for (int k = 0; k < norb; ++k) { Complex val = diag_coulomb_mats_reshaped(i, j, k); diag_coulomb_mats_stacked(i, 0, j, k) = val; diag_coulomb_mats_stacked(i, 1, j, k) = val; @@ -411,22 +427,22 @@ struct UCJOpSpinBalanced } } - if (n_reps.has_value() && n_vecs < n_reps.value()) - { + if (n_reps.has_value() && n_vecs < n_reps.value()) { size_t pad = n_reps.value() - n_vecs; - Tensor diag_coulomb_mats_pad(static_cast(pad), 2, static_cast(norb), - static_cast(norb)); + Tensor diag_coulomb_mats_pad( + static_cast(pad), 2, static_cast(norb), + static_cast(norb) + ); diag_coulomb_mats_pad.setZero(); diag_coulomb_mats_stacked = diag_coulomb_mats_stacked.concatenate(diag_coulomb_mats_pad, 0); - Tensor orbital_rotations_pad(static_cast(pad), static_cast(norb), - static_cast(norb)); + Tensor orbital_rotations_pad( + static_cast(pad), static_cast(norb), static_cast(norb) + ); orbital_rotations_pad.setZero(); - for (int p = 0; p < pad; ++p) - { - for (int i = 0; i < norb; ++i) - { + for (int p = 0; p < pad; ++p) { + for (int i = 0; i < norb; ++i) { orbital_rotations_pad(p, i, i) = Complex(1.0, 0.0); } } @@ -435,61 +451,74 @@ struct UCJOpSpinBalanced } std::optional final_orbital_rotation = std::nullopt; - if (t1.has_value()) - { - const MatrixXcd& t1_mat = t1.value(); - MatrixXcd final_orbital_rotation_generator = MatrixXcd::Zero(static_cast(norb), static_cast(norb)); - final_orbital_rotation_generator.block(0, static_cast(nocc), static_cast(nocc), static_cast(nvrt)) = t1_mat; - final_orbital_rotation_generator.block(static_cast(nocc), 0, static_cast(nvrt), static_cast(nocc)) = -t1_mat.adjoint(); + if (t1.has_value()) { + const MatrixXcd &t1_mat = t1.value(); + MatrixXcd final_orbital_rotation_generator = + MatrixXcd::Zero(static_cast(norb), static_cast(norb)); + final_orbital_rotation_generator.block( + 0, static_cast(nocc), static_cast(nocc), + static_cast(nvrt) + ) = t1_mat; + final_orbital_rotation_generator.block( + static_cast(nocc), 0, static_cast(nvrt), + static_cast(nocc) + ) = -t1_mat.adjoint(); final_orbital_rotation = linalg::expm(final_orbital_rotation_generator); } auto mask_and_zero = - [&](Tensor& tensor, size_t index, - const std::optional>>& pairs) - { - if (!pairs.has_value()) - return; - size_t n_vecs = tensor.dimension(0); - - std::vector> mask(norb, std::vector(norb, false)); - for (const auto& [i, j] : pairs.value()) - { - mask[i][j] = true; - mask[j][i] = true; - } + [&]( + Tensor &tensor, size_t index, + const std::optional>> &pairs + ) { + if (!pairs.has_value()) + return; + size_t n_vecs = tensor.dimension(0); + + std::vector> mask( + norb, std::vector(norb, false) + ); + for (const auto &[i, j] : pairs.value()) { + mask[i][j] = true; + mask[j][i] = true; + } - for (int v = 0; v < n_vecs; ++v) - { - for (int i = 0; i < norb; ++i) - { - for (int j = 0; j < norb; ++j) - { - if (!mask[i][j]) - { - tensor(v, static_cast(index), i, j) = Complex(0.0, 0.0); + for (int v = 0; v < n_vecs; ++v) { + for (int i = 0; i < norb; ++i) { + for (int j = 0; j < norb; ++j) { + if (!mask[i][j]) { + tensor(v, static_cast(index), i, j) = + Complex(0.0, 0.0); + } } } } - } - }; + }; mask_and_zero(diag_coulomb_mats_stacked, 0, interaction_pairs[0]); mask_and_zero(diag_coulomb_mats_stacked, 1, interaction_pairs[1]); - return UCJOpSpinBalanced(diag_coulomb_mats_stacked, orbital_rotations_reshaped, - final_orbital_rotation, true, 1e-5, 1e-8); + return UCJOpSpinBalanced( + diag_coulomb_mats_stacked, orbital_rotations_reshaped, + final_orbital_rotation, true, 1e-5, 1e-8 + ); } /** * @brief Returns the number of orbitals (norb). */ - size_t norb() const { return diag_coulomb_mats.dimension(3); } + size_t norb() const + { + return diag_coulomb_mats.dimension(3); + } /** * @brief Returns the number of repetitions (n_reps). */ - size_t n_reps() const { return diag_coulomb_mats.dimension(0); } + size_t n_reps() const + { + return diag_coulomb_mats.dimension(0); + } }; } // namespace ffsim diff --git a/ffsim/include/ffsim/utils.hpp b/ffsim/include/ffsim/utils.hpp index 16a39ed..43635a4 100644 --- a/ffsim/include/ffsim/utils.hpp +++ b/ffsim/include/ffsim/utils.hpp @@ -35,21 +35,19 @@ using namespace Eigen; * (false). * @return A vector of parameters representing the orbital rotation matrix. */ -VectorXd orbital_rotation_to_parameters(const MatrixXcd& orbital_rotation, bool real) +VectorXd orbital_rotation_to_parameters(const MatrixXcd &orbital_rotation, bool real) { - if (real) - { - for (int i = 0; i < orbital_rotation.rows(); ++i) - { - for (int j = 0; j < orbital_rotation.cols(); ++j) - { - if (std::abs(orbital_rotation(i, j).imag()) > 1e-12) - { - throw std::runtime_error("real was set to True, but the orbital " - "rotation has a complex data type. " - "Try passing an orbital rotation with a " - "real-valued data type, or else " - "set real=False."); + if (real) { + for (int i = 0; i < orbital_rotation.rows(); ++i) { + for (int j = 0; j < orbital_rotation.cols(); ++j) { + if (std::abs(orbital_rotation(i, j).imag()) > 1e-12) { + throw std::runtime_error( + "real was set to True, but the orbital " + "rotation has a complex data type. " + "Try passing an orbital rotation with a " + "real-valued data type, or else " + "set real=False." + ); } } } @@ -58,10 +56,8 @@ VectorXd orbital_rotation_to_parameters(const MatrixXcd& orbital_rotation, bool int norb = static_cast(orbital_rotation.rows()); std::vector> triu_indices_no_diag; - for (int i = 0; i < norb; ++i) - { - for (int j = i + 1; j < norb; ++j) - { + for (int i = 0; i < norb; ++i) { + for (int j = i + 1; j < norb; ++j) { triu_indices_no_diag.emplace_back(i, j); } } @@ -70,26 +66,23 @@ VectorXd orbital_rotation_to_parameters(const MatrixXcd& orbital_rotation, bool int param_len = real ? norb * (norb - 1) / 2 : norb * norb; VectorXd params = VectorXd::Zero(param_len); - for (size_t idx = 0; idx < triu_indices_no_diag.size(); ++idx) - { + for (size_t idx = 0; idx < triu_indices_no_diag.size(); ++idx) { auto [i, j] = triu_indices_no_diag[idx]; - params(static_cast(idx)) = mat(static_cast(i), static_cast(j)).real(); + params(static_cast(idx)) = + mat(static_cast(i), static_cast(j)).real(); } - if (!real) - { + if (!real) { std::vector> triu_indices; - for (int i = 0; i < norb; ++i) - { - for (int j = i; j < norb; ++j) - { + for (int i = 0; i < norb; ++i) { + for (int j = i; j < norb; ++j) { triu_indices.emplace_back(i, j); } } - for (size_t idx = 0; idx < triu_indices.size(); ++idx) - { + for (size_t idx = 0; idx < triu_indices.size(); ++idx) { auto [i, j] = triu_indices[idx]; - params(static_cast(idx + triu_indices_no_diag.size())) = mat(static_cast(i), static_cast(j)).imag(); + params(static_cast(idx + triu_indices_no_diag.size())) = + mat(static_cast(i), static_cast(j)).imag(); } } @@ -106,43 +99,41 @@ VectorXd orbital_rotation_to_parameters(const MatrixXcd& orbital_rotation, bool * (false). * @return The resulting orbital rotation matrix. */ -MatrixXcd orbital_rotation_from_parameters(const VectorXcd& params, int norb, bool real) +MatrixXcd orbital_rotation_from_parameters(const VectorXcd ¶ms, int norb, bool real) { std::vector> triu_indices_no_diag; - for (int i = 0; i < norb; ++i) - { - for (int j = i + 1; j < norb; ++j) - { + for (int i = 0; i < norb; ++i) { + for (int j = i + 1; j < norb; ++j) { triu_indices_no_diag.emplace_back(i, j); } } MatrixXcd generator = MatrixXcd::Zero(norb, norb); - if (!real) - { + if (!real) { std::vector> triu_indices; - for (int i = 0; i < norb; ++i) - { - for (int j = i; j < norb; ++j) - { + for (int i = 0; i < norb; ++i) { + for (int j = i; j < norb; ++j) { triu_indices.emplace_back(i, j); } } - for (size_t idx = 0; idx < triu_indices.size(); ++idx) - { + for (size_t idx = 0; idx < triu_indices.size(); ++idx) { auto [i, j] = triu_indices[idx]; - Complex imag_param_val = params[static_cast(idx + triu_indices_no_diag.size())]; - generator(static_cast(i), static_cast(j)) = Complex(0.0, imag_param_val.real()); - generator(static_cast(j), static_cast(i)) = Complex(0.0, imag_param_val.real()); + Complex imag_param_val = + params[static_cast(idx + triu_indices_no_diag.size())]; + generator(static_cast(i), static_cast(j)) = + Complex(0.0, imag_param_val.real()); + generator(static_cast(j), static_cast(i)) = + Complex(0.0, imag_param_val.real()); } } - for (size_t idx = 0; idx < triu_indices_no_diag.size(); ++idx) - { + for (size_t idx = 0; idx < triu_indices_no_diag.size(); ++idx) { auto [i, j] = triu_indices_no_diag[idx]; Complex param_val = params[static_cast(idx)]; - generator(static_cast(i), static_cast(j)) += Complex(param_val.real(), 0.0); - generator(static_cast(j), static_cast(i)) -= Complex(param_val.real(), 0.0); + generator(static_cast(i), static_cast(j)) += + Complex(param_val.real(), 0.0); + generator(static_cast(j), static_cast(i)) -= + Complex(param_val.real(), 0.0); } return linalg::expm(generator); }; @@ -157,16 +148,11 @@ MatrixXcd orbital_rotation_from_parameters(const VectorXcd& params, int norb, bo double round_for_acos(double value) { constexpr double EPSILON = 1e-12; - if (value > 1.0 && value < 1.0 + EPSILON) - { + if (value > 1.0 && value < 1.0 + EPSILON) { return 1.0; - } - else if (value < -1.0 && value > -1.0 - EPSILON) - { + } else if (value < -1.0 && value > -1.0 - EPSILON) { return -1.0; - } - else - { + } else { return value; } } @@ -179,31 +165,27 @@ double round_for_acos(double value) * @param rtol The relative tolerance for comparison. * @param atol The absolute tolerance for comparison. */ -void validate_orbital_rotation(const OrbitalRotation& mat, double rtol, double atol) +void validate_orbital_rotation(const OrbitalRotation &mat, double rtol, double atol) { - if (mat.type == OrbitalRotationType::Spinless) - { - if (!linalg::is_unitary(mat.spinless, rtol, atol)) - { - throw std::runtime_error("The input orbital rotation matrix was not unitary."); + if (mat.type == OrbitalRotationType::Spinless) { + if (!linalg::is_unitary(mat.spinless, rtol, atol)) { + throw std::runtime_error( + "The input orbital rotation matrix was not unitary." + ); } - } - else - { - if (const auto& matrix0_opt = mat.spinfull[0]; matrix0_opt.has_value()) - { - if (!linalg::is_unitary(matrix0_opt.value(), rtol, atol)) - { + } else { + if (const auto &matrix0_opt = mat.spinfull[0]; matrix0_opt.has_value()) { + if (!linalg::is_unitary(matrix0_opt.value(), rtol, atol)) { throw std::runtime_error( - "The input orbital rotation matrix for spin alpha was not unitary."); + "The input orbital rotation matrix for spin alpha was not unitary." + ); } } - if (const auto& matrix1_opt = mat.spinfull[1]; matrix1_opt.has_value()) - { - if (!linalg::is_unitary(matrix1_opt.value(), rtol, atol)) - { + if (const auto &matrix1_opt = mat.spinfull[1]; matrix1_opt.has_value()) { + if (!linalg::is_unitary(matrix1_opt.value(), rtol, atol)) { throw std::runtime_error( - "The input orbital rotation matrix for spin beta was not unitary."); + "The input orbital rotation matrix for spin beta was not unitary." + ); } } } diff --git a/src/load_parameters.hpp b/src/load_parameters.hpp index 6f5d067..904e966 100644 --- a/src/load_parameters.hpp +++ b/src/load_parameters.hpp @@ -20,16 +20,16 @@ #include -void load_initial_parameters(const std::string& filepath, uint64_t& norb, - std::pair& nelec, - std::vector>& alpha_alpha_indices, - std::vector>& alpha_beta_indices, - std::vector& init_params) +void load_initial_parameters( + const std::string &filepath, uint64_t &norb, std::pair &nelec, + std::vector> &alpha_alpha_indices, + std::vector> &alpha_beta_indices, + std::vector &init_params +) { std::ifstream i(filepath); - if (!i.is_open()) - { + if (!i.is_open()) { throw std::runtime_error("Could not open file: " + filepath); } @@ -38,34 +38,33 @@ void load_initial_parameters(const std::string& filepath, uint64_t& norb, norb = input["norb"].get(); - const auto& nelec_array = input["nelec"]; - if (!nelec_array.is_array() || nelec_array.size() != 2) - { + const auto &nelec_array = input["nelec"]; + if (!nelec_array.is_array() || nelec_array.size() != 2) { throw std::runtime_error("'nelec' must be an array of two integers."); } nelec.first = nelec_array[0].get(); nelec.second = nelec_array[1].get(); alpha_alpha_indices.clear(); - const auto& aa_indices = input["alpha_alpha_indices"]; - for (const auto& pair : aa_indices) - { - alpha_alpha_indices.emplace_back(pair[0].get(), pair[1].get()); + const auto &aa_indices = input["alpha_alpha_indices"]; + for (const auto &pair : aa_indices) { + alpha_alpha_indices.emplace_back( + pair[0].get(), pair[1].get() + ); } alpha_beta_indices.clear(); - const auto& ab_indices = input["alpha_beta_indices"]; - for (const auto& pair : ab_indices) - { - alpha_beta_indices.emplace_back(pair[0].get(), pair[1].get()); + const auto &ab_indices = input["alpha_beta_indices"]; + for (const auto &pair : ab_indices) { + alpha_beta_indices.emplace_back( + pair[0].get(), pair[1].get() + ); } init_params.clear(); - const auto& init_params_nodes = input["params"]; - for (const auto& param : init_params_nodes) - { - for (const auto& val : param) - { + const auto &init_params_nodes = input["params"]; + for (const auto ¶m : init_params_nodes) { + for (const auto &val : param) { init_params.push_back(val.get()); } } diff --git a/src/main.cpp b/src/main.cpp index e72a206..9dbf5c2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -47,21 +47,21 @@ using Sampler = BackendSamplerV2; // Test stub: generate num_samples random bitstrings of length num_bits // with Bernoulli(p=0.5) and aggregate into counts (bitstring -> occurrences). // Use this when a real backend/simulator is unavailable (debugging). -std::unordered_map -generate_counts_uniform(int num_samples, int num_bits, // NOLINT(bugprone-easily-swappable-parameters) - std::optional seed = std::nullopt) +std::unordered_map generate_counts_uniform( + int num_samples, // NOLINT(bugprone-easily-swappable-parameters) + int num_bits, // NOLINT(bugprone-easily-swappable-parameters) + std::optional seed = std::nullopt +) { std::mt19937 rng(seed.value_or(std::random_device{}())); std::bernoulli_distribution dist(0.5); std::unordered_map counts; - for (int i = 0; i < num_samples; ++i) - { + for (int i = 0; i < num_samples; ++i) { std::string bitstring; bitstring.reserve(num_bits); - for (int j = 0; j < num_bits; ++j) - { + for (int j = 0; j < num_bits; ++j) { bitstring += dist(rng) ? '1' : '0'; } counts[bitstring]++; @@ -70,14 +70,13 @@ generate_counts_uniform(int num_samples, int num_bits, // NOLINT(bugprone-easil } // Convert an array of boost::dynamic_bitset<> to string-based BitString objects. -static auto bitsets_to_bitstrings(const std::vector>& bitsets) +static auto bitsets_to_bitstrings(const std::vector> &bitsets) -> std::vector { std::vector bitstrings; bitstrings.reserve(bitsets.size()); std::string str; - for (const auto& bitset : bitsets) - { + for (const auto &bitset : bitsets) { boost::to_string(bitset, str); bitstrings.emplace_back(str); } @@ -85,13 +84,12 @@ static auto bitsets_to_bitstrings(const std::vector>& bi } // Convert string-based BitString objects back to boost::dynamic_bitset<>. // Internal representation for efficient bitwise operations in recovery/post-selection. -static auto bitsets_from_bitstrings(const std::vector& bitstrings) +static auto bitsets_from_bitstrings(const std::vector &bitstrings) -> std::vector> { std::vector> bitsets; bitsets.reserve(bitsets.size()); - for (const auto& bitstring : bitstrings) - { + for (const auto &bitstring : bitstrings) { bitsets.emplace_back(bitstring.to_string()); } return bitsets; @@ -100,7 +98,7 @@ static auto bitsets_from_bitstrings(const std::vector& bitstrings) // Load initial alpha/beta occupancies from a JSON file. // Format: { "init_occupancies": [ alpha..., beta... ] } (even length) // After splitting, reverse each to match the internal right-to-left convention. -std::array, 2> load_initial_occupancies(const std::string& filename) +std::array, 2> load_initial_occupancies(const std::string &filename) { std::ifstream i(filename); nlohmann::json input; @@ -108,17 +106,26 @@ std::array, 2> load_initial_occupancies(const std::string& f // Validate input JSON: throw on missing key to fail fast on user error. if (!input.contains("init_occupancies")) - throw std::invalid_argument("no init_params in initial parameter json: file=" + filename); + throw std::invalid_argument( + "no init_params in initial parameter json: file=" + filename + ); std::vector init_occupancy = input["init_occupancies"]; - if ((init_occupancy.size() & 1) != 0) - { - throw std::runtime_error("Initial occupancies list must have even number of elements"); + if ((init_occupancy.size() & 1) != 0) { + throw std::runtime_error( + "Initial occupancies list must have even number of elements" + ); } const auto half_size = init_occupancy.size() / 2; - std::vector alpha_occupancy(init_occupancy.begin(), init_occupancy.begin() + static_cast(half_size)); - std::vector beta_occupancy(init_occupancy.begin() + static_cast(half_size), init_occupancy.end()); + std::vector alpha_occupancy( + init_occupancy.begin(), + init_occupancy.begin() + static_cast(half_size) + ); + std::vector beta_occupancy( + init_occupancy.begin() + static_cast(half_size), + init_occupancy.end() + ); std::reverse(alpha_occupancy.begin(), alpha_occupancy.end()); std::reverse(beta_occupancy.begin(), beta_occupancy.end()); @@ -129,24 +136,25 @@ std::array, 2> load_initial_occupancies(const std::string& f // Utility: normalize counts (occurrences) into probabilities in [0,1]. // Empty input returns an empty map (no exception). std::unordered_map -normalize_counts_dict(const std::unordered_map& counts) +normalize_counts_dict(const std::unordered_map &counts) { // Check if the input map is empty - if (counts.empty()) - { + if (counts.empty()) { return {}; // Return an empty map } // Calculate the total counts - uint64_t total_counts = - std::accumulate(counts.begin(), counts.end(), 0, - [](uint64_t sum, const auto& pair) { return sum + pair.second; }); + uint64_t total_counts = std::accumulate( + counts.begin(), counts.end(), 0, [](uint64_t sum, const auto &pair) { + return sum + pair.second; + } + ); // Create a new map with normalized values std::unordered_map probabilities; - for (const auto& [key, value] : counts) - { - probabilities[key] = static_cast(value) / static_cast(total_counts); + for (const auto &[key, value] : counts) { + probabilities[key] = + static_cast(value) / static_cast(total_counts); } return probabilities; @@ -155,7 +163,7 @@ normalize_counts_dict(const std::unordered_map& counts) // Transform counts (bitstring -> count) into parallel arrays (bitstrings, // probabilities). std::pair, std::vector> -counts_to_arrays(const std::unordered_map& counts) +counts_to_arrays(const std::unordered_map &counts) { std::vector bs_mat; std::vector freq_arr; @@ -167,14 +175,12 @@ counts_to_arrays(const std::unordered_map& counts) auto prob_dict = normalize_counts_dict(counts); // Convert bitstrings to a 2D boolean matrix - for (const auto& [bitstring, _] : prob_dict) - { + for (const auto &[bitstring, _] : prob_dict) { bs_mat.push_back(BitString(bitstring)); } // Convert probabilities to a 1D array - for (const auto& [_, probability] : prob_dict) - { + for (const auto &[_, probability] : prob_dict) { freq_arr.push_back(probability); } @@ -184,286 +190,284 @@ counts_to_arrays(const std::unordered_map& counts) using namespace Eigen; using namespace ffsim; -int main(int argc, char* argv[]) +int main(int argc, char *argv[]) { - try - { - // ===== MPI initialization ===== - // This workflow assumes MPI. Request FUNNELED (only main thread calls MPI). - int provided; - int mpi_init_error = MPI_Init_thread(&argc, &argv, MPI_THREAD_FUNNELED, &provided); - if (mpi_init_error != MPI_SUCCESS) - { - char err_msg[1024]; - int err_msg_len; - MPI_Error_string(mpi_init_error, err_msg, &err_msg_len); - // On failure, print a readable error and exit immediately (cluster-friendly - // diagnostics). - std::cerr << "MPI_Init failed: " << err_msg << std::endl; - return mpi_init_error; - } + try { + // ===== MPI initialization ===== + // This workflow assumes MPI. Request FUNNELED (only main thread calls MPI). + int provided; + int mpi_init_error = + MPI_Init_thread(&argc, &argv, MPI_THREAD_FUNNELED, &provided); + if (mpi_init_error != MPI_SUCCESS) { + char err_msg[1024]; + int err_msg_len; + MPI_Error_string(mpi_init_error, err_msg, &err_msg_len); + // On failure, print a readable error and exit immediately (cluster-friendly + // diagnostics). + std::cerr << "MPI_Init failed: " << err_msg << std::endl; + return mpi_init_error; + } - // ===== SBD (diagonalization sub-workflow) configuration ===== - // Build SBD parameters from CLI args. Used by sbd_main for energy evaluation, etc. - SBD diag_data = generate_sbd_data(argc, argv); - - // ===== SQD (sampling/recovery sub-workflow) configuration ===== - // Holds run_id, backend, shot count, and other metadata for sampling and recovery. - SQD sqd_data = generate_sqd_data(argc, argv); - sqd_data.comm = MPI_COMM_WORLD; - MPI_Comm_rank(sqd_data.comm, &sqd_data.mpi_rank); - MPI_Comm_size(sqd_data.comm, &sqd_data.mpi_size); - int message_size = static_cast(sqd_data.run_id.size()); - MPI_Bcast(&message_size, 1, MPI_INT, 0, MPI_COMM_WORLD); - if (sqd_data.mpi_rank != 0) - { - sqd_data.run_id.resize(message_size); - } - // Broadcast the textual run_id to all ranks to keep logs/artifacts consistent. - // Rank 0 sends the size, others resize buffer, then receive content. - MPI_Bcast(sqd_data.run_id.data(), message_size, MPI_CHAR, 0, MPI_COMM_WORLD); - - // Random generators: - // - rng : used for sampling/subsampling (fixed seed for reproducibility). - // - rc_rng : used for configuration recovery randomness (derived from rng). - std::mt19937 rng(1234); - std::mt19937 rc_rng(rng()); - // Batch sizing for SBD input (alpha-determinant groups). - uint64_t samples_per_batch = sqd_data.samples_per_batch; - - // Read initial parameters (norb, nelec, params for lucj) from JSON. - const std::string input_file_path = "../data/parameters_fe4s4.json"; - double tol = 1e-8; - uint64_t norb; - size_t n_reps = 1; - std::pair nelec; - std::vector> interaction_aa; - std::vector> interaction_ab; - std::vector init_params; - - // Centralize I/O on rank 0. Abort the whole job on input failure. - if (sqd_data.mpi_rank == 0) - { - try - { - load_initial_parameters(input_file_path, norb, nelec, interaction_aa, interaction_ab, - init_params); + // ===== SBD (diagonalization sub-workflow) configuration ===== + // Build SBD parameters from CLI args. Used by sbd_main for energy evaluation, + // etc. + SBD diag_data = generate_sbd_data(argc, argv); + + // ===== SQD (sampling/recovery sub-workflow) configuration ===== + // Holds run_id, backend, shot count, and other metadata for sampling and + // recovery. + SQD sqd_data = generate_sqd_data(argc, argv); + sqd_data.comm = MPI_COMM_WORLD; + MPI_Comm_rank(sqd_data.comm, &sqd_data.mpi_rank); + MPI_Comm_size(sqd_data.comm, &sqd_data.mpi_size); + int message_size = static_cast(sqd_data.run_id.size()); + MPI_Bcast(&message_size, 1, MPI_INT, 0, MPI_COMM_WORLD); + if (sqd_data.mpi_rank != 0) { + sqd_data.run_id.resize(message_size); } - catch (const std::exception& e) - { - std::cerr << "Error loading initial parameters: " << e.what() << std::endl; - MPI_Abort(sqd_data.comm, 1); - return 1; + // Broadcast the textual run_id to all ranks to keep logs/artifacts consistent. + // Rank 0 sends the size, others resize buffer, then receive content. + MPI_Bcast(sqd_data.run_id.data(), message_size, MPI_CHAR, 0, MPI_COMM_WORLD); + + // Random generators: + // - rng : used for sampling/subsampling (fixed seed for reproducibility). + // - rc_rng : used for configuration recovery randomness (derived from rng). + std::mt19937 rng(1234); + std::mt19937 rc_rng(rng()); + // Batch sizing for SBD input (alpha-determinant groups). + uint64_t samples_per_batch = sqd_data.samples_per_batch; + + // Read initial parameters (norb, nelec, params for lucj) from JSON. + const std::string input_file_path = "../data/parameters_fe4s4.json"; + double tol = 1e-8; + uint64_t norb; + size_t n_reps = 1; + std::pair nelec; + std::vector> interaction_aa; + std::vector> interaction_ab; + std::vector init_params; + + // Centralize I/O on rank 0. Abort the whole job on input failure. + if (sqd_data.mpi_rank == 0) { + try { + load_initial_parameters( + input_file_path, norb, nelec, interaction_aa, interaction_ab, + init_params + ); + } catch (const std::exception &e) { + std::cerr << "Error loading initial parameters: " << e.what() + << std::endl; + MPI_Abort(sqd_data.comm, 1); + return 1; + } + log(sqd_data, {"initial parameters are loaded. param_length=", + std::to_string(init_params.size())}); } - log(sqd_data, - {"initial parameters are loaded. param_length=", std::to_string(init_params.size())}); - } - // Measurement results: (bitstring -> counts). Produced on rank 0, then array-ified - // later. - std::unordered_map counts; + // Measurement results: (bitstring -> counts). Produced on rank 0, then + // array-ified later. + std::unordered_map counts; - auto num_elec_a = nelec.first; - auto num_elec_b = nelec.second; - if (sqd_data.mpi_rank == 0) - { + auto num_elec_a = nelec.first; + auto num_elec_b = nelec.second; + if (sqd_data.mpi_rank == 0) { // ===== Sampling mode switch ===== // a) Mock: generate_counts_uniform (debugging) // b) Real: build LUCJ circuit -> transpile -> run on backend with Sampler -> get counts #if USE_RANDOM_SHOTS != 0 - counts = generate_counts_uniform(sqd_data.num_shots, 2 * norb, 1234); + counts = generate_counts_uniform(sqd_data.num_shots, 2 * norb, 1234); #else - //////////////// LUCJ Circuit Generation //////////////// - size_t params_size = init_params.size(); + //////////////// LUCJ Circuit Generation //////////////// + size_t params_size = init_params.size(); - Eigen::VectorXcd params(params_size); - for (size_t i = 0; i < params_size; ++i) - { - params(static_cast(i)) = init_params[i]; - } - std::optional t1 = std::nullopt; - // 'interaction_pairs' allows passing (alpha-alpha, alpha-beta/beta-beta) - // coupling patterns. - std::array>>, 2> interaction_pairs = - {std::make_optional>>(interaction_aa), - std::make_optional>>(interaction_ab)}; - - // Construct the spin-balanced UCJ operator from parameter vector. - - UCJOpSpinBalanced ucj_op = - UCJOpSpinBalanced::from_parameters(params, norb, n_reps, interaction_pairs, true); - std::vector qubits(2 * norb); - std::iota(qubits.begin(), qubits.end(), 0); - auto instructions = hf_and_ucj_op_spin_balanced_jw(qubits, nelec, ucj_op); - - // Quantum circuit with Qiskit C++ - auto qr = QuantumRegister(2 * norb); // quantum registers - auto cr = ClassicalRegister(2 * norb); // classical registers - auto circ = QuantumCircuit(qr, cr); // create a quantum circuits with registers - - // add gates from instruction list from hf_and_ucj_op_spin_balanced_jw - // for demo: calling Qiskit C++ circuit functions to make quantum circuit - for (const auto& instr : instructions) - { - if (std::string("x") == instr.gate) - { - // X gate - circ.x(instr.qubits[0]); + Eigen::VectorXcd params(params_size); + for (size_t i = 0; i < params_size; ++i) { + params(static_cast(i)) = init_params[i]; } - else if (std::string("rz") == instr.gate) - { - // RZ gate - circ.rz(instr.params[0], instr.qubits[0]); + std::optional t1 = std::nullopt; + // 'interaction_pairs' allows passing (alpha-alpha, alpha-beta/beta-beta) + // coupling patterns. + std::array>>, 2> + interaction_pairs = { + std::make_optional>>( + interaction_aa + ), + std::make_optional>>( + interaction_ab + ) + }; + + // Construct the spin-balanced UCJ operator from parameter vector. + + UCJOpSpinBalanced ucj_op = UCJOpSpinBalanced::from_parameters( + params, norb, n_reps, interaction_pairs, true + ); + std::vector qubits(2 * norb); + std::iota(qubits.begin(), qubits.end(), 0); + auto instructions = hf_and_ucj_op_spin_balanced_jw(qubits, nelec, ucj_op); + + // Quantum circuit with Qiskit C++ + auto qr = QuantumRegister(2 * norb); // quantum registers + auto cr = ClassicalRegister(2 * norb); // classical registers + auto circ = + QuantumCircuit(qr, cr); // create a quantum circuits with registers + + // add gates from instruction list from hf_and_ucj_op_spin_balanced_jw + // for demo: calling Qiskit C++ circuit functions to make quantum circuit + for (const auto &instr : instructions) { + if (std::string("x") == instr.gate) { + // X gate + circ.x(instr.qubits[0]); + } else if (std::string("rz") == instr.gate) { + // RZ gate + circ.rz(instr.params[0], instr.qubits[0]); + } else if (std::string("cp") == instr.gate) { + // controlled phase gate + circ.cp(instr.params[0], instr.qubits[0], instr.qubits[1]); + } else if (std::string("xx_plus_yy") == instr.gate) { + // XX_plus_YY gate + circ.xx_plus_yy( + instr.params[0], instr.params[1], instr.qubits[0], + instr.qubits[1] + ); + } } - else if (std::string("cp") == instr.gate) - { - // controlled phase gate - circ.cp(instr.params[0], instr.qubits[0], instr.qubits[1]); + // this is smarter way using standard gate mapping to convert gate name to + // op auto map = get_standard_gate_name_mapping(); for (const auto &instr : + // instructions) { + // auto op = map[instr.gate]; + // if (instr.params.size() > 0) + // op.set_params(instr.params); + // circ.append(op, instr.qubits); + // } + + // sampling all the qubits + for (size_t i = 0; i < circ.num_qubits(); ++i) { + circ.measure(i, i); } - else if (std::string("xx_plus_yy") == instr.gate) - { - // XX_plus_YY gate - circ.xx_plus_yy(instr.params[0], instr.params[1], instr.qubits[0], instr.qubits[1]); - } - } - // this is smarter way using standard gate mapping to convert gate name to op - // auto map = get_standard_gate_name_mapping(); - // for (const auto &instr : instructions) { - // auto op = map[instr.gate]; - // if (instr.params.size() > 0) - // op.set_params(instr.params); - // circ.append(op, instr.qubits); - // } - - // sampling all the qubits - for (size_t i = 0; i < circ.num_qubits(); ++i) - { - circ.measure(i, i); - } - // get backend from Quantum Runtime Service - // set 2 environment variables before executing - // QISKIT_IBM_TOKEN = "your API key" - // QISKIT_IBM_INSTANCE = "your CRN" - std::string backend_name = sqd_data.backend_name; - auto service = QiskitRuntimeService(); - auto backend = service.backend(backend_name); + // get backend from Quantum Runtime Service + // set 2 environment variables before executing + // QISKIT_IBM_TOKEN = "your API key" + // QISKIT_IBM_INSTANCE = "your CRN" + std::string backend_name = sqd_data.backend_name; + auto service = QiskitRuntimeService(); + auto backend = service.backend(backend_name); - // Transpile a quantum circuit for the target backend. - auto transpiled = transpile(circ, backend); + // Transpile a quantum circuit for the target backend. + auto transpiled = transpile(circ, backend); - uint64_t num_shots = sqd_data.num_shots; + uint64_t num_shots = sqd_data.num_shots; - // Configure the Sampler execution (num_shots from SQD configuration). - auto sampler = Sampler(backend, num_shots); + // Configure the Sampler execution (num_shots from SQD configuration). + auto sampler = Sampler(backend, num_shots); - auto job = sampler.run({SamplerPub(transpiled)}); - if (job == nullptr) - return -1; - auto result = job->result(); - auto pub_result = result[0]; + auto job = sampler.run({SamplerPub(transpiled)}); + if (job == nullptr) + return -1; + auto result = job->result(); + auto pub_result = result[0]; - // Extract classical counts from the execution result. - // These form the classical distribution for downstream recovery/selection. - counts = pub_result.data().get_counts(); + // Extract classical counts from the execution result. + // These form the classical distribution for downstream recovery/selection. + counts = pub_result.data().get_counts(); #endif // USE_RANDOM_SHOTS - } + } - ////// Configuration Recovery, Post Selection, Diagonalization ////// + ////// Configuration Recovery, Post Selection, Diagonalization ////// - // Expand counts (map) into (bitstrings[], probs[]). - auto [bitstring_matrix_full_, probs_arr_full] = counts_to_arrays(counts); - auto bitstring_matrix_full = bitsets_from_bitstrings(bitstring_matrix_full_); + // Expand counts (map) into (bitstrings[], probs[]). + auto [bitstring_matrix_full_, probs_arr_full] = counts_to_arrays(counts); + auto bitstring_matrix_full = bitsets_from_bitstrings(bitstring_matrix_full_); - std::vector> bs_mat_tmp; - std::vector probs_arr_tmp; - std::array, 2> latest_occupancies, initial_occupancies; - int n_recovery = static_cast(sqd_data.n_recovery); + std::vector> bs_mat_tmp; + std::vector probs_arr_tmp; + std::array, 2> latest_occupancies, initial_occupancies; + int n_recovery = static_cast(sqd_data.n_recovery); - try - { - // Load prior alpha/beta occupancies used as the initial distribution for - // recovery. - initial_occupancies = load_initial_occupancies("../data/initial_occupancies_fe4s4.json"); - } - catch (const std::invalid_argument& e) - { - std::cerr << "Error loading initial occupancies: " << e.what() << std::endl; - return 1; - } - // ===== Configuration recovery loop (n_recovery iterations) ===== - // Each iter: recover_configurations → postselect → subsample → SBD (diagonalize) → - // update occupancies. - for (uint64_t i_recovery = 0; i_recovery < n_recovery; ++i_recovery) - { - log(sqd_data, {"start recovery: iteration=", std::to_string(i_recovery)}); - - // Iteration 0: feed full bitstring/probability sets and seed recovery from - // initial occupancies. - if (i_recovery == 0) - { - bs_mat_tmp = bitstring_matrix_full; - probs_arr_tmp = probs_arr_full; - latest_occupancies = initial_occupancies; - } - if (sqd_data.mpi_rank == 0) - { - // Recover physically consistent configurations from observed probabilities - // + prior occupancies. - auto recovered = Qiskit::addon::sqd::recover_configurations( - bitstring_matrix_full, probs_arr_full, latest_occupancies, {num_elec_a, num_elec_b}, - rc_rng); - bs_mat_tmp = std::move(recovered.first); - probs_arr_tmp = std::move(recovered.second); - - std::vector> batch; - // Post-selection: accept bitstrings whose left/right (alpha/beta) Hamming - // weights match target electron counts. - auto [postselected_bitstrings, postselected_probs] = - Qiskit::addon::sqd::postselect_bitstrings( - bs_mat_tmp, probs_arr_tmp, - Qiskit::addon::sqd::MatchesRightLeftHamming(num_elec_a, num_elec_b)); - log(sqd_data, {"Number of postselected bitstrings: ", - std::to_string(postselected_bitstrings.size())}); - - // Subsample to a single batch of fixed size for SBD, to cap IO/compute per - // iteration. - Qiskit::addon::sqd::subsample(batch, postselected_bitstrings, postselected_probs, - samples_per_batch, rng); - // Write alpha-determinants file for SBD input (includes run id / iteration - // for traceability). - diag_data.adetfile = - write_alphadets_file(sqd_data, norb, num_elec_a, bitsets_to_bitstrings(batch), - sqd_data.samples_per_batch * 2, i_recovery); + try { + // Load prior alpha/beta occupancies used as the initial distribution for + // recovery. + initial_occupancies = + load_initial_occupancies("../data/initial_occupancies_fe4s4.json"); + } catch (const std::invalid_argument &e) { + std::cerr << "Error loading initial occupancies: " << e.what() << std::endl; + return 1; } - // Run SBD to get energy and batch occupancies (interleaved alpha/beta...). - // Energy goes to logs; occupancies seed the next iteration. - auto [energy_sci, occs_batch] = sbd_main(sqd_data.comm, diag_data); - log(sqd_data, {"energy: ", std::to_string(energy_sci)}); - - // Convert interleaved [alpha0, beta0, alpha1, beta1, ...] to { alpha[], beta[] - // }. NOTE: assert ensures occs_batch size matches 2 * alpha.size(). - assert(2 * latest_occupancies[0].size() == occs_batch.size()); - for (std::size_t j = 0; j < latest_occupancies[0].size(); ++j) - { - latest_occupancies[0][j] = occs_batch[2 * j]; // alpha orbital - latest_occupancies[1][j] = occs_batch[2 * j + 1]; // beta orbital + // ===== Configuration recovery loop (n_recovery iterations) ===== + // Each iter: recover_configurations → postselect → subsample → SBD + // (diagonalize) → update occupancies. + for (uint64_t i_recovery = 0; i_recovery < n_recovery; ++i_recovery) { + log(sqd_data, {"start recovery: iteration=", std::to_string(i_recovery)}); + + // Iteration 0: feed full bitstring/probability sets and seed recovery from + // initial occupancies. + if (i_recovery == 0) { + bs_mat_tmp = bitstring_matrix_full; + probs_arr_tmp = probs_arr_full; + latest_occupancies = initial_occupancies; + } + if (sqd_data.mpi_rank == 0) { + // Recover physically consistent configurations from observed + // probabilities + // + prior occupancies. + auto recovered = Qiskit::addon::sqd::recover_configurations( + bitstring_matrix_full, probs_arr_full, latest_occupancies, + {num_elec_a, num_elec_b}, rc_rng + ); + bs_mat_tmp = std::move(recovered.first); + probs_arr_tmp = std::move(recovered.second); + + std::vector> batch; + // Post-selection: accept bitstrings whose left/right (alpha/beta) + // Hamming weights match target electron counts. + auto [postselected_bitstrings, postselected_probs] = + Qiskit::addon::sqd::postselect_bitstrings( + bs_mat_tmp, probs_arr_tmp, + Qiskit::addon::sqd::MatchesRightLeftHamming( + num_elec_a, num_elec_b + ) + ); + log(sqd_data, {"Number of postselected bitstrings: ", + std::to_string(postselected_bitstrings.size())}); + + // Subsample to a single batch of fixed size for SBD, to cap IO/compute + // per iteration. + Qiskit::addon::sqd::subsample( + batch, postselected_bitstrings, postselected_probs, + samples_per_batch, rng + ); + // Write alpha-determinants file for SBD input (includes run id / + // iteration for traceability). + diag_data.adetfile = write_alphadets_file( + sqd_data, norb, num_elec_a, bitsets_to_bitstrings(batch), + sqd_data.samples_per_batch * 2, i_recovery + ); + } + // Run SBD to get energy and batch occupancies (interleaved alpha/beta...). + // Energy goes to logs; occupancies seed the next iteration. + auto [energy_sci, occs_batch] = sbd_main(sqd_data.comm, diag_data); + log(sqd_data, {"energy: ", std::to_string(energy_sci)}); + + // Convert interleaved [alpha0, beta0, alpha1, beta1, ...] to { alpha[], + // beta[] + // }. NOTE: assert ensures occs_batch size matches 2 * alpha.size(). + assert(2 * latest_occupancies[0].size() == occs_batch.size()); + for (std::size_t j = 0; j < latest_occupancies[0].size(); ++j) { + latest_occupancies[0][j] = occs_batch[2 * j]; // alpha orbital + latest_occupancies[1][j] = occs_batch[2 * j + 1]; // beta orbital + } } - } // Synchronize and tear down MPI. No MPI calls are allowed beyond this point. MPI_Finalize(); return 0; - } - catch (const std::exception& e) - { + } catch (const std::exception &e) { std::cerr << "Unhandled exception in main: " << e.what() << std::endl; MPI_Finalize(); return 1; - } - catch (...) - { + } catch (...) { std::cerr << "Unknown exception in main" << std::endl; MPI_Finalize(); return 1; diff --git a/src/sbd_helper.hpp b/src/sbd_helper.hpp index 02d12ca..5aa31b5 100644 --- a/src/sbd_helper.hpp +++ b/src/sbd_helper.hpp @@ -32,8 +32,7 @@ #include "mpi.h" #include "sbd/sbd.h" -struct SBD -{ +struct SBD { int task_comm_size = 1; int adet_comm_size = 1; int bdet_comm_size = 1; @@ -55,48 +54,39 @@ struct SBD std::string fcidumpfile = ""; }; -SBD generate_sbd_data(int argc, char* argv[]) +SBD generate_sbd_data(int argc, char *argv[]) { SBD sbd; - for (int i = 1; i < argc; i++) - { - if (std::string(argv[i]) == "--fcidump") - { + for (int i = 1; i < argc; i++) { + if (std::string(argv[i]) == "--fcidump") { sbd.fcidumpfile = std::string(argv[i + 1]); i++; } - if (std::string(argv[i]) == "--iteration") - { + if (std::string(argv[i]) == "--iteration") { sbd.max_it = std::atoi(argv[i + 1]); i++; } - if (std::string(argv[i]) == "--block") - { + if (std::string(argv[i]) == "--block") { sbd.max_nb = std::atoi(argv[i + 1]); i++; } - if (std::string(argv[i]) == "--tolerance") - { + if (std::string(argv[i]) == "--tolerance") { sbd.eps = std::atof(argv[i + 1]); i++; } - if (std::string(argv[i]) == "--max_time") - { + if (std::string(argv[i]) == "--max_time") { sbd.max_time = std::atof(argv[i + 1]); i++; } - if (std::string(argv[i]) == "--adet_comm_size") - { + if (std::string(argv[i]) == "--adet_comm_size") { sbd.adet_comm_size = std::atoi(argv[i + 1]); i++; } - if (std::string(argv[i]) == "--bdet_comm_size") - { + if (std::string(argv[i]) == "--bdet_comm_size") { sbd.bdet_comm_size = std::atoi(argv[i + 1]); i++; } - if (std::string(argv[i]) == "--task_comm_size") - { + if (std::string(argv[i]) == "--task_comm_size") { sbd.task_comm_size = std::atoi(argv[i + 1]); i++; } @@ -105,7 +95,8 @@ SBD generate_sbd_data(int argc, char* argv[]) } // energy, occupancy -std::tuple> sbd_main(const MPI_Comm& comm, const SBD& sbd_data) +std::tuple> +sbd_main(const MPI_Comm &comm, const SBD &sbd_data) { double E = 0.0; @@ -138,8 +129,7 @@ std::tuple> sbd_main(const MPI_Comm& comm, const SBD base_comm_size = adet_comm_size * bdet_comm_size * task_comm_size; int h_comm_size = mpi_size / base_comm_size; - if (mpi_size != base_comm_size * h_comm_size) - { + if (mpi_size != base_comm_size * h_comm_size) { throw std::invalid_argument("communicator size is not appropriate"); } @@ -148,8 +138,7 @@ std::tuple> sbd_main(const MPI_Comm& comm, const SBD */ sbd::FCIDump fcidump; - if (mpi_rank == 0) - { + if (mpi_rank == 0) { fcidump = sbd::LoadFCIDump(fcidumpfile); } sbd::MpiBcast(fcidump, 0, comm); @@ -165,8 +154,7 @@ std::tuple> sbd_main(const MPI_Comm& comm, const SBD std::vector> adet; std::vector> bdet; - if (mpi_rank == 0) - { + if (mpi_rank == 0) { adet = sbd::DecodeAlphaDets(adetfile, L); sbd::change_bitlength(1, adet, bit_length); sbd::sort_bitarray(adet); @@ -183,13 +171,19 @@ std::tuple> sbd_main(const MPI_Comm& comm, const SBD MPI_Comm h_comm; MPI_Comm b_comm; MPI_Comm t_comm; - sbd::TaskCommunicator(comm, h_comm_size, adet_comm_size, bdet_comm_size, task_comm_size, h_comm, - b_comm, t_comm); - - sbd::MakeHelpers(adet, bdet, bit_length, L, helper, sharedMemory, h_comm, b_comm, t_comm, - adet_comm_size, bdet_comm_size); - sbd::RemakeHelpers(adet, bdet, bit_length, L, helper, sharedMemory, h_comm, b_comm, t_comm, - adet_comm_size, bdet_comm_size); + sbd::TaskCommunicator( + comm, h_comm_size, adet_comm_size, bdet_comm_size, task_comm_size, h_comm, + b_comm, t_comm + ); + + sbd::MakeHelpers( + adet, bdet, bit_length, L, helper, sharedMemory, h_comm, b_comm, t_comm, + adet_comm_size, bdet_comm_size + ); + sbd::RemakeHelpers( + adet, bdet, bit_length, L, helper, sharedMemory, h_comm, b_comm, t_comm, + adet_comm_size, bdet_comm_size + ); int mpi_rank_h; MPI_Comm_rank(h_comm, &mpi_rank_h); @@ -208,25 +202,31 @@ std::tuple> sbd_main(const MPI_Comm& comm, const SBD Initialize/Load wave function */ std::vector W; - sbd::BasisInitVector(W, adet, bdet, adet_comm_size, bdet_comm_size, h_comm, b_comm, t_comm, - init); + sbd::BasisInitVector( + W, adet, bdet, adet_comm_size, bdet_comm_size, h_comm, b_comm, t_comm, init + ); /** Diagonalization */ std::vector hii; auto time_start_diag = std::chrono::high_resolution_clock::now(); - sbd::makeQChamDiagTerms(adet, bdet, bit_length, L, helper, I0, I1, I2, hii, h_comm, b_comm, - t_comm); - sbd::Davidson(hii, W, adet, bdet, bit_length, static_cast(L), adet_comm_size, - bdet_comm_size, helper, I0, I1, I2, h_comm, b_comm, t_comm, max_it, max_nb, eps, - max_time); + sbd::makeQChamDiagTerms( + adet, bdet, bit_length, L, helper, I0, I1, I2, hii, h_comm, b_comm, t_comm + ); + sbd::Davidson( + hii, W, adet, bdet, bit_length, static_cast(L), adet_comm_size, + bdet_comm_size, helper, I0, I1, I2, h_comm, b_comm, t_comm, max_it, max_nb, eps, + max_time + ); auto time_end_diag = std::chrono::high_resolution_clock::now(); - auto elapsed_diag_count = - std::chrono::duration_cast(time_end_diag - time_start_diag) - .count(); + auto elapsed_diag_count = std::chrono::duration_cast( + time_end_diag - time_start_diag + ) + .count(); double elapsed_diag = 0.000001 * static_cast(elapsed_diag_count); if (mpi_rank == 0) - std::cout << " Elapsed time for diagonalization " << elapsed_diag << " (sec) " << std::endl; + std::cout << " Elapsed time for diagonalization " << elapsed_diag << " (sec) " + << std::endl; /** Evaluation of Hamiltonian expectation value @@ -234,17 +234,17 @@ std::tuple> sbd_main(const MPI_Comm& comm, const SBD std::vector C(W.size(), 0.0); - sbd::mult(hii, W, C, adet, bdet, bit_length, static_cast(L), adet_comm_size, - bdet_comm_size, helper, I0, I1, I2, h_comm, b_comm, t_comm); + sbd::mult( + hii, W, C, adet, bdet, bit_length, static_cast(L), adet_comm_size, + bdet_comm_size, helper, I0, I1, I2, h_comm, b_comm, t_comm + ); sbd::InnerProduct(W, C, E, b_comm); - if (energy_target != 0.0 && std::abs(E - energy_target) > energy_variance) - { + if (energy_target != 0.0 && std::abs(E - energy_target) > energy_variance) { E = 0.0; } - if (mpi_rank == 0) - { + if (mpi_rank == 0) { std::cout.precision(16); std::cout << " Energy = " << E << std::endl; } @@ -261,18 +261,23 @@ std::tuple> sbd_main(const MPI_Comm& comm, const SBD std::vector oIdx(o_size); std::iota(oIdx.begin(), oIdx.end(), o_start); std::vector res_density; - sbd::OccupationDensity(oIdx, W, adet, bdet, bit_length, adet_comm_size, bdet_comm_size, b_comm, - res_density); + sbd::OccupationDensity( + oIdx, W, adet, bdet, bit_length, adet_comm_size, bdet_comm_size, b_comm, + res_density + ); std::vector density_rank(static_cast(2 * L), 0.0); std::vector density_group(static_cast(2 * L), 0.0); std::vector density(static_cast(2 * L), 0.0); - for (size_t io = o_start; io < o_end; io++) - { + for (size_t io = o_start; io < o_end; io++) { density_rank[2 * io] = res_density[2 * (io - o_start)]; density_rank[2 * io + 1] = res_density[2 * (io - o_start) + 1]; } - MPI_Allreduce(density_rank.data(), density_group.data(), 2 * L, MPI_DOUBLE, MPI_SUM, t_comm); - MPI_Allreduce(density_group.data(), density.data(), 2 * L, MPI_DOUBLE, MPI_SUM, h_comm); + MPI_Allreduce( + density_rank.data(), density_group.data(), 2 * L, MPI_DOUBLE, MPI_SUM, t_comm + ); + MPI_Allreduce( + density_group.data(), density.data(), 2 * L, MPI_DOUBLE, MPI_SUM, h_comm + ); FreeHelpers(helper); return {E, density}; diff --git a/src/sqd_helper.hpp b/src/sqd_helper.hpp index 73f1358..7a8bfea 100644 --- a/src/sqd_helper.hpp +++ b/src/sqd_helper.hpp @@ -36,11 +36,15 @@ std::string get_time(bool compact = false) auto in_time_t = std::chrono::system_clock::to_time_t(now); std::stringstream ss; if (compact) - ss << std::put_time(std::localtime(&in_time_t), - "%Y%m%d%H%M%S"); // Format: YYYYMMDDHHMMSS + ss << std::put_time( + std::localtime(&in_time_t), + "%Y%m%d%H%M%S" + ); // Format: YYYYMMDDHHMMSS else - ss << std::put_time(std::localtime(&in_time_t), - "%Y-%m-%d %H:%M:%S"); // Format: YYYY-MM-DD HH:MM:SS + ss << std::put_time( + std::localtime(&in_time_t), + "%Y-%m-%d %H:%M:%S" + ); // Format: YYYY-MM-DD HH:MM:SS return ss.str(); } @@ -48,8 +52,7 @@ std::string get_time(bool compact = false) // [false, false, true, true] is data[0]=0b0011 // [false, false, false, true, true] is data[0]=0b00011 // [false, true, false, true x 64] is data[0]=0b010, data[1]= 0xffff -struct UArrayString -{ +struct UArrayString { std::vector data; // use data[0] for padding size_t nbits; @@ -60,16 +63,20 @@ struct UArrayString return nbits / REG_SIZE + ((nbits % REG_SIZE) == 0 ? 0 : 1); } - UArrayString() : nbits(0) {} + UArrayString() : nbits(0) + { + } - UArrayString(size_t nbits_) : data(std::vector(nbits_)), nbits(nbits_) {} + UArrayString(size_t nbits_) : data(std::vector(nbits_)), nbits(nbits_) + { + } UArrayString(uint64_t src, size_t nbits); - UArrayString(const std::vector& src, const size_t nbits); - UArrayString(const std::vector& src); + UArrayString(const std::vector &src, const size_t nbits); + UArrayString(const std::vector &src); UArrayString(std::initializer_list init); - UArrayString(const std::string& src); + UArrayString(const std::string &src); - UArrayString(const UArrayString& src) + UArrayString(const UArrayString &src) { data = src.data; nbits = src.nbits; @@ -79,14 +86,14 @@ struct UArrayString bool set(size_t pos, bool value); - UArrayString& operator=(const UArrayString& src) + UArrayString &operator=(const UArrayString &src) { data = src.data; nbits = src.nbits; return *this; } - UArrayString& operator=(const std::string& src) + UArrayString &operator=(const std::string &src) { auto d = UArrayString(src); data = d.data; @@ -94,42 +101,60 @@ struct UArrayString return *this; } - bool operator==(const UArrayString& other) const { return to_string() == other.to_string(); } + bool operator==(const UArrayString &other) const + { + return to_string() == other.to_string(); + } - bool operator!=(const UArrayString& other) const { return to_string() != other.to_string(); } + bool operator!=(const UArrayString &other) const + { + return to_string() != other.to_string(); + } // convert to other data types std::string to_string() const; std::vector to_vector() const; - size_t size() const { return nbits; } + size_t size() const + { + return nbits; + } size_t get_counts(const size_t from, const size_t until, const bool value) const; - std::vector get_indices(const size_t from, const size_t unti, const bool value) const; + std::vector + get_indices(const size_t from, const size_t unti, const bool value) const; - inline bool operator[](const size_t idx) const { return get(idx); } + inline bool operator[](const size_t idx) const + { + return get(idx); + } }; -UArrayString::UArrayString(uint64_t src, size_t nbits_) : data({src}), nbits(nbits_) // NOLINT(bugprone-easily-swappable-parameters) +UArrayString::UArrayString( + uint64_t src, // NOLINT(bugprone-easily-swappable-parameters) + size_t nbits_ +) // NOLINT(bugprone-easily-swappable-parameters) + : data({src}), nbits(nbits_) // NOLINT(bugprone-easily-swappable-parameters) { if (nbits_ > 1) data.resize(nbits_, 0UL); } -UArrayString::UArrayString(const std::vector& src, const size_t nbits_) - : data({src}), nbits(nbits_) +UArrayString::UArrayString(const std::vector &src, const size_t nbits_) + : data({src}), nbits(nbits_) { } -UArrayString::UArrayString(const std::vector& src) - : data(VEC_SIZE(src.size())), nbits(src.size()) +UArrayString::UArrayString(const std::vector &src) + : data(VEC_SIZE(src.size())), nbits(src.size()) { for (size_t i = 0; i < src.size(); ++i) set(i, src[i]); } -UArrayString::UArrayString(const std::string& src) : data(VEC_SIZE(src.size())), nbits(src.size()) +UArrayString::UArrayString(const std::string &src) + : data(VEC_SIZE(src.size())), nbits(src.size()) { for (size_t i = 0; i < src.size(); ++i) set(i, src[i] == '1'); @@ -190,7 +215,11 @@ std::vector UArrayString::to_vector(void) const return ret; } -size_t UArrayString::get_counts(const size_t from, const size_t until, const bool value) const // NOLINT(bugprone-easily-swappable-parameters) +size_t UArrayString::get_counts( + const size_t from, // NOLINT(bugprone-easily-swappable-parameters) + const size_t until, // NOLINT(bugprone-easily-swappable-parameters) + const bool value +) const // NOLINT(bugprone-easily-swappable-parameters) { size_t ret = 0; for (size_t i = from; i < until; ++i) @@ -199,8 +228,11 @@ size_t UArrayString::get_counts(const size_t from, const size_t until, const boo return ret; } -std::vector UArrayString::get_indices(const size_t from, const size_t until, // NOLINT(bugprone-easily-swappable-parameters) - const bool value) const +std::vector UArrayString::get_indices( + const size_t from, // NOLINT(bugprone-easily-swappable-parameters) + const size_t until, // NOLINT(bugprone-easily-swappable-parameters) + const bool value +) const { std::vector ret; for (size_t i = from; i < until; ++i) @@ -211,8 +243,9 @@ std::vector UArrayString::get_indices(const size_t from, const size_t un typedef UArrayString BitString; -std::pair, std::vector> -bitstring_matrix_to_ci_strs(const std::vector& bitstring_matrix, bool open_shell = false) +std::pair, std::vector> bitstring_matrix_to_ci_strs( + const std::vector &bitstring_matrix, bool open_shell = false +) { size_t num_configs = bitstring_matrix.size(); size_t norb = bitstring_matrix[0].size() / 2; @@ -220,9 +253,8 @@ bitstring_matrix_to_ci_strs(const std::vector& bitstring_matrix, bool std::vector ci_str_left(num_configs, 0); std::vector ci_str_right(num_configs, 0); - for (size_t config = 0; config < num_configs; ++config) - { - const auto& row = bitstring_matrix[config]; + for (size_t config = 0; config < num_configs; ++config) { + const auto &row = bitstring_matrix[config]; for (size_t i = 0; i < norb; ++i) if (row[i]) @@ -230,28 +262,31 @@ bitstring_matrix_to_ci_strs(const std::vector& bitstring_matrix, bool for (size_t i = 0; i < norb; ++i) if (row[i + norb]) - ci_str_right[config] += static_cast(std::pow(2, norb - 1 - i)); + ci_str_right[config] += + static_cast(std::pow(2, norb - 1 - i)); } std::set unique_ci_str_left(ci_str_left.begin(), ci_str_left.end()); std::set unique_ci_str_right(ci_str_right.begin(), ci_str_right.end()); - if (!open_shell) - { + if (!open_shell) { std::set combined_set; combined_set.insert(unique_ci_str_left.begin(), unique_ci_str_left.end()); combined_set.insert(unique_ci_str_right.begin(), unique_ci_str_right.end()); unique_ci_str_left = unique_ci_str_right = combined_set; } - std::vector result_left(unique_ci_str_left.begin(), unique_ci_str_left.end()); - std::vector result_right(unique_ci_str_right.begin(), unique_ci_str_right.end()); + std::vector result_left( + unique_ci_str_left.begin(), unique_ci_str_left.end() + ); + std::vector result_right( + unique_ci_str_right.begin(), unique_ci_str_right.end() + ); return {result_right, result_left}; } -struct SQD -{ +struct SQD { std::string date_str = get_time(true); std::string run_id = date_str; uint64_t n_recovery = 3; // number of configuration recovery iterations @@ -281,75 +316,67 @@ struct SQD } }; -void log(const SQD& sqd_data, const std::vector& messages) +void log(const SQD &sqd_data, const std::vector &messages) { - if (sqd_data.verbose) - { + if (sqd_data.verbose) { std::cout << get_time(); std::cout << ": "; - for (auto& msg : messages) + for (auto &msg : messages) std::cout << msg; std::cout << std::endl; } } -void error(const SQD& sqd_data, const std::vector& messages) +void error(const SQD &sqd_data, const std::vector &messages) { - if (sqd_data.verbose) - { + if (sqd_data.verbose) { std::cerr << ": "; - for (auto& msg : messages) + for (auto &msg : messages) std::cerr << msg; std::cerr << std::endl; } } - -SQD generate_sqd_data(int argc, char* argv[]) +SQD generate_sqd_data(int argc, char *argv[]) { SQD sqd; - for (int i = 1; i < argc; i++) - { - if (std::string(argv[i]) == "--recovery") - { + for (int i = 1; i < argc; i++) { + if (std::string(argv[i]) == "--recovery") { sqd.n_recovery = std::stoi(argv[i + 1]); i++; } - if (std::string(argv[i]) == "--number_of_batch") - { + if (std::string(argv[i]) == "--number_of_batch") { sqd.n_batches = std::stoi(argv[i + 1]); i++; } - if (std::string(argv[i]) == "--number_of_samples") - { + if (std::string(argv[i]) == "--number_of_samples") { sqd.samples_per_batch = std::stoi(argv[i + 1]); i++; } - if (std::string(argv[i]) == "--backend_name") - { + if (std::string(argv[i]) == "--backend_name") { sqd.backend_name = std::string(argv[i + 1]); i++; } - if (std::string(argv[i]) == "--num_shots") - { + if (std::string(argv[i]) == "--num_shots") { sqd.num_shots = std::stoi(argv[i + 1]); i++; } - if (std::string(argv[i]) == "-v") - { + if (std::string(argv[i]) == "-v") { sqd.verbose = true; } } return sqd; } -std::vector integer_to_bytes(uint64_t n, int norb) // NOLINT(bugprone-easily-swappable-parameters) +std::vector integer_to_bytes( + uint64_t n, // NOLINT(bugprone-easily-swappable-parameters) + int norb // NOLINT(bugprone-easily-swappable-parameters) +) { int num_bytes = (norb + 7) / 8; std::vector result(num_bytes); - for (int i = num_bytes - 1; i >= 0; --i) - { + for (int i = num_bytes - 1; i >= 0; --i) { result[i] = static_cast(n & 0xFF); n >>= 8; } @@ -357,20 +384,22 @@ std::vector integer_to_bytes(uint64_t n, int norb) // NOLINT(bugprone- return result; } -std::vector> ci_strs_to_bytes(const std::vector& ci_strs, int norb) +std::vector> +ci_strs_to_bytes(const std::vector &ci_strs, int norb) { std::vector> bytes; bytes.reserve(ci_strs.size()); - for (uint64_t ci_str : ci_strs) - { + for (uint64_t ci_str : ci_strs) { bytes.push_back(integer_to_bytes(ci_str, norb)); } return bytes; } std::vector // -get_unique_ci_strs_with_HF(const SQD& sqd_data, const std::vector& left_ci_strs, - const std::vector& right_ci_strs, const size_t num_elec) +get_unique_ci_strs_with_HF( + const SQD &sqd_data, const std::vector &left_ci_strs, + const std::vector &right_ci_strs, const size_t num_elec +) { std::set unique_set; if (sqd_data.with_hf) @@ -383,48 +412,57 @@ get_unique_ci_strs_with_HF(const SQD& sqd_data, const std::vector& lef return std::move(ret); } -void write_bytestrings_to_file(const std::vector>& byte_strings, - const std::string& filename) +void write_bytestrings_to_file( + const std::vector> &byte_strings, const std::string &filename +) { std::ofstream output_file(filename, std::ios::binary); - if (!output_file.is_open()) - { + if (!output_file.is_open()) { std::cerr << "Error: Could not open file " << filename << std::endl; return; // Or throw an exception } - for (const auto& byte_string : byte_strings) - { - output_file.write(reinterpret_cast(byte_string.data()), static_cast(byte_string.size())); + for (const auto &byte_string : byte_strings) { + output_file.write( + reinterpret_cast(byte_string.data()), + static_cast(byte_string.size()) + ); } output_file.close(); } -std::string write_alphadets_file(const SQD& sqd_data, const size_t norb, const size_t num_elec, // NOLINT(bugprone-easily-swappable-parameters) - const std::vector& batch, - const size_t maximum_numbers_of_ctrs, const size_t i_recovery) // NOLINT(bugprone-easily-swappable-parameters) +std::string write_alphadets_file( + const SQD &sqd_data, + const size_t norb, // NOLINT(bugprone-easily-swappable-parameters) + const size_t num_elec, // NOLINT(bugprone-easily-swappable-parameters) + const std::vector &batch, + const size_t // NOLINT(bugprone-easily-swappable-parameters) + maximum_numbers_of_ctrs, // NOLINT(bugprone-easily-swappable-parameters) + const size_t i_recovery +) // NOLINT(bugprone-easily-swappable-parameters) { log(sqd_data, {"number of items in a batch: ", std::to_string(batch.size())}); bool open_shell = false; auto ci_strs = bitstring_matrix_to_ci_strs(batch, open_shell); - log(sqd_data, {"number of items in left ci_strs:", std::to_string(ci_strs.first.size())}); - log(sqd_data, {"number of items in right ci_strs:", std::to_string(ci_strs.second.size())}); + log(sqd_data, + {"number of items in left ci_strs:", std::to_string(ci_strs.first.size())}); + log(sqd_data, + {"number of items in right ci_strs:", std::to_string(ci_strs.second.size())}); auto unique_ci_strs = get_unique_ci_strs_with_HF(sqd_data, ci_strs.first, ci_strs.second, num_elec); - if (unique_ci_strs.size() < maximum_numbers_of_ctrs) - { - log(sqd_data, {"number of unique ci_strs:", std::to_string(unique_ci_strs.size())}); - } - else - { + if (unique_ci_strs.size() < maximum_numbers_of_ctrs) { + log(sqd_data, + {"number of unique ci_strs:", std::to_string(unique_ci_strs.size())}); + } else { size_t truncated = unique_ci_strs.size() - maximum_numbers_of_ctrs; unique_ci_strs.resize(maximum_numbers_of_ctrs); - log(sqd_data, {"number of unique ci_strs:", std::to_string(unique_ci_strs.size()), - ", truncated:", std::to_string(truncated)}); + log(sqd_data, + {"number of unique ci_strs:", std::to_string(unique_ci_strs.size()), + ", truncated:", std::to_string(truncated)}); } auto bytestrings = ci_strs_to_bytes(unique_ci_strs, static_cast(norb)); std::string alphadets_bin_file = From 9d562edb01a7c2dda95f99494dced36b74d6f975 Mon Sep 17 00:00:00 2001 From: to24toro Date: Mon, 29 Sep 2025 00:01:16 +0900 Subject: [PATCH 05/25] Add libopenblas-dev liblapack-dev --- .github/workflows/coverage.yml | 3 ++- .github/workflows/test_development_versions.yml | 3 ++- .github/workflows/test_latest_versions.yml | 3 ++- .github/workflows/test_without_exceptions_rtti.yml | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 7776aa6..4cb3c74 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -29,7 +29,8 @@ jobs: if: runner.os == 'Linux' run: | sudo apt-get update - sudo apt-get install -y g++ clang cmake ninja-build + sudo apt-get install -y g++ clang cmake ninja-build \ + libopenblas-dev liblapack-dev - name: Install tox run: | python -m pip install --upgrade pip diff --git a/.github/workflows/test_development_versions.yml b/.github/workflows/test_development_versions.yml index f77e768..4c3f56a 100644 --- a/.github/workflows/test_development_versions.yml +++ b/.github/workflows/test_development_versions.yml @@ -48,7 +48,8 @@ jobs: if: runner.os == 'Linux' run: | sudo apt-get update - sudo apt-get install -y g++ clang cmake ninja-build + sudo apt-get install -y g++ clang cmake ninja-build \ + libopenblas-dev liblapack-dev - name: Configure CMake run: >- cmake -S . -B build diff --git a/.github/workflows/test_latest_versions.yml b/.github/workflows/test_latest_versions.yml index 702e067..bb33412 100644 --- a/.github/workflows/test_latest_versions.yml +++ b/.github/workflows/test_latest_versions.yml @@ -69,7 +69,8 @@ jobs: if: runner.os == 'Linux' run: | sudo apt-get update - sudo apt-get install -y g++ clang cmake ninja-build + sudo apt-get install -y g++ clang cmake ninja-build \ + libopenblas-dev liblapack-dev - name: Configure CMake run: >- cmake -S . -B build diff --git a/.github/workflows/test_without_exceptions_rtti.yml b/.github/workflows/test_without_exceptions_rtti.yml index 5a699d6..aa8700b 100644 --- a/.github/workflows/test_without_exceptions_rtti.yml +++ b/.github/workflows/test_without_exceptions_rtti.yml @@ -30,7 +30,8 @@ jobs: if: runner.os == 'Linux' run: | sudo apt-get update - sudo apt-get install -y g++ clang cmake ninja-build + sudo apt-get install -y g++ clang cmake ninja-build \ + libopenblas-dev liblapack-dev - name: Configure CMake run: >- cmake -S . -B build From 093d35c96079df89f9d43b9cfd867e9bbd324b43 Mon Sep 17 00:00:00 2001 From: to24toro Date: Mon, 29 Sep 2025 00:04:53 +0900 Subject: [PATCH 06/25] Add libeigen3-dev --- .github/workflows/coverage.yml | 2 +- .github/workflows/test_development_versions.yml | 2 +- .github/workflows/test_latest_versions.yml | 2 +- .github/workflows/test_without_exceptions_rtti.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 4cb3c74..a52b023 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -30,7 +30,7 @@ jobs: run: | sudo apt-get update sudo apt-get install -y g++ clang cmake ninja-build \ - libopenblas-dev liblapack-dev + libopenblas-dev liblapack-dev libeigen3-dev - name: Install tox run: | python -m pip install --upgrade pip diff --git a/.github/workflows/test_development_versions.yml b/.github/workflows/test_development_versions.yml index 4c3f56a..0f167af 100644 --- a/.github/workflows/test_development_versions.yml +++ b/.github/workflows/test_development_versions.yml @@ -49,7 +49,7 @@ jobs: run: | sudo apt-get update sudo apt-get install -y g++ clang cmake ninja-build \ - libopenblas-dev liblapack-dev + libopenblas-dev liblapack-dev libeigen3-dev - name: Configure CMake run: >- cmake -S . -B build diff --git a/.github/workflows/test_latest_versions.yml b/.github/workflows/test_latest_versions.yml index bb33412..0bd4316 100644 --- a/.github/workflows/test_latest_versions.yml +++ b/.github/workflows/test_latest_versions.yml @@ -70,7 +70,7 @@ jobs: run: | sudo apt-get update sudo apt-get install -y g++ clang cmake ninja-build \ - libopenblas-dev liblapack-dev + libopenblas-dev liblapack-dev libeigen3-dev - name: Configure CMake run: >- cmake -S . -B build diff --git a/.github/workflows/test_without_exceptions_rtti.yml b/.github/workflows/test_without_exceptions_rtti.yml index aa8700b..0bb44ac 100644 --- a/.github/workflows/test_without_exceptions_rtti.yml +++ b/.github/workflows/test_without_exceptions_rtti.yml @@ -31,7 +31,7 @@ jobs: run: | sudo apt-get update sudo apt-get install -y g++ clang cmake ninja-build \ - libopenblas-dev liblapack-dev + libopenblas-dev liblapack-dev libeigen3-dev - name: Configure CMake run: >- cmake -S . -B build From 9b249fc82a04818ffc377d5a8615481aece33639 Mon Sep 17 00:00:00 2001 From: to24toro Date: Mon, 29 Sep 2025 00:07:47 +0900 Subject: [PATCH 07/25] Add eigen in macOS --- .github/workflows/test_latest_versions.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/test_latest_versions.yml b/.github/workflows/test_latest_versions.yml index 0bd4316..1997202 100644 --- a/.github/workflows/test_latest_versions.yml +++ b/.github/workflows/test_latest_versions.yml @@ -71,6 +71,10 @@ jobs: sudo apt-get update sudo apt-get install -y g++ clang cmake ninja-build \ libopenblas-dev liblapack-dev libeigen3-dev + - name: Install dependencies (macOS) + if: runner.os == 'macOS' + run: | + brew install eigen - name: Configure CMake run: >- cmake -S . -B build From fb1f90f7770c64ad5ed9070b81e83bbc08f05cb8 Mon Sep 17 00:00:00 2001 From: to24toro Date: Mon, 29 Sep 2025 00:15:08 +0900 Subject: [PATCH 08/25] Add openmpi --- .github/workflows/coverage.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index a52b023..e05ba22 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -30,7 +30,8 @@ jobs: run: | sudo apt-get update sudo apt-get install -y g++ clang cmake ninja-build \ - libopenblas-dev liblapack-dev libeigen3-dev + libopenblas-dev liblapack-dev libeigen3-dev \ + libopenmpi-dev openmpi-bin - name: Install tox run: | python -m pip install --upgrade pip From 972734f35a6fad6bcfa5f770a7c75a74a34e0e6d Mon Sep 17 00:00:00 2001 From: to24toro Date: Mon, 29 Sep 2025 00:15:15 +0900 Subject: [PATCH 09/25] Remove windows --- .../workflows/test_development_versions.yml | 11 ++++------ .github/workflows/test_latest_versions.yml | 20 ++++--------------- .../test_without_exceptions_rtti.yml | 11 ++++------ 3 files changed, 12 insertions(+), 30 deletions(-) diff --git a/.github/workflows/test_development_versions.yml b/.github/workflows/test_development_versions.yml index 0f167af..45a5f68 100644 --- a/.github/workflows/test_development_versions.yml +++ b/.github/workflows/test_development_versions.yml @@ -49,23 +49,20 @@ jobs: run: | sudo apt-get update sudo apt-get install -y g++ clang cmake ninja-build \ - libopenblas-dev liblapack-dev libeigen3-dev + libopenblas-dev liblapack-dev libeigen3-dev \ + libopenmpi-dev openmpi-bin - name: Configure CMake run: >- cmake -S . -B build -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON - ${{ matrix.compiler != 'MSVC' && '-G Ninja' || '' }} + -G Ninja ${{ matrix.compiler && format('-DCMAKE_CXX_COMPILER={0}', matrix.compiler) }} ${{ matrix.cxx_standard && format('-DCMAKE_CXX_STANDARD={0}', matrix.cxx_standard) }} -DCMAKE_CXX_FLAGS="-DUSE_RANDOM_SHOTS=1" - name: CMake Build run: >- cmake --build build -j4 - ${{ matrix.compiler == 'MSVC' && '--config Release' || '' }} - - name: Copy build/Release/*.exe to build/ (MSVC) - if: matrix.compiler == 'MSVC' - run: | - cp build/Release/*.exe build/ + --config Release - name: Run tests run: | cd build diff --git a/.github/workflows/test_latest_versions.yml b/.github/workflows/test_latest_versions.yml index 1997202..412c989 100644 --- a/.github/workflows/test_latest_versions.yml +++ b/.github/workflows/test_latest_versions.yml @@ -52,15 +52,6 @@ jobs: # macOS ARM - os: macos-latest compiler: clang++ - # Windows - - os: windows-latest - compiler: MSVC - - os: windows-latest - compiler: MSVC - cxx_standard: 20 - - os: windows-latest - compiler: MSVC - cxx_standard: 23 steps: - uses: actions/checkout@v5 with: @@ -70,7 +61,8 @@ jobs: run: | sudo apt-get update sudo apt-get install -y g++ clang cmake ninja-build \ - libopenblas-dev liblapack-dev libeigen3-dev + libopenblas-dev liblapack-dev libeigen3-dev \ + libopenmpi-dev openmpi-bin - name: Install dependencies (macOS) if: runner.os == 'macOS' run: | @@ -78,19 +70,15 @@ jobs: - name: Configure CMake run: >- cmake -S . -B build + -G Ninja -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON - ${{ matrix.compiler != 'MSVC' && '-G Ninja' || '' }} ${{ matrix.compiler && format('-DCMAKE_CXX_COMPILER={0}', matrix.compiler) }} ${{ matrix.cxx_standard && format('-DCMAKE_CXX_STANDARD={0}', matrix.cxx_standard) }} -DCMAKE_CXX_FLAGS="-DUSE_RANDOM_SHOTS=1" - name: CMake Build run: >- cmake --build build -j4 - ${{ matrix.compiler == 'MSVC' && '--config Release' || '' }} - - name: Copy build/Release/*.exe to build/ (MSVC) - if: matrix.compiler == 'MSVC' - run: | - cp build/Release/*.exe build/ + --config Release - name: Run tests run: | cd build diff --git a/.github/workflows/test_without_exceptions_rtti.yml b/.github/workflows/test_without_exceptions_rtti.yml index 0bb44ac..89e8540 100644 --- a/.github/workflows/test_without_exceptions_rtti.yml +++ b/.github/workflows/test_without_exceptions_rtti.yml @@ -31,24 +31,21 @@ jobs: run: | sudo apt-get update sudo apt-get install -y g++ clang cmake ninja-build \ - libopenblas-dev liblapack-dev libeigen3-dev + libopenblas-dev liblapack-dev libeigen3-dev \ + libopenmpi-dev openmpi-bin - name: Configure CMake run: >- cmake -S . -B build + -G Ninja -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -DCMAKE_CXX_FLAGS="-fno-rtti -fno-exceptions -DQKA_SQD_DISABLE_EXCEPTIONS=1 -DDOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS" - ${{ matrix.compiler != 'MSVC' && '-G Ninja' || '' }} ${{ matrix.compiler && format('-DCMAKE_CXX_COMPILER={0}', matrix.compiler) }} ${{ matrix.cxx_standard && format('-DCMAKE_CXX_STANDARD={0}', matrix.cxx_standard) }} -DCMAKE_CXX_FLAGS="-DUSE_RANDOM_SHOTS=1" - name: CMake Build run: >- cmake --build build -j4 --target sqd_tests - ${{ matrix.compiler == 'MSVC' && '--config Release' || '' }} - - name: Copy build/Release/*.exe to build/ (MSVC) - if: matrix.compiler == 'MSVC' - run: | - cp build/Release/*.exe build/ + --config Release - name: Run tests run: | cd build From ca3d108fd0122fc6b28327e51c780861e81de711 Mon Sep 17 00:00:00 2001 From: to24toro Date: Mon, 29 Sep 2025 00:22:54 +0900 Subject: [PATCH 10/25] Add deps --- .github/workflows/coverage.yml | 13 +++++++++--- .../workflows/test_development_versions.yml | 10 ++++++++++ .github/workflows/test_latest_versions.yml | 2 +- .../test_without_exceptions_rtti.yml | 20 +++++++++++++++++++ 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index e05ba22..fffaf36 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -36,9 +36,16 @@ jobs: run: | python -m pip install --upgrade pip pip install gcovr - - name: Configure CMake - run: cmake -S . -B build -G Ninja -DCMAKE_CXX_FLAGS="-DUSE_RANDOM_SHOTS=1" - + - name: Clone submodules + run: git submodule update --init --recursive + - name: Build qiskit + run: | + cd deps/qiskit + make c + - name: Build qrmi + run: | + cd deps/qrmi + cargo build --release - name: Build run: ninja -C build diff --git a/.github/workflows/test_development_versions.yml b/.github/workflows/test_development_versions.yml index 45a5f68..58717c8 100644 --- a/.github/workflows/test_development_versions.yml +++ b/.github/workflows/test_development_versions.yml @@ -51,6 +51,16 @@ jobs: sudo apt-get install -y g++ clang cmake ninja-build \ libopenblas-dev liblapack-dev libeigen3-dev \ libopenmpi-dev openmpi-bin + - name: Clone submodules + run: git submodule update --init --recursive + - name: Build qiskit + run: | + cd deps/qiskit + make c + - name: Build qrmi + run: | + cd deps/qrmi + cargo build --release - name: Configure CMake run: >- cmake -S . -B build diff --git a/.github/workflows/test_latest_versions.yml b/.github/workflows/test_latest_versions.yml index 412c989..58a52bb 100644 --- a/.github/workflows/test_latest_versions.yml +++ b/.github/workflows/test_latest_versions.yml @@ -66,7 +66,7 @@ jobs: - name: Install dependencies (macOS) if: runner.os == 'macOS' run: | - brew install eigen + brew install eigen open-mpi - name: Configure CMake run: >- cmake -S . -B build diff --git a/.github/workflows/test_without_exceptions_rtti.yml b/.github/workflows/test_without_exceptions_rtti.yml index 89e8540..58b9d2e 100644 --- a/.github/workflows/test_without_exceptions_rtti.yml +++ b/.github/workflows/test_without_exceptions_rtti.yml @@ -33,6 +33,26 @@ jobs: sudo apt-get install -y g++ clang cmake ninja-build \ libopenblas-dev liblapack-dev libeigen3-dev \ libopenmpi-dev openmpi-bin + - name: Clone submodules + run: git submodule update --init --recursive + - name: Build qiskit + run: | + cd deps/qiskit + make c + - name: Build qrmi + run: | + cd deps/qrmi + cargo build --release + - name: Clone submodules + run: git submodule update --init --recursive + - name: Build qiskit + run: | + cd deps/qiskit + make c + - name: Build qrmi + run: | + cd deps/qrmi + cargo build --release - name: Configure CMake run: >- cmake -S . -B build From 2df9179ca28325cd8ac688b945024bdcc1aefb92 Mon Sep 17 00:00:00 2001 From: to24toro Date: Mon, 29 Sep 2025 00:23:12 +0900 Subject: [PATCH 11/25] Remove ci/scripts --- ci/scripts/acceptance-test.sh | 4 --- ci/scripts/build-artifact.sh | 4 --- ci/scripts/deploy.sh | 4 --- ci/scripts/github-login.sh | 10 ------- ci/scripts/release.sh | 4 --- ci/scripts/rollback.sh | 4 --- ci/scripts/setup.sh | 16 ----------- ci/scripts/unit-test.sh | 50 ----------------------------------- 8 files changed, 96 deletions(-) delete mode 100644 ci/scripts/acceptance-test.sh delete mode 100644 ci/scripts/build-artifact.sh delete mode 100644 ci/scripts/deploy.sh delete mode 100644 ci/scripts/github-login.sh delete mode 100644 ci/scripts/release.sh delete mode 100644 ci/scripts/rollback.sh delete mode 100644 ci/scripts/setup.sh delete mode 100644 ci/scripts/unit-test.sh diff --git a/ci/scripts/acceptance-test.sh b/ci/scripts/acceptance-test.sh deleted file mode 100644 index 9f6c3d0..0000000 --- a/ci/scripts/acceptance-test.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -echo "Running ----------acceptance-test script----------" diff --git a/ci/scripts/build-artifact.sh b/ci/scripts/build-artifact.sh deleted file mode 100644 index ffab3ef..0000000 --- a/ci/scripts/build-artifact.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -echo "Running ----------build-artifact script----------" diff --git a/ci/scripts/deploy.sh b/ci/scripts/deploy.sh deleted file mode 100644 index 726512c..0000000 --- a/ci/scripts/deploy.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -echo "Running ----------deploy script----------" diff --git a/ci/scripts/github-login.sh b/ci/scripts/github-login.sh deleted file mode 100644 index 813ce1b..0000000 --- a/ci/scripts/github-login.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -set -euo pipefail - -GITHUB_TOKEN="$(get_env git-token)" - -echo -e "machine github.ibm.com\n login $GITHUB_TOKEN" > ~/.netrc -git config user.name "ibmqops" -git config user.email "ibmqops@ibm.com" - -echo '::info::Git is configured' diff --git a/ci/scripts/release.sh b/ci/scripts/release.sh deleted file mode 100644 index 112b77b..0000000 --- a/ci/scripts/release.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -echo "Running ----------release script----------" diff --git a/ci/scripts/rollback.sh b/ci/scripts/rollback.sh deleted file mode 100644 index c64c0c1..0000000 --- a/ci/scripts/rollback.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -echo "Running ----------rollback script----------" diff --git a/ci/scripts/setup.sh b/ci/scripts/setup.sh deleted file mode 100644 index dd3256d..0000000 --- a/ci/scripts/setup.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -echo "Running ----------setup script----------" - -# Enable/disable specific compliance checks -set_env branch-protection-check 0 -set_env peer-review-compliance 0 -set_env sbom-validation-collect-evidence 0 -set_env evidence-reuse 0 - -# We're not enabling evidence collection yet, but we can turn on some settings now! -set_env batched-evidence-collection 1 - -# Make sure that we're interacting with the inventory as little as possible -set_env skip-inventory-update-on-failure 1 diff --git a/ci/scripts/unit-test.sh b/ci/scripts/unit-test.sh deleted file mode 100644 index 6481a75..0000000 --- a/ci/scripts/unit-test.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -echo "Running ----------unit-test script----------" - -source ci/scripts/github-login.sh - -SOURCE_DIR="$(pwd)" -BUILD_DIR="${SOURCE_DIR}/build" - -set -x - -# Install KitWare ppa to obtain latest cmake (https://apt.kitware.com/) -apt-get update -apt-get install -y ca-certificates gpg wget -test -f /usr/share/doc/kitware-archive-keyring/copyright || wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | sudo tee /usr/share/keyrings/kitware-archive-keyring.gpg >/dev/null -echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ jammy main' | sudo tee /etc/apt/sources.list.d/kitware.list >/dev/null - -# Update and install desired packages -apt-get update -apt-get install -y curl build-essential g++ cmake ninja-build libhdf5-dev libopenblas-dev python3.10-dev pkg-config libssl-dev libomp-dev libeigen3-dev openmpi-bin libopenmpi-dev - -# Recent rust is essential to build Qiskit -curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y -source "$HOME/.cargo/env" - -# Clone submodules -git submodule update --init --recursive - -# Build qiskit -cd $SOURCE_DIR/deps/qiskit -make c - -# Build qrmi -cd $SOURCE_DIR/deps/qrmi -cargo build --release - -cd $SOURCE_DIR - -# Build -cmake -S "$SOURCE_DIR" -B "$BUILD_DIR" -G Ninja -ninja -C "$BUILD_DIR" - -# Re-build with USE_RANDOM_SHOTS=1 and test the resulting binary -cmake -S "$SOURCE_DIR" -B "$BUILD_DIR" -G Ninja -DCMAKE_CXX_FLAGS="-DUSE_RANDOM_SHOTS=1" -ninja -C "$BUILD_DIR" -cd "$BUILD_DIR" -./capi-demo --fcidump ../data/fcidump_Fe4S4_MO.txt --tolerance 1.0e-3 --max_time 600 --recovery 1 --number_of_samples 300 --num_shots 1000 - -cd $SOURCE_DIR From cc70be2a00532d6a952f07c8cccfd776b426025d Mon Sep 17 00:00:00 2001 From: to24toro Date: Mon, 29 Sep 2025 00:25:43 +0900 Subject: [PATCH 12/25] Add deps build for latest versions --- .github/workflows/test_latest_versions.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/test_latest_versions.yml b/.github/workflows/test_latest_versions.yml index 58a52bb..ef1998d 100644 --- a/.github/workflows/test_latest_versions.yml +++ b/.github/workflows/test_latest_versions.yml @@ -67,6 +67,16 @@ jobs: if: runner.os == 'macOS' run: | brew install eigen open-mpi + - name: Clone submodules + run: git submodule update --init --recursive + - name: Build qiskit + run: | + cd deps/qiskit + make c + - name: Build qrmi + run: | + cd deps/qrmi + cargo build --release - name: Configure CMake run: >- cmake -S . -B build From 774536acbafc0eab0190a522a1b794ea8e48bc44 Mon Sep 17 00:00:00 2001 From: to24toro Date: Mon, 29 Sep 2025 00:49:12 +0900 Subject: [PATCH 13/25] Add openmp --- .github/workflows/coverage.yml | 2 +- .github/workflows/test_development_versions.yml | 2 +- .github/workflows/test_latest_versions.yml | 4 ++-- .github/workflows/test_without_exceptions_rtti.yml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index fffaf36..c577ae9 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -31,7 +31,7 @@ jobs: sudo apt-get update sudo apt-get install -y g++ clang cmake ninja-build \ libopenblas-dev liblapack-dev libeigen3-dev \ - libopenmpi-dev openmpi-bin + libopenmpi-dev openmpi-bin libomp-dev - name: Install tox run: | python -m pip install --upgrade pip diff --git a/.github/workflows/test_development_versions.yml b/.github/workflows/test_development_versions.yml index 58717c8..9f410ba 100644 --- a/.github/workflows/test_development_versions.yml +++ b/.github/workflows/test_development_versions.yml @@ -50,7 +50,7 @@ jobs: sudo apt-get update sudo apt-get install -y g++ clang cmake ninja-build \ libopenblas-dev liblapack-dev libeigen3-dev \ - libopenmpi-dev openmpi-bin + libopenmpi-dev openmpi-bin libomp-dev - name: Clone submodules run: git submodule update --init --recursive - name: Build qiskit diff --git a/.github/workflows/test_latest_versions.yml b/.github/workflows/test_latest_versions.yml index ef1998d..84698f7 100644 --- a/.github/workflows/test_latest_versions.yml +++ b/.github/workflows/test_latest_versions.yml @@ -62,11 +62,11 @@ jobs: sudo apt-get update sudo apt-get install -y g++ clang cmake ninja-build \ libopenblas-dev liblapack-dev libeigen3-dev \ - libopenmpi-dev openmpi-bin + libopenmpi-dev openmpi-bin libomp-dev - name: Install dependencies (macOS) if: runner.os == 'macOS' run: | - brew install eigen open-mpi + brew install eigen open-mpi libomp - name: Clone submodules run: git submodule update --init --recursive - name: Build qiskit diff --git a/.github/workflows/test_without_exceptions_rtti.yml b/.github/workflows/test_without_exceptions_rtti.yml index 58b9d2e..a8df87f 100644 --- a/.github/workflows/test_without_exceptions_rtti.yml +++ b/.github/workflows/test_without_exceptions_rtti.yml @@ -32,7 +32,7 @@ jobs: sudo apt-get update sudo apt-get install -y g++ clang cmake ninja-build \ libopenblas-dev liblapack-dev libeigen3-dev \ - libopenmpi-dev openmpi-bin + libopenmpi-dev openmpi-bin libomp-dev - name: Clone submodules run: git submodule update --init --recursive - name: Build qiskit From 0ca2517fcdee472a3cf686c5a177f8d2be1315e3 Mon Sep 17 00:00:00 2001 From: to24toro Date: Mon, 29 Sep 2025 01:00:09 +0900 Subject: [PATCH 14/25] Removed unused target --- .github/workflows/test_without_exceptions_rtti.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test_without_exceptions_rtti.yml b/.github/workflows/test_without_exceptions_rtti.yml index a8df87f..9cdc2f0 100644 --- a/.github/workflows/test_without_exceptions_rtti.yml +++ b/.github/workflows/test_without_exceptions_rtti.yml @@ -64,7 +64,7 @@ jobs: -DCMAKE_CXX_FLAGS="-DUSE_RANDOM_SHOTS=1" - name: CMake Build run: >- - cmake --build build -j4 --target sqd_tests + cmake --build build -j4 --config Release - name: Run tests run: | From 64461b1a00645d60c6d5c3d01d2b288cc9f5ee00 Mon Sep 17 00:00:00 2001 From: to24toro Date: Wed, 1 Oct 2025 09:28:35 +0900 Subject: [PATCH 15/25] format based on linux --- ffsim/include/ffsim/gates/diag_coulomb.hpp | 314 +++++++++--------- .../include/ffsim/gates/orbital_rotation.hpp | 277 ++++++++------- ffsim/include/ffsim/gates/phase_shift.hpp | 8 +- .../ffsim/linalg/double_factorized_decomp.hpp | 133 ++++---- ffsim/include/ffsim/linalg/expm.hpp | 5 +- ffsim/include/ffsim/linalg/givens.hpp | 90 ++--- ffsim/include/ffsim/linalg/logm.hpp | 5 +- ffsim/include/ffsim/linalg/matrix_utils.hpp | 41 +-- src/sqd_helper.hpp | 8 +- 9 files changed, 424 insertions(+), 457 deletions(-) diff --git a/ffsim/include/ffsim/gates/diag_coulomb.hpp b/ffsim/include/ffsim/gates/diag_coulomb.hpp index 53695fc..714f1c3 100644 --- a/ffsim/include/ffsim/gates/diag_coulomb.hpp +++ b/ffsim/include/ffsim/gates/diag_coulomb.hpp @@ -38,8 +38,7 @@ using namespace Eigen; * - Single: Represents a single matrix. * - Triple: Represents a set of three matrices. */ -enum class MatType : std::uint8_t -{ +enum class MatType : std::uint8_t { Single, ///< Represents a single matrix for all orbitals. Triple, ///< Represents a set of three matrices for (aa, ab, bb) orbitals. }; @@ -52,37 +51,33 @@ enum class MatType : std::uint8_t * - single: The single matrix (used when type is Single). * - triple: The three matrices (used when type is Triple). */ -struct Mat -{ - MatType type; ///< Type of matrix (Single or Triple). - MatrixXcd single; ///< Single matrix (used when type is Single). - std::array, 3> triple; ///< Three matrices (used when type is Triple). +struct Mat { + MatType type; ///< Type of matrix (Single or Triple). + MatrixXcd single; ///< Single matrix (used when type is Single). + std::array, 3> + triple; ///< Three matrices (used when type is Triple). }; /** * @brief Matrix exponentials for diagonal Coulomb evolution. * @details This structure holds the matrix exponentials to avoid parameter confusion. */ -struct MatExp -{ - MatrixXcd aa; // Matrix exponential for alpha-alpha interactions. - MatrixXcd ab; // Matrix exponential for alpha-beta interactions. - MatrixXcd bb; // Matrix exponential for beta-beta interactions. +struct MatExp { + MatrixXcd aa; // Matrix exponential for alpha-alpha interactions. + MatrixXcd ab; // Matrix exponential for alpha-beta interactions. + MatrixXcd bb; // Matrix exponential for beta-beta interactions. }; -MatExp get_mat_exp(const Mat& mat, uint64_t norb, bool z_representation, double time) +MatExp get_mat_exp(const Mat &mat, uint64_t norb, bool z_representation, double time) { const Complex I(0.0, 1.0); - if (mat.type == MatType::Single) - { + if (mat.type == MatType::Single) { MatrixXcd mat_aa = mat.single; MatrixXcd mat_ab = mat.single; - for (size_t i = 0; i < norb; ++i) - { + for (size_t i = 0; i < norb; ++i) { mat_aa(static_cast(i), static_cast(i)) *= 0.5; } - if (z_representation) - { + if (z_representation) { mat_aa *= 0.25; mat_ab *= 0.25; } @@ -93,91 +88,77 @@ MatExp get_mat_exp(const Mat& mat, uint64_t norb, bool z_representation, double result.bb = result.aa; return result; - } - else - { + } else { MatExp result; - if (const auto& opt_mat = mat.triple[0]; opt_mat.has_value()) - { + if (const auto &opt_mat = mat.triple[0]; opt_mat.has_value()) { MatrixXcd mat_aa = opt_mat.value(); - for (size_t i = 0; i < norb; ++i) - { + for (size_t i = 0; i < norb; ++i) { mat_aa(static_cast(i), static_cast(i)) *= 0.5; } - if (z_representation) - { + if (z_representation) { mat_aa *= 0.25; } result.aa = (-I * time * mat_aa.array()).exp().matrix(); + } else { + result.aa = + MatrixXcd::Identity(static_cast(norb), static_cast(norb)); } - else - { - result.aa = MatrixXcd::Identity(static_cast(norb), static_cast(norb)); - } - if (const auto& opt_mat = mat.triple[1]; opt_mat.has_value()) - { + if (const auto &opt_mat = mat.triple[1]; opt_mat.has_value()) { MatrixXcd mat_ab = opt_mat.value(); - if (z_representation) - { + if (z_representation) { mat_ab *= 0.25; } result.ab = (-I * time * mat_ab.array()).exp().matrix(); + } else { + result.ab = + MatrixXcd::Identity(static_cast(norb), static_cast(norb)); } - else - { - result.ab = MatrixXcd::Identity(static_cast(norb), static_cast(norb)); - } - if (const auto& opt_mat = mat.triple[2]; opt_mat.has_value()) - { + if (const auto &opt_mat = mat.triple[2]; opt_mat.has_value()) { MatrixXcd mat_bb = opt_mat.value(); - for (size_t i = 0; i < norb; ++i) - { + for (size_t i = 0; i < norb; ++i) { mat_bb(static_cast(i), static_cast(i)) *= 0.5; } - if (z_representation) - { + if (z_representation) { mat_bb *= 0.25; } result.bb = (-I * time * mat_bb.array()).exp().matrix(); - } - else - { - result.bb = MatrixXcd::Identity(static_cast(norb), static_cast(norb)); + } else { + result.bb = + MatrixXcd::Identity(static_cast(norb), static_cast(norb)); } return result; } } -OrbitalRotation conjugate_orbital_rotation(const OrbitalRotation& orb_rot) +OrbitalRotation conjugate_orbital_rotation(const OrbitalRotation &orb_rot) { - if (orb_rot.type == OrbitalRotationType::Spinless) - { - return OrbitalRotation{OrbitalRotationType::Spinless, - orb_rot.spinless.adjoint(), - {std::nullopt, std::nullopt}}; - } - else - { + if (orb_rot.type == OrbitalRotationType::Spinless) { + return OrbitalRotation{ + OrbitalRotationType::Spinless, + orb_rot.spinless.adjoint(), + {std::nullopt, std::nullopt} + }; + } else { std::array, 2> spinfull_conj; - for (int i = 0; i < 2; ++i) - { - if (const auto& opt_spinfull = orb_rot.spinfull[i]; opt_spinfull.has_value()) - { + for (int i = 0; i < 2; ++i) { + if (const auto &opt_spinfull = orb_rot.spinfull[i]; + opt_spinfull.has_value()) { spinfull_conj[i] = opt_spinfull.value().adjoint(); - } - else - { + } else { spinfull_conj[i] = std::nullopt; } } - return OrbitalRotation{OrbitalRotationType::Spinfull, MatrixXcd(), spinfull_conj}; + return OrbitalRotation{ + OrbitalRotationType::Spinfull, MatrixXcd(), spinfull_conj + }; } } void apply_diag_coulomb_evolution_in_place_num_rep( - MatrixXcd& vec, uint64_t norb, const MatExp& mat_exp, - const std::vector>& occupations_a, - const std::vector>& occupations_b) + MatrixXcd &vec, uint64_t norb, const MatExp &mat_exp, + const std::vector> &occupations_a, + const std::vector> &occupations_b +) { const size_t dim_a = vec.rows(); const size_t dim_b = vec.cols(); @@ -186,44 +167,41 @@ void apply_diag_coulomb_evolution_in_place_num_rep( ArrayXcd alpha_phases = ArrayXcd::Zero(static_cast(dim_a)); ArrayXcd beta_phases = ArrayXcd::Zero(static_cast(dim_b)); - ArrayXXcd phase_map = ArrayXXcd::Ones(static_cast(dim_a), static_cast(dim_b)); + ArrayXXcd phase_map = + ArrayXXcd::Ones(static_cast(dim_a), static_cast(dim_b)); - for (size_t i = 0; i < dim_b; ++i) - { + for (size_t i = 0; i < dim_b; ++i) { Complex phase = 1.0; - for (size_t j = 0; j < n_beta; ++j) - { + for (size_t j = 0; j < n_beta; ++j) { size_t orb_1 = occupations_b[i][j]; - for (size_t k = j; k < n_beta; ++k) - { + for (size_t k = j; k < n_beta; ++k) { size_t orb_2 = occupations_b[i][k]; - phase *= mat_exp.bb(static_cast(orb_1), static_cast(orb_2)); + phase *= + mat_exp.bb(static_cast(orb_1), static_cast(orb_2)); } } beta_phases(static_cast(i)) = phase; } - for (size_t i = 0; i < dim_a; ++i) - { + for (size_t i = 0; i < dim_a; ++i) { Complex phase = 1.0; - for (size_t j = 0; j < n_alpha; ++j) - { + for (size_t j = 0; j < n_alpha; ++j) { size_t orb_1 = occupations_a[i][j]; - phase_map.row(static_cast(i)) = phase_map.row(static_cast(i)).array() * mat_exp.ab.row(static_cast(orb_1)).array(); - for (size_t k = j; k < n_alpha; ++k) - { + phase_map.row(static_cast(i)) = + phase_map.row(static_cast(i)).array() * + mat_exp.ab.row(static_cast(orb_1)).array(); + for (size_t k = j; k < n_alpha; ++k) { size_t orb_2 = occupations_a[i][k]; - phase *= mat_exp.aa(static_cast(orb_1), static_cast(orb_2)); + phase *= + mat_exp.aa(static_cast(orb_1), static_cast(orb_2)); } } alpha_phases(static_cast(i)) = phase; } - for (size_t i = 0; i < dim_a; ++i) - { - for (size_t j = 0; j < dim_b; ++j) - { - Complex phase = alpha_phases(static_cast(i)) * beta_phases(static_cast(j)); - for (size_t k = 0; k < n_beta; ++k) - { + for (size_t i = 0; i < dim_a; ++i) { + for (size_t j = 0; j < dim_b; ++j) { + Complex phase = alpha_phases(static_cast(i)) * + beta_phases(static_cast(j)); + for (size_t k = 0; k < n_beta; ++k) { size_t orb = occupations_b[j][k]; phase *= phase_map(static_cast(i), static_cast(orb)); } @@ -232,10 +210,10 @@ void apply_diag_coulomb_evolution_in_place_num_rep( } } -void apply_diag_coulomb_evolution_in_place_z_rep(MatrixXcd& vec, uint64_t norb, - MatExp& mat_exp, - const std::vector& strings_a, - const std::vector& strings_b) +void apply_diag_coulomb_evolution_in_place_z_rep( + MatrixXcd &vec, uint64_t norb, MatExp &mat_exp, + const std::vector &strings_a, const std::vector &strings_b +) { MatrixXcd mat_exp_aa_conj = mat_exp.aa.conjugate(); MatrixXcd mat_exp_ab_conj = mat_exp.ab.conjugate(); @@ -246,58 +224,62 @@ void apply_diag_coulomb_evolution_in_place_z_rep(MatrixXcd& vec, uint64_t norb, ArrayXcd alpha_phases = ArrayXcd::Zero(static_cast(dim_a)); ArrayXcd beta_phases = ArrayXcd::Zero(static_cast(dim_b)); - ArrayXXcd phase_map = ArrayXXcd::Ones(static_cast(dim_a), static_cast(norb)); + ArrayXXcd phase_map = + ArrayXXcd::Ones(static_cast(dim_a), static_cast(norb)); - for (size_t i = 0; i < dim_b; ++i) - { + for (size_t i = 0; i < dim_b; ++i) { Complex phase = 1.0; int64_t str0 = strings_b[i]; - for (size_t j = 0; j < norb; ++j) - { + for (size_t j = 0; j < norb; ++j) { bool sign_j = (str0 >> j) & 1; - for (size_t k = j + 1; k < norb; ++k) - { + for (size_t k = j + 1; k < norb; ++k) { bool sign_k = (str0 >> k) & 1; - Complex this_phase = (sign_j ^ sign_k) ? mat_exp_bb_conj(static_cast(j), static_cast(k)) : mat_exp.bb(static_cast(j), static_cast(k)); + Complex this_phase = + (sign_j ^ sign_k) + ? mat_exp_bb_conj(static_cast(j), static_cast(k)) + : mat_exp.bb(static_cast(j), static_cast(k)); phase *= this_phase; } } beta_phases(static_cast(i)) = phase; } - for (size_t i = 0; i < dim_a; ++i) - { + for (size_t i = 0; i < dim_a; ++i) { Complex phase = 1.0; int64_t str0 = strings_a[i]; - for (size_t j = 0; j < norb; ++j) - { + for (size_t j = 0; j < norb; ++j) { bool sign_j = (str0 >> j) & 1; - auto this_row = sign_j ? mat_exp_ab_conj.row(static_cast(j)) : mat_exp.ab.row(static_cast(j)); - for (size_t k = 0; k < norb; ++k) - { - phase_map(static_cast(i), static_cast(k)) *= this_row(static_cast(k)); + auto this_row = sign_j ? mat_exp_ab_conj.row(static_cast(j)) + : mat_exp.ab.row(static_cast(j)); + for (size_t k = 0; k < norb; ++k) { + phase_map(static_cast(i), static_cast(k)) *= + this_row(static_cast(k)); } - for (size_t k = j + 1; k < norb; ++k) - { + for (size_t k = j + 1; k < norb; ++k) { bool sign_k = (str0 >> k) & 1; - Complex this_phase = (sign_j ^ sign_k) ? mat_exp_aa_conj(static_cast(j), static_cast(k)) : mat_exp.aa(static_cast(j), static_cast(k)); + Complex this_phase = + (sign_j ^ sign_k) + ? mat_exp_aa_conj(static_cast(j), static_cast(k)) + : mat_exp.aa(static_cast(j), static_cast(k)); phase *= this_phase; } } alpha_phases(static_cast(i)) = phase; } - for (size_t i = 0; i < dim_a; ++i) - { - for (size_t j = 0; j < dim_b; ++j) - { - Complex phase = alpha_phases(static_cast(i)) * beta_phases(static_cast(j)); + for (size_t i = 0; i < dim_a; ++i) { + for (size_t j = 0; j < dim_b; ++j) { + Complex phase = alpha_phases(static_cast(i)) * + beta_phases(static_cast(j)); int64_t str0 = strings_b[j]; - for (size_t k = 0; k < norb; ++k) - { + for (size_t k = 0; k < norb; ++k) { bool sign = (str0 >> k) & 1; - phase *= sign ? std::conj(phase_map(static_cast(i), static_cast(k))) : phase_map(static_cast(i), static_cast(k)); + phase *= + sign ? std::conj( + phase_map(static_cast(i), static_cast(k)) + ) + : phase_map(static_cast(i), static_cast(k)); } vec(static_cast(i), static_cast(j)) *= phase; } @@ -305,8 +287,10 @@ void apply_diag_coulomb_evolution_in_place_z_rep(MatrixXcd& vec, uint64_t norb, } VectorXcd apply_diag_coulomb_evolution_spinfull( - VectorXcd vec, const Mat& mat, double time, uint64_t norb, std::pair nelec, - const std::optional& orbital_rotation, bool z_representation) + VectorXcd vec, const Mat &mat, double time, uint64_t norb, + std::pair nelec, + const std::optional &orbital_rotation, bool z_representation +) { MatExp mat_exp = get_mat_exp(mat, norb, z_representation, time); @@ -315,36 +299,39 @@ VectorXcd apply_diag_coulomb_evolution_spinfull( size_t dim_a = binomial(norb, n_alpha); size_t dim_b = binomial(norb, n_beta); - if (orbital_rotation.has_value()) - { + if (orbital_rotation.has_value()) { auto conj_rot = conjugate_orbital_rotation(orbital_rotation.value()); - vec = apply_orbital_rotation(vec, conj_rot, norb, - Electron{ElectronType::Spinfull, 0, {n_alpha, n_beta}}); + vec = apply_orbital_rotation( + vec, conj_rot, norb, Electron{ElectronType::Spinfull, 0, {n_alpha, n_beta}} + ); } - MatrixXcd vec_reshaped = Map(vec.data(), static_cast(dim_a), static_cast(dim_b)); + MatrixXcd vec_reshaped = Map( + vec.data(), static_cast(dim_a), static_cast(dim_b) + ); std::vector orb_list(norb); std::iota(orb_list.begin(), orb_list.end(), 0); - if (z_representation) - { + if (z_representation) { auto strings_a = make_strings(orb_list, n_alpha); auto strings_b = make_strings(orb_list, n_beta); - apply_diag_coulomb_evolution_in_place_z_rep(vec_reshaped, norb, mat_exp, - strings_a, strings_b); - } - else - { + apply_diag_coulomb_evolution_in_place_z_rep( + vec_reshaped, norb, mat_exp, strings_a, strings_b + ); + } else { auto occupations_a = gen_occslst(orb_list, n_alpha); auto occupations_b = gen_occslst(orb_list, n_beta); apply_diag_coulomb_evolution_in_place_num_rep( - vec_reshaped, norb, mat_exp, occupations_a, occupations_b); + vec_reshaped, norb, mat_exp, occupations_a, occupations_b + ); } - VectorXcd vec_flat = Map(vec_reshaped.data(), static_cast(dim_a * dim_b)); + VectorXcd vec_flat = + Map(vec_reshaped.data(), static_cast(dim_a * dim_b)); - if (orbital_rotation.has_value()) - { - vec_flat = apply_orbital_rotation(vec_flat, orbital_rotation.value(), norb, - Electron{ElectronType::Spinfull, 0, {n_alpha, n_beta}}); + if (orbital_rotation.has_value()) { + vec_flat = apply_orbital_rotation( + vec_flat, orbital_rotation.value(), norb, + Electron{ElectronType::Spinfull, 0, {n_alpha, n_beta}} + ); } return vec_flat; @@ -366,29 +353,30 @@ VectorXcd apply_diag_coulomb_evolution_spinfull( * @return The evolved vector after applying the diagonal Coulomb evolution * operator. */ -VectorXcd apply_diag_coulomb_evolution(const VectorXcd& vec, const Mat& mat, double time, - uint64_t norb, const Electron& nelec, - const std::optional& orb_rot, - bool z_representation) +VectorXcd apply_diag_coulomb_evolution( + const VectorXcd &vec, const Mat &mat, double time, uint64_t norb, + const Electron &nelec, const std::optional &orb_rot, + bool z_representation +) { - if (nelec.type == ElectronType::Spinless) - { - if (mat.type != MatType::Single) - { - throw std::runtime_error("Expected single matrix for spinless electron type"); + if (nelec.type == ElectronType::Spinless) { + if (mat.type != MatType::Single) { + throw std::runtime_error( + "Expected single matrix for spinless electron type" + ); } - if (z_representation) - { + if (z_representation) { throw std::runtime_error( - "z_representation is not supported for spinless electron type"); + "z_representation is not supported for spinless electron type" + ); } - return apply_diag_coulomb_evolution_spinfull(vec, mat, time, norb, {nelec.spinless, 0}, - orb_rot, false); - } - else - { - return apply_diag_coulomb_evolution_spinfull(vec, mat, time, norb, nelec.spinfull, orb_rot, - z_representation); + return apply_diag_coulomb_evolution_spinfull( + vec, mat, time, norb, {nelec.spinless, 0}, orb_rot, false + ); + } else { + return apply_diag_coulomb_evolution_spinfull( + vec, mat, time, norb, nelec.spinfull, orb_rot, z_representation + ); } } diff --git a/ffsim/include/ffsim/gates/orbital_rotation.hpp b/ffsim/include/ffsim/gates/orbital_rotation.hpp index d4cc8b8..4768cf7 100644 --- a/ffsim/include/ffsim/gates/orbital_rotation.hpp +++ b/ffsim/include/ffsim/gates/orbital_rotation.hpp @@ -42,15 +42,15 @@ std::size_t binomial(std::size_t n, std::size_t k) k = n - k; std::size_t result = 1; - for (std::size_t i = 1; i <= k; ++i) - { + for (std::size_t i = 1; i <= k; ++i) { result *= (n - k + i); result /= i; } return result; } -std::vector shifted_orbitals(uint64_t norb, const std::vector& target_orbs) +std::vector +shifted_orbitals(uint64_t norb, const std::vector &target_orbs) { std::vector orbitals(norb - target_orbs.size()); std::iota(orbitals.begin(), orbitals.end(), 0); @@ -58,56 +58,47 @@ std::vector shifted_orbitals(uint64_t norb, const std::vector& t std::vector> values; values.reserve(target_orbs.size()); - for (size_t i = 0; i < target_orbs.size(); ++i) - { + for (size_t i = 0; i < target_orbs.size(); ++i) { values.emplace_back(target_orbs[i], norb - target_orbs.size() + i); } std::sort(values.begin(), values.end()); - for (const auto& [idx, val] : values) - { + for (const auto &[idx, val] : values) { orbitals.insert(orbitals.begin() + static_cast(idx), val); } return orbitals; } -std::vector make_strings(const std::vector& orb_list, size_t nelec) +std::vector make_strings(const std::vector &orb_list, size_t nelec) { assert(orb_list.size() < 64); - if (nelec == 0) - { + if (nelec == 0) { return {0}; - } - else if (nelec > orb_list.size()) - { + } else if (nelec > orb_list.size()) { return {}; } - std::function(const std::vector&, size_t)> gen_str_iter = - [&](const std::vector& orb_list, size_t nelec) -> std::vector - { - if (nelec == 1) - { + std::function(const std::vector &, size_t)> + gen_str_iter = [&](const std::vector &orb_list, + size_t nelec) -> std::vector { + if (nelec == 1) { std::vector res; res.reserve(orb_list.size()); for (auto i : orb_list) res.push_back(1LL << i); return res; - } - else if (nelec >= orb_list.size()) - { + } else if (nelec >= orb_list.size()) { int64_t sum = 0; for (auto i : orb_list) sum |= (1LL << i); return {sum}; - } - else - { - std::vector res = gen_str_iter({orb_list.begin(), orb_list.end() - 1}, nelec); - for (auto n : gen_str_iter({orb_list.begin(), orb_list.end() - 1}, nelec - 1)) - { + } else { + std::vector res = + gen_str_iter({orb_list.begin(), orb_list.end() - 1}, nelec); + for (auto n : + gen_str_iter({orb_list.begin(), orb_list.end() - 1}, nelec - 1)) { res.push_back(n | (1LL << orb_list.back())); } return res; @@ -119,41 +110,48 @@ std::vector make_strings(const std::vector& orb_list, size_t ne return strings; } -std::vector zero_one_subspace_indices(uint64_t norb, size_t nocc, - const std::vector& target_orbs) +std::vector zero_one_subspace_indices( + uint64_t norb, size_t nocc, const std::vector &target_orbs +) { std::vector orbitals = shifted_orbitals(norb, target_orbs); std::vector strings = make_strings(orbitals, nocc); std::vector indices(strings.size()); std::iota(indices.begin(), indices.end(), 0); - std::sort(indices.begin(), indices.end(), - [&](size_t i, size_t j) { return strings[i] < strings[j]; }); + std::sort(indices.begin(), indices.end(), [&](size_t i, size_t j) { + return strings[i] < strings[j]; + }); size_t n00 = binomial(norb - 2, nocc); size_t n11 = (nocc >= 2) ? binomial(norb - 2, nocc - 2) : 0; - return std::vector(indices.begin() + static_cast(n00), indices.end() - static_cast(n11)); + return std::vector( + indices.begin() + static_cast(n00), + indices.end() - static_cast(n11) + ); } -std::vector one_subspace_indices(uint64_t norb, size_t nocc, - const std::vector& target_orbs) +std::vector +one_subspace_indices(uint64_t norb, size_t nocc, const std::vector &target_orbs) { std::vector orbitals = shifted_orbitals(norb, target_orbs); std::vector strings = make_strings(orbitals, nocc); std::vector indices(strings.size()); std::iota(indices.begin(), indices.end(), 0); - std::sort(indices.begin(), indices.end(), - [&](size_t i, size_t j) { return strings[i] < strings[j]; }); + std::sort(indices.begin(), indices.end(), [&](size_t i, size_t j) { + return strings[i] < strings[j]; + }); size_t n0 = binomial(norb, nocc); - if (nocc >= target_orbs.size()) - { + if (nocc >= target_orbs.size()) { n0 -= binomial(norb - target_orbs.size(), nocc - target_orbs.size()); } - return std::vector(indices.begin() + static_cast(n0), indices.end()); + return std::vector( + indices.begin() + static_cast(n0), indices.end() + ); } /** @@ -162,8 +160,7 @@ std::vector one_subspace_indices(uint64_t norb, size_t nocc, * - Spinless: One matrix for both spin-up and spin-down orbitals. * - Spinfull: Separate matrices for spin-up and spin-down orbitals. */ -enum class OrbitalRotationType : std::uint8_t -{ +enum class OrbitalRotationType : std::uint8_t { Spinless, ///< Shared matrix for both spin components. Spinfull ///< Separate matrices for each spin component. }; @@ -174,8 +171,7 @@ enum class OrbitalRotationType : std::uint8_t * - Spinless: One spin sector. * - Spinfull: Two separate spin sectors. */ -enum class ElectronType : std::uint8_t -{ +enum class ElectronType : std::uint8_t { Spinless, ///< Single spin type. Spinfull, ///< Spin-resolved. }; @@ -186,8 +182,7 @@ enum class ElectronType : std::uint8_t * Represents either a single orbital rotation matrix (`spinless`) * or two matrices for alpha and beta (`spinfull`). */ -struct OrbitalRotation -{ +struct OrbitalRotation { OrbitalRotationType type; ///< Indicates if the rotation is spinfull or spinless. MatrixXcd spinless; ///< Orbital rotation matrix for spinless case. std::array, 2> spinfull; ///< [0]: alpha, [1]: beta @@ -198,40 +193,38 @@ struct OrbitalRotation * * Indicates the number of electrons per spin channel. */ -struct Electron -{ - ElectronType type; ///< Spinless or spinfull electron setting. - size_t spinless; ///< Number of electrons for spinless case. - std::pair spinfull; ///< (alpha, beta) electron counts for spinfull. +struct Electron { + ElectronType type; ///< Spinless or spinfull electron setting. + size_t spinless; ///< Number of electrons for spinless case. + std::pair + spinfull; ///< (alpha, beta) electron counts for spinfull. }; -std::pair, VectorXcd>>, - std::optional, VectorXcd>>> -get_givens_decomposition(const OrbitalRotation& mat) +std::pair< + std::optional, VectorXcd>>, + std::optional, VectorXcd>>> +get_givens_decomposition(const OrbitalRotation &mat) { - if (mat.type == OrbitalRotationType::Spinless) - { + if (mat.type == OrbitalRotationType::Spinless) { auto decomp = linalg::givens_decomposition(mat.spinless); return {decomp, decomp}; - } - else - { - std::optional, VectorXcd>> decomp_a, decomp_b; - if (const auto& opt_mat_0 = mat.spinfull[0]; opt_mat_0.has_value()) - { + } else { + std::optional, VectorXcd>> + decomp_a, decomp_b; + if (const auto &opt_mat_0 = mat.spinfull[0]; opt_mat_0.has_value()) { decomp_a = linalg::givens_decomposition(opt_mat_0.value()); } - if (const auto& opt_mat_1 = mat.spinfull[1]; opt_mat_1.has_value()) - { + if (const auto &opt_mat_1 = mat.spinfull[1]; opt_mat_1.has_value()) { decomp_b = linalg::givens_decomposition(opt_mat_1.value()); } return {decomp_a, decomp_b}; } } -void apply_givens_rotation_in_place(MatrixXcd& vec, double c, Complex s, - const std::vector& slice1, - const std::vector& slice2) +void apply_givens_rotation_in_place( + MatrixXcd &vec, double c, Complex s, const std::vector &slice1, + const std::vector &slice2 +) { auto dim_b = vec.cols(); double s_abs = std::abs(s); @@ -239,8 +232,7 @@ void apply_givens_rotation_in_place(MatrixXcd& vec, double c, Complex s, Complex phase(std::cos(angle), std::sin(angle)); Complex phase_conj = std::conj(phase); - for (size_t k = 0; k < slice1.size(); ++k) - { + for (size_t k = 0; k < slice1.size(); ++k) { size_t i = slice1[k]; size_t j = slice2[k]; VectorXcd row_i = vec.row(static_cast(i)); @@ -249,8 +241,7 @@ void apply_givens_rotation_in_place(MatrixXcd& vec, double c, Complex s, // altanative method: zscal -> zdrot -> zscal row_i *= phase_conj; - for (int n = 0; n < dim_b; ++n) - { + for (int n = 0; n < dim_b; ++n) { Complex temp = c * row_i[n] + s_abs * row_j[n]; row_j[n] = c * row_j[n] - s_abs * row_i[n]; row_i[n] = temp; @@ -262,9 +253,10 @@ void apply_givens_rotation_in_place(MatrixXcd& vec, double c, Complex s, } } -void apply_orbital_rotation_adjacent_spin_inplace(MatrixXcd& vec, double c, Complex s, - const std::pair& target_orbs, - uint64_t norb, size_t nelec) +void apply_orbital_rotation_adjacent_spin_inplace( + MatrixXcd &vec, double c, Complex s, + const std::pair &target_orbs, uint64_t norb, size_t nelec +) { size_t i = target_orbs.first; size_t j = target_orbs.second; @@ -272,37 +264,44 @@ void apply_orbital_rotation_adjacent_spin_inplace(MatrixXcd& vec, double c, Comp std::vector indices = one_subspace_indices(norb, nelec, {i, j}); size_t half = indices.size() / 2; - std::vector silce1(indices.begin(), indices.begin() + static_cast(half)); - std::vector slice2(indices.begin() + static_cast(half), indices.end()); + std::vector silce1( + indices.begin(), indices.begin() + static_cast(half) + ); + std::vector slice2( + indices.begin() + static_cast(half), indices.end() + ); apply_givens_rotation_in_place(vec, c, s, silce1, slice2); } -VectorXcd apply_orbital_rotation_spinless(VectorXcd& vec, const MatrixXcd& mat, uint64_t norb, - size_t nelec) +VectorXcd apply_orbital_rotation_spinless( + VectorXcd &vec, const MatrixXcd &mat, uint64_t norb, size_t nelec +) { auto [rotations, phase_shifts] = linalg::givens_decomposition(mat); MatrixXcd reshaped = vec; reshaped.resize(vec.size(), 1); - for (const auto& rotation : rotations) - { - apply_orbital_rotation_adjacent_spin_inplace(reshaped, rotation.c, std::conj(rotation.s), - std::make_pair(rotation.i, rotation.j), norb, - nelec); + for (const auto &rotation : rotations) { + apply_orbital_rotation_adjacent_spin_inplace( + reshaped, rotation.c, std::conj(rotation.s), + std::make_pair(rotation.i, rotation.j), norb, nelec + ); } - for (size_t i = 0; i < phase_shifts.size(); ++i) - { + for (size_t i = 0; i < phase_shifts.size(); ++i) { auto indices = one_subspace_indices(norb, nelec, {i}); - apply_phase_shift_in_place(reshaped, phase_shifts(static_cast(i)), indices); + apply_phase_shift_in_place( + reshaped, phase_shifts(static_cast(i)), indices + ); } return Map(reshaped.data(), vec.size()); } -VectorXcd apply_orbital_rotation_spinfull(VectorXcd& vec, - const std::array, 2>& mat, - uint64_t norb, const std::pair& nelec) +VectorXcd apply_orbital_rotation_spinfull( + VectorXcd &vec, const std::array, 2> &mat, uint64_t norb, + const std::pair &nelec +) { size_t n_alpha = nelec.first; @@ -319,35 +318,35 @@ VectorXcd apply_orbital_rotation_spinfull(VectorXcd& vec, auto [decomp_a, decomp_b] = get_givens_decomposition(rot); - if (decomp_a) - { - auto& [rots_a, phase_shifts_a] = *decomp_a; - for (const auto& rotation : rots_a) - { + if (decomp_a) { + auto &[rots_a, phase_shifts_a] = *decomp_a; + for (const auto &rotation : rots_a) { apply_orbital_rotation_adjacent_spin_inplace( - reshaped, rotation.c, std::conj(rotation.s), std::make_pair(rotation.i, rotation.j), - norb, n_alpha); + reshaped, rotation.c, std::conj(rotation.s), + std::make_pair(rotation.i, rotation.j), norb, n_alpha + ); } - for (size_t i = 0; i < phase_shifts_a.size(); ++i) - { + for (size_t i = 0; i < phase_shifts_a.size(); ++i) { auto indices = one_subspace_indices(norb, n_alpha, {i}); - apply_phase_shift_in_place(reshaped, phase_shifts_a(static_cast(i)), indices); + apply_phase_shift_in_place( + reshaped, phase_shifts_a(static_cast(i)), indices + ); } } - if (decomp_b) - { + if (decomp_b) { MatrixXcd transposed = reshaped.transpose(); - auto& [rots_b, phase_shifts_b] = *decomp_b; - for (const auto& rotation : rots_b) - { + auto &[rots_b, phase_shifts_b] = *decomp_b; + for (const auto &rotation : rots_b) { apply_orbital_rotation_adjacent_spin_inplace( transposed, rotation.c, std::conj(rotation.s), - std::make_pair(rotation.i, rotation.j), norb, n_beta); + std::make_pair(rotation.i, rotation.j), norb, n_beta + ); } - for (size_t i = 0; i < phase_shifts_b.size(); ++i) - { + for (size_t i = 0; i < phase_shifts_b.size(); ++i) { auto indices = one_subspace_indices(norb, n_beta, {i}); - apply_phase_shift_in_place(transposed, phase_shifts_b(static_cast(i)), indices); + apply_phase_shift_in_place( + transposed, phase_shifts_b(static_cast(i)), indices + ); } reshaped = transposed.transpose(); } @@ -367,21 +366,24 @@ VectorXcd apply_orbital_rotation_spinfull(VectorXcd& vec, * * @return Rotated vector. */ -VectorXcd apply_orbital_rotation(VectorXcd& vec, const OrbitalRotation& rotation, uint64_t norb, - const Electron& nelec) +VectorXcd apply_orbital_rotation( + VectorXcd &vec, const OrbitalRotation &rotation, uint64_t norb, + const Electron &nelec +) { - if (nelec.type == ElectronType::Spinless) - { - if (rotation.type != OrbitalRotationType::Spinless) - { + if (nelec.type == ElectronType::Spinless) { + if (rotation.type != OrbitalRotationType::Spinless) { throw std::runtime_error( - "Expected spinless orbital rotation with spinless electron type"); + "Expected spinless orbital rotation with spinless electron type" + ); } - return apply_orbital_rotation_spinless(vec, rotation.spinless, norb, nelec.spinless); - } - else - { - return apply_orbital_rotation_spinfull(vec, rotation.spinfull, norb, nelec.spinfull); + return apply_orbital_rotation_spinless( + vec, rotation.spinless, norb, nelec.spinless + ); + } else { + return apply_orbital_rotation_spinfull( + vec, rotation.spinfull, norb, nelec.spinfull + ); } } @@ -395,39 +397,30 @@ VectorXcd apply_orbital_rotation(VectorXcd& vec, const OrbitalRotation& rotation * * @return Vector of occupation lists (each list is a set of orbital indices). */ -std::vector> gen_occslst(const std::vector& orb_list, size_t nelec) +std::vector> +gen_occslst(const std::vector &orb_list, size_t nelec) { - if (nelec == 0) - { + if (nelec == 0) { return {std::vector(0)}; - } - else if (nelec > orb_list.size()) - { + } else if (nelec > orb_list.size()) { return {{}}; } - std::function>(const std::vector&, size_t)> - gen_occs_iter = - [&](const std::vector& list, size_t n) -> std::vector> - { - if (n == 1) - { + std::function>(const std::vector &, size_t)> + gen_occs_iter = [&](const std::vector &list, + size_t n) -> std::vector> { + if (n == 1) { std::vector> res; res.reserve(list.size()); - for (auto i : list) - { + for (auto i : list) { res.push_back({i}); } return res; - } - else if (n >= list.size()) - { + } else if (n >= list.size()) { return {list}; - } - else - { - std::vector> res = gen_occs_iter({list.begin(), list.end() - 1}, n); - for (auto& v : gen_occs_iter({list.begin(), list.end() - 1}, n - 1)) - { + } else { + std::vector> res = + gen_occs_iter({list.begin(), list.end() - 1}, n); + for (auto &v : gen_occs_iter({list.begin(), list.end() - 1}, n - 1)) { v.push_back(list.back()); res.push_back(v); } diff --git a/ffsim/include/ffsim/gates/phase_shift.hpp b/ffsim/include/ffsim/gates/phase_shift.hpp index 3d23801..7828614 100644 --- a/ffsim/include/ffsim/gates/phase_shift.hpp +++ b/ffsim/include/ffsim/gates/phase_shift.hpp @@ -32,11 +32,11 @@ using Complex = std::complex; * @param indices The indices of the rows/columns to which the phase shift is * applied. */ -void apply_phase_shift_in_place(MatrixXcd& mat, const Complex& phase, - const std::vector& indices) +void apply_phase_shift_in_place( + MatrixXcd &mat, const Complex &phase, const std::vector &indices +) { - for (size_t row : indices) - { + for (size_t row : indices) { mat.row(static_cast(row)) *= phase; } } diff --git a/ffsim/include/ffsim/linalg/double_factorized_decomp.hpp b/ffsim/include/ffsim/linalg/double_factorized_decomp.hpp index 3a0dbdb..d516ea8 100644 --- a/ffsim/include/ffsim/linalg/double_factorized_decomp.hpp +++ b/ffsim/include/ffsim/linalg/double_factorized_decomp.hpp @@ -39,7 +39,7 @@ using Complex = std::complex; * @param sign The sign of the imaginary unit (1 or -1) * @return The quadrature-transformed matrix */ -MatrixXcd quadrature(const MatrixXcd& mat, int sign) +MatrixXcd quadrature(const MatrixXcd &mat, int sign) { Complex i(0.0, 1.0); Complex factor = 0.5 * (1.0 - static_cast(sign) * i); @@ -67,9 +67,9 @@ MatrixXcd quadrature(const MatrixXcd& mat, int sign) * @return A tuple of (diag_coulomb_out, orbital_rotations), both tensors of * shape `[n_vecs, 2, norb, norb]` */ -std::tuple, Tensor> -double_factorized_t2(const Tensor& t2_amplitudes, double tol, - std::optional max_vecs) +std::tuple, Tensor> double_factorized_t2( + const Tensor &t2_amplitudes, double tol, std::optional max_vecs +) { const auto dims = t2_amplitudes.dimensions(); @@ -79,30 +79,24 @@ double_factorized_t2(const Tensor& t2_amplitudes, double tol, const int n_pairs = nocc * nvrt; std::vector occ, vrt; - for (int i = 0; i < nocc; ++i) - { - for (int j = 0; j < nvrt; ++j) - { + for (int i = 0; i < nocc; ++i) { + for (int j = 0; j < nvrt; ++j) { occ.push_back(i); vrt.push_back(j); } } std::vector row, col; - for (int i = 0; i < nocc; ++i) - { - for (int a = nocc; a < norb; ++a) - { + for (int i = 0; i < nocc; ++i) { + for (int a = nocc; a < norb; ++a) { col.push_back(i); row.push_back(a); } } MatrixXcd t2_mat = MatrixXcd::Zero(n_pairs, n_pairs); - for (int p = 0; p < n_pairs; ++p) - { - for (int q = 0; q < n_pairs; ++q) - { + for (int p = 0; p < n_pairs; ++p) { + for (int q = 0; q < n_pairs; ++q) { t2_mat(p, q) = t2_amplitudes(occ[p], occ[q], vrt[p], vrt[q]); } } @@ -113,70 +107,67 @@ double_factorized_t2(const Tensor& t2_amplitudes, double tol, std::vector indices(eigs.size()); std::iota(indices.begin(), indices.end(), 0); - std::sort(indices.begin(), indices.end(), - [&](size_t i, size_t j) { return std::abs(eigs[static_cast(j)]) < std::abs(eigs[static_cast(i)]); }); + std::sort(indices.begin(), indices.end(), [&](size_t i, size_t j) { + return std::abs(eigs[static_cast(j)]) < + std::abs(eigs[static_cast(i)]); + }); VectorXcd eigs_sorted(eigs.size()); MatrixXcd vecs_sorted(vecs.rows(), vecs.cols()); - for (size_t i = 0; i < indices.size(); ++i) - { + for (size_t i = 0; i < indices.size(); ++i) { eigs_sorted(static_cast(i)) = eigs(static_cast(indices[i])); - vecs_sorted.col(static_cast(i)) = vecs.col(static_cast(indices[i])); + vecs_sorted.col(static_cast(i)) = + vecs.col(static_cast(indices[i])); } double acc = 0.0; size_t n_discard = eigs_sorted.size(); - for (int i = static_cast(eigs_sorted.size()) - 1; i >= 0; --i) - { + for (int i = static_cast(eigs_sorted.size()) - 1; i >= 0; --i) { acc += std::abs(eigs_sorted(i)); - if (acc >= tol) - { + if (acc >= tol) { n_discard = eigs_sorted.size() - 1 - i; break; } } size_t n_vecs = eigs_sorted.size() - n_discard; - if (max_vecs.has_value()) - { + if (max_vecs.has_value()) { n_vecs = std::min(n_vecs, max_vecs.value()); } - Tensor one_body_tensors(static_cast(n_vecs), 2, static_cast(norb), static_cast(norb)); + Tensor one_body_tensors( + static_cast(n_vecs), 2, static_cast(norb), static_cast(norb) + ); one_body_tensors.setZero(); - for (size_t k = 0; k < n_vecs; ++k) - { + for (size_t k = 0; k < n_vecs; ++k) { MatrixXcd mat = MatrixXcd::Zero(norb, norb); - for (int idx = 0; idx < n_pairs; ++idx) - { + for (int idx = 0; idx < n_pairs; ++idx) { mat(row[idx], col[idx]) = vecs_sorted(idx, static_cast(k)); } MatrixXcd Qp = quadrature(mat, 1); MatrixXcd Qm = quadrature(mat, -1); - for (int i = 0; i < norb; ++i) - { - for (int j = 0; j < norb; ++j) - { + for (int i = 0; i < norb; ++i) { + for (int j = 0; j < norb; ++j) { one_body_tensors(static_cast(k), 0, i, j) = Qp(i, j); one_body_tensors(static_cast(k), 1, i, j) = Qm(i, j); } } } - Tensor orbital_rotations(static_cast(n_vecs), 2, static_cast(norb), static_cast(norb)); + Tensor orbital_rotations( + static_cast(n_vecs), 2, static_cast(norb), static_cast(norb) + ); orbital_rotations.setZero(); - Tensor eigs_tensor(static_cast(n_vecs), 2, static_cast(norb)); + Tensor eigs_tensor( + static_cast(n_vecs), 2, static_cast(norb) + ); - for (size_t k = 0; k < n_vecs; ++k) - { - for (int s = 0; s < 2; ++s) - { + for (size_t k = 0; k < n_vecs; ++k) { + for (int s = 0; s < 2; ++s) { MatrixXcd tensor_mat(norb, norb); - for (int i = 0; i < norb; ++i) - { - for (int j = 0; j < norb; ++j) - { + for (int i = 0; i < norb; ++i) { + for (int j = 0; j < norb; ++j) { tensor_mat(i, j) = one_body_tensors(static_cast(k), s, i, j); } } @@ -185,49 +176,45 @@ double_factorized_t2(const Tensor& t2_amplitudes, double tol, VectorXd evals = es_tensor.eigenvalues(); MatrixXcd evecs = es_tensor.eigenvectors(); - for (int i = 0; i < norb; ++i) - { + for (int i = 0; i < norb; ++i) { eigs_tensor(static_cast(k), s, static_cast(i)) = evals(i); } - for (int i = 0; i < norb; ++i) - { - for (int j = 0; j < norb; ++j) - { + for (int i = 0; i < norb; ++i) { + for (int j = 0; j < norb; ++j) { orbital_rotations(static_cast(k), s, i, j) = evecs(i, j); } } } } - Tensor diag_coulomb(static_cast(n_vecs), 2, static_cast(norb), static_cast(norb)); - for (size_t i = 0; i < n_vecs; ++i) - { - for (int s = 0; s < 2; ++s) - { + Tensor diag_coulomb( + static_cast(n_vecs), 2, static_cast(norb), static_cast(norb) + ); + for (size_t i = 0; i < n_vecs; ++i) { + for (int s = 0; s < 2; ++s) { double sign_coeff = (s == 0) ? 1.0 : -1.0; - for (int a = 0; a < norb; ++a) - { - for (int b = 0; b < norb; ++b) - { - diag_coulomb(static_cast(i), s, a, b) = sign_coeff * eigs_tensor(static_cast(i), s, a) * - eigs_tensor(static_cast(i), s, b) * eigs_sorted(static_cast(i)).real(); + for (int a = 0; a < norb; ++a) { + for (int b = 0; b < norb; ++b) { + diag_coulomb(static_cast(i), s, a, b) = + sign_coeff * eigs_tensor(static_cast(i), s, a) * + eigs_tensor(static_cast(i), s, b) * + eigs_sorted(static_cast(i)).real(); } } } } - Tensor diag_coulomb_out(static_cast(n_vecs), 2, static_cast(norb), static_cast(norb)); + Tensor diag_coulomb_out( + static_cast(n_vecs), 2, static_cast(norb), static_cast(norb) + ); diag_coulomb_out.setZero(); - for (size_t i = 0; i < n_vecs; ++i) - { - for (int s = 0; s < 2; ++s) - { - for (int a = 0; a < norb; ++a) - { - for (int b = 0; b < norb; ++b) - { - diag_coulomb_out(static_cast(i), s, a, b) = Complex(diag_coulomb(static_cast(i), s, a, b), 0.0); + for (size_t i = 0; i < n_vecs; ++i) { + for (int s = 0; s < 2; ++s) { + for (int a = 0; a < norb; ++a) { + for (int b = 0; b < norb; ++b) { + diag_coulomb_out(static_cast(i), s, a, b) = + Complex(diag_coulomb(static_cast(i), s, a, b), 0.0); } } } diff --git a/ffsim/include/ffsim/linalg/expm.hpp b/ffsim/include/ffsim/linalg/expm.hpp index 6cc746d..70f49e7 100644 --- a/ffsim/include/ffsim/linalg/expm.hpp +++ b/ffsim/include/ffsim/linalg/expm.hpp @@ -28,7 +28,10 @@ using namespace Eigen; * @param A The input matrix for which the exponential is to be computed. * @return The matrix exponential of the input matrix A. */ -MatrixXcd expm(const MatrixXcd& A) { return A.exp(); } +MatrixXcd expm(const MatrixXcd &A) +{ + return A.exp(); +} } // namespace linalg } // namespace ffsim #endif // EXPM_HPP \ No newline at end of file diff --git a/ffsim/include/ffsim/linalg/givens.hpp b/ffsim/include/ffsim/linalg/givens.hpp index 1a94748..392c135 100644 --- a/ffsim/include/ffsim/linalg/givens.hpp +++ b/ffsim/include/ffsim/linalg/givens.hpp @@ -28,19 +28,16 @@ namespace linalg using namespace Eigen; using Complex = std::complex; -extern "C" -{ - void zrotg_(Complex* a, Complex* b, double* c, Complex* s); +extern "C" { +void zrotg_(Complex *a, Complex *b, double *c, Complex *s); } std::tuple zrotg(Complex ca, Complex cb) { - if (std::abs(ca) < 1e-12) - { + if (std::abs(ca) < 1e-12) { return {0.0, {1.0, 0.0}, {0.0, 0.0}}; } - if (std::abs(cb) < 1e-12) - { + if (std::abs(cb) < 1e-12) { return {1.0, {0.0, 0.0}, {0.0, 0.0}}; } double c; @@ -78,11 +75,10 @@ std::tuple zrotg(Complex ca, Complex cb); * @param c Cosine component of the rotation * @param s Sine component of the rotation (complex) */ -inline void zrot(VectorXcd& x, VectorXcd& y, double c, Complex s) +inline void zrot(VectorXcd &x, VectorXcd &y, double c, Complex s) { int n = static_cast(std::min(x.size(), y.size())); - for (int i = 0; i < n; ++i) - { + for (int i = 0; i < n; ++i) { Complex temp = c * x[i] + s * y[i]; y[i] = c * y[i] - std::conj(s) * x[i]; x[i] = temp; @@ -96,8 +92,7 @@ inline void zrot(VectorXcd& x, VectorXcd& y, double c, Complex s) * `(i, j)` that it acts on. This structure stores the parameters needed to * construct the rotation matrix or apply it to vectors or matrices. */ -struct GivensRotation -{ +struct GivensRotation { double c; ///< Cosine part of the rotation Complex s; ///< Sine part of the rotation (complex) size_t i, j; ///< Indices of the rows (or columns) involved in the rotation @@ -109,8 +104,11 @@ struct GivensRotation * @param first_index First index involved * @param second_index Second index involved */ - GivensRotation(double c, Complex s, size_t first_index, size_t second_index) : c(c), s(s), i(first_index), j(second_index) // NOLINT(bugprone-easily-swappable-parameters) - {} + GivensRotation(double c, Complex s, size_t first_index, size_t second_index) + : c(c), s(s), i(first_index), + j(second_index) // NOLINT(bugprone-easily-swappable-parameters) + { + } }; /** @@ -130,7 +128,8 @@ struct GivensRotation * - A vector of complex values representing the resulting diagonal */ -std::pair, VectorXcd> givens_decomposition(const MatrixXcd& mat) +std::pair, VectorXcd> +givens_decomposition(const MatrixXcd &mat) { int n = static_cast(mat.rows()); MatrixXcd current_matrix = mat; @@ -138,18 +137,15 @@ std::pair, VectorXcd> givens_decomposition(const Mat std::vector left_rotations; std::vector right_rotations; - for (int i = 0; i < n - 1; ++i) - { - if (i % 2 == 0) - { - for (int j = 0; j < i + 1; ++j) - { + for (int i = 0; i < n - 1; ++i) { + if (i % 2 == 0) { + for (int j = 0; j < i + 1; ++j) { int target = i - j; int row = n - j - 1; - if (std::abs(current_matrix(row, target)) > 1e-12) - { - auto [c, s, _] = - zrotg(current_matrix(row, target + 1), current_matrix(row, target)); + if (std::abs(current_matrix(row, target)) > 1e-12) { + auto [c, s, _] = zrotg( + current_matrix(row, target + 1), current_matrix(row, target) + ); right_rotations.emplace_back(c, s, target + 1, target); VectorXcd col1 = current_matrix.col(target + 1); VectorXcd col2 = current_matrix.col(target); @@ -159,17 +155,14 @@ std::pair, VectorXcd> givens_decomposition(const Mat current_matrix.col(target) = col2; } } - } - else - { - for (int j = 0; j < i + 1; ++j) - { + } else { + for (int j = 0; j < i + 1; ++j) { int target = n - i + j - 1; int col = j; - if (std::abs(current_matrix(target, col)) > 1e-9) - { - auto [c, s, _] = - zrotg(current_matrix(target - 1, col), current_matrix(target, col)); + if (std::abs(current_matrix(target, col)) > 1e-9) { + auto [c, s, _] = zrotg( + current_matrix(target - 1, col), current_matrix(target, col) + ); left_rotations.emplace_back(c, s, target - 1, target); VectorXcd row1 = current_matrix.row(target - 1); VectorXcd row2 = current_matrix.row(target); @@ -183,26 +176,35 @@ std::pair, VectorXcd> givens_decomposition(const Mat std::reverse(left_rotations.begin(), left_rotations.end()); - for (const auto& rot : left_rotations) - { + for (const auto &rot : left_rotations) { double c = rot.c; - Complex s = std::conj(rot.s) * current_matrix(static_cast(rot.i), static_cast(rot.i)); - auto [new_c, new_s, _] = zrotg(c * current_matrix(static_cast(rot.j), static_cast(rot.j)), s); + Complex s = + std::conj(rot.s) * + current_matrix(static_cast(rot.i), static_cast(rot.i)); + auto [new_c, new_s, _] = zrotg( + c * current_matrix(static_cast(rot.j), static_cast(rot.j)), s + ); right_rotations.emplace_back(new_c, -std::conj(new_s), rot.i, rot.j); Matrix2cd givens_mat; givens_mat << new_c, -new_s, std::conj(new_s), new_c; - givens_mat(0, 0) *= current_matrix(static_cast(rot.i), static_cast(rot.i)); - givens_mat(1, 0) *= current_matrix(static_cast(rot.i), static_cast(rot.i)); - givens_mat(0, 1) *= current_matrix(static_cast(rot.j), static_cast(rot.j)); - givens_mat(1, 1) *= current_matrix(static_cast(rot.j), static_cast(rot.j)); + givens_mat(0, 0) *= + current_matrix(static_cast(rot.i), static_cast(rot.i)); + givens_mat(1, 0) *= + current_matrix(static_cast(rot.i), static_cast(rot.i)); + givens_mat(0, 1) *= + current_matrix(static_cast(rot.j), static_cast(rot.j)); + givens_mat(1, 1) *= + current_matrix(static_cast(rot.j), static_cast(rot.j)); auto [c2, s2, _2] = zrotg(givens_mat(1, 1), givens_mat(1, 0)); Matrix2cd givens_mat2; givens_mat2 << c2, s2, -std::conj(s2), c2; Matrix2cd final_mat = givens_mat * givens_mat2; - current_matrix(static_cast(rot.i), static_cast(rot.i)) = final_mat(0, 0); - current_matrix(static_cast(rot.j), static_cast(rot.j)) = final_mat(1, 1); + current_matrix(static_cast(rot.i), static_cast(rot.i)) = + final_mat(0, 0); + current_matrix(static_cast(rot.j), static_cast(rot.j)) = + final_mat(1, 1); } return {right_rotations, current_matrix.diagonal()}; } diff --git a/ffsim/include/ffsim/linalg/logm.hpp b/ffsim/include/ffsim/linalg/logm.hpp index 9718a94..1b77cd5 100644 --- a/ffsim/include/ffsim/linalg/logm.hpp +++ b/ffsim/include/ffsim/linalg/logm.hpp @@ -28,7 +28,10 @@ using namespace Eigen; * @param A The input matrix for which the logarithm is to be computed. * @return The matrix logarithm of the input matrix A. */ -MatrixXcd logm(const MatrixXcd& A) { return A.log(); } +MatrixXcd logm(const MatrixXcd &A) +{ + return A.log(); +} } // namespace linalg } // namespace ffsim #endif // LOGM_HPP \ No newline at end of file diff --git a/ffsim/include/ffsim/linalg/matrix_utils.hpp b/ffsim/include/ffsim/linalg/matrix_utils.hpp index 429650f..47bfd64 100644 --- a/ffsim/include/ffsim/linalg/matrix_utils.hpp +++ b/ffsim/include/ffsim/linalg/matrix_utils.hpp @@ -11,22 +11,19 @@ namespace linalg { using namespace Eigen; using Complex = std::complex; -inline bool array_all_close(const MatrixXcd& mat1, const MatrixXcd& mat2, double rtol = 1e-5, - double atol = 1e-8) +inline bool array_all_close( + const MatrixXcd &mat1, const MatrixXcd &mat2, double rtol = 1e-5, double atol = 1e-8 +) { - if (mat1.rows() != mat2.rows() || mat1.cols() != mat2.cols()) - { + if (mat1.rows() != mat2.rows() || mat1.cols() != mat2.cols()) { return false; } - for (int i = 0; i < mat1.rows(); ++i) - { - for (int j = 0; j < mat1.cols(); ++j) - { - const Complex& a = mat1(i, j); - const Complex& b = mat2(i, j); - if (std::abs(a - b) > atol + rtol * std::abs(b)) - { + for (int i = 0; i < mat1.rows(); ++i) { + for (int j = 0; j < mat1.cols(); ++j) { + const Complex &a = mat1(i, j); + const Complex &b = mat2(i, j); + if (std::abs(a - b) > atol + rtol * std::abs(b)) { return false; } } @@ -34,19 +31,16 @@ inline bool array_all_close(const MatrixXcd& mat1, const MatrixXcd& mat2, double return true; } -inline bool is_real_symmetric(const MatrixXcd& mat, double rtol = 1e-5, double atol = 1e-8) +inline bool +is_real_symmetric(const MatrixXcd &mat, double rtol = 1e-5, double atol = 1e-8) { - if (mat.rows() != mat.cols()) - { + if (mat.rows() != mat.cols()) { return false; } - for (int i = 0; i < mat.rows(); ++i) - { - for (int j = 0; j < mat.cols(); ++j) - { - if (std::abs(mat(i, j).imag()) > atol) - { + for (int i = 0; i < mat.rows(); ++i) { + for (int j = 0; j < mat.cols(); ++j) { + if (std::abs(mat(i, j).imag()) > atol) { return false; } } @@ -54,10 +48,9 @@ inline bool is_real_symmetric(const MatrixXcd& mat, double rtol = 1e-5, double a return array_all_close(mat, mat.transpose(), rtol, atol); } -inline bool is_unitary(const MatrixXcd& mat, double rtol = 1e-5, double atol = 1e-8) +inline bool is_unitary(const MatrixXcd &mat, double rtol = 1e-5, double atol = 1e-8) { - if (mat.rows() != mat.cols()) - { + if (mat.rows() != mat.cols()) { return false; } diff --git a/src/sqd_helper.hpp b/src/sqd_helper.hpp index 7a8bfea..77d78a4 100644 --- a/src/sqd_helper.hpp +++ b/src/sqd_helper.hpp @@ -368,10 +368,8 @@ SQD generate_sqd_data(int argc, char *argv[]) return sqd; } -std::vector integer_to_bytes( - uint64_t n, // NOLINT(bugprone-easily-swappable-parameters) - int norb // NOLINT(bugprone-easily-swappable-parameters) -) +std::vector +integer_to_bytes(uint64_t n, int norb) // NOLINT(bugprone-easily-swappable-parameters) { int num_bytes = (norb + 7) / 8; std::vector result(num_bytes); @@ -438,7 +436,7 @@ std::string write_alphadets_file( const size_t norb, // NOLINT(bugprone-easily-swappable-parameters) const size_t num_elec, // NOLINT(bugprone-easily-swappable-parameters) const std::vector &batch, - const size_t // NOLINT(bugprone-easily-swappable-parameters) + const size_t maximum_numbers_of_ctrs, // NOLINT(bugprone-easily-swappable-parameters) const size_t i_recovery ) // NOLINT(bugprone-easily-swappable-parameters) From 011f6393668ee1300b4dcb6e0c60ddeb568caf4e Mon Sep 17 00:00:00 2001 From: to24toro Date: Wed, 1 Oct 2025 11:54:08 +0900 Subject: [PATCH 16/25] Fix lint.yaml and test_latest_versions.yaml --- .github/workflows/lint.yml | 16 +++++++++++++++- .github/workflows/test_latest_versions.yml | 3 ++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index cc348f0..5bb0088 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -35,14 +35,28 @@ jobs: sudo ln -fs clang-format-21 /usr/bin/clang-format sudo ln -fs clang-tidy-21 /usr/bin/clang-tidy sudo ln -fs /usr/bin/fdfind /usr/local/bin/fd + sudo apt-get install -y g++ clang cmake ninja-build \ + libopenblas-dev liblapack-dev libeigen3-dev \ + libopenmpi-dev openmpi-bin libomp-dev - name: Run clang-format check run: | fd '\.(cpp|hpp|h|c)$' src ffsim/include/ffsim \ --exec clang-format --dry-run -Werror + - name: Build qiskit + run: | + cd deps/qiskit + make c + - name: Build qrmi + run: | + cd deps/qrmi + cargo build --release - name: Configure CMake (for compile_commands.json) - run: cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -B build + run: cmake -S . -B build + -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON + -G Ninja + -DCMAKE_CXX_FLAGS="-DUSE_RANDOM_SHOTS=1" - name: Run clang-tidy run: | diff --git a/.github/workflows/test_latest_versions.yml b/.github/workflows/test_latest_versions.yml index 84698f7..dbe5e49 100644 --- a/.github/workflows/test_latest_versions.yml +++ b/.github/workflows/test_latest_versions.yml @@ -84,7 +84,8 @@ jobs: -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON ${{ matrix.compiler && format('-DCMAKE_CXX_COMPILER={0}', matrix.compiler) }} ${{ matrix.cxx_standard && format('-DCMAKE_CXX_STANDARD={0}', matrix.cxx_standard) }} - -DCMAKE_CXX_FLAGS="-DUSE_RANDOM_SHOTS=1" + -DCMAKE_CXX_FLAGS="-DUSE_RANDOM_SHOTS=1 -Xpreprocessor -fopenmp -I$(brew --prefix libomp)/include" + -DCMAKE_EXE_LINKER_FLAGS="-L$(brew --prefix libomp)/lib -lomp" - name: CMake Build run: >- cmake --build build -j4 From ebf8fcba79b2ebc22f93e3e5fbeeca5bfca4c1a1 Mon Sep 17 00:00:00 2001 From: to24toro Date: Wed, 1 Oct 2025 12:15:09 +0900 Subject: [PATCH 17/25] Fix test_latest_versions.yml --- .github/workflows/test_latest_versions.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test_latest_versions.yml b/.github/workflows/test_latest_versions.yml index dbe5e49..5f3bf89 100644 --- a/.github/workflows/test_latest_versions.yml +++ b/.github/workflows/test_latest_versions.yml @@ -77,8 +77,18 @@ jobs: run: | cd deps/qrmi cargo build --release - - name: Configure CMake + - name: Configure CMake (Linux) + if: runner.os == 'Linux' run: >- + cmake -S . -B build + -G Ninja + -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON + ${{ matrix.compiler && format('-DCMAKE_CXX_COMPILER={0}', matrix.compiler) }} + ${{ matrix.cxx_standard && format('-DCMAKE_CXX_STANDARD={0}', matrix.cxx_standard) }} + -DCMAKE_CXX_FLAGS="-DUSE_RANDOM_SHOTS=1" + - name: Configure CMake (macOS) + if: runner.os == 'macOS' + run: > cmake -S . -B build -G Ninja -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON From fcc66235e61779ee8105e6841e49061826f53105 Mon Sep 17 00:00:00 2001 From: to24toro Date: Wed, 1 Oct 2025 16:12:13 +0900 Subject: [PATCH 18/25] Remove clang-tidy --- .github/workflows/lint.yml | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 5bb0088..58bbc3c 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -33,32 +33,9 @@ jobs: sudo apt-get update sudo apt-get install -y fd-find clang-tidy-21 clang-format-21 cmake sudo ln -fs clang-format-21 /usr/bin/clang-format - sudo ln -fs clang-tidy-21 /usr/bin/clang-tidy sudo ln -fs /usr/bin/fdfind /usr/local/bin/fd - sudo apt-get install -y g++ clang cmake ninja-build \ - libopenblas-dev liblapack-dev libeigen3-dev \ - libopenmpi-dev openmpi-bin libomp-dev - name: Run clang-format check run: | fd '\.(cpp|hpp|h|c)$' src ffsim/include/ffsim \ - --exec clang-format --dry-run -Werror - - name: Build qiskit - run: | - cd deps/qiskit - make c - - name: Build qrmi - run: | - cd deps/qrmi - cargo build --release - - - name: Configure CMake (for compile_commands.json) - run: cmake -S . -B build - -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON - -G Ninja - -DCMAKE_CXX_FLAGS="-DUSE_RANDOM_SHOTS=1" - - - name: Run clang-tidy - run: | - fd '\.(cpp|hpp|h|c)$' src ffsim/include/ffsim \ - --exec-batch clang-tidy -p build --extra-arg=-Wno-error=missing-headers {} + + --exec clang-format --dry-run -Werror \ No newline at end of file From dc692e81249c0a46afbeb2a40bae5d1f1793d66d Mon Sep 17 00:00:00 2001 From: to24toro Date: Thu, 2 Oct 2025 12:35:13 +0900 Subject: [PATCH 19/25] Add test_latest_versions.yml --- .github/workflows/test_latest_versions.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test_latest_versions.yml b/.github/workflows/test_latest_versions.yml index 5f3bf89..ebb902d 100644 --- a/.github/workflows/test_latest_versions.yml +++ b/.github/workflows/test_latest_versions.yml @@ -89,13 +89,13 @@ jobs: - name: Configure CMake (macOS) if: runner.os == 'macOS' run: > - cmake -S . -B build - -G Ninja + brew install llvm libomp + cmake -S . -B build \ + -G Ninja \ + -DCMAKE_C_COMPILER=$(brew --prefix llvm)/bin/clang \ + -DCMAKE_CXX_COMPILER=$(brew --prefix llvm)/bin/clang++ \ + -DCMAKE_CXX_FLAGS="-DUSE_RANDOM_SHOTS=1" \ -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON - ${{ matrix.compiler && format('-DCMAKE_CXX_COMPILER={0}', matrix.compiler) }} - ${{ matrix.cxx_standard && format('-DCMAKE_CXX_STANDARD={0}', matrix.cxx_standard) }} - -DCMAKE_CXX_FLAGS="-DUSE_RANDOM_SHOTS=1 -Xpreprocessor -fopenmp -I$(brew --prefix libomp)/include" - -DCMAKE_EXE_LINKER_FLAGS="-L$(brew --prefix libomp)/lib -lomp" - name: CMake Build run: >- cmake --build build -j4 From 173bbc6fcd74c0a771ea918135e167fdf02a9392 Mon Sep 17 00:00:00 2001 From: to24toro Date: Thu, 2 Oct 2025 13:02:40 +0900 Subject: [PATCH 20/25] Add test_latest_versions.yml --- .github/workflows/test_latest_versions.yml | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/test_latest_versions.yml b/.github/workflows/test_latest_versions.yml index ebb902d..5099e59 100644 --- a/.github/workflows/test_latest_versions.yml +++ b/.github/workflows/test_latest_versions.yml @@ -86,16 +86,19 @@ jobs: ${{ matrix.compiler && format('-DCMAKE_CXX_COMPILER={0}', matrix.compiler) }} ${{ matrix.cxx_standard && format('-DCMAKE_CXX_STANDARD={0}', matrix.cxx_standard) }} -DCMAKE_CXX_FLAGS="-DUSE_RANDOM_SHOTS=1" - - name: Configure CMake (macOS) + - name: Install LLVM & libomp (macOS) if: runner.os == 'macOS' - run: > + run: | brew install llvm libomp + - name: Configure CMake (macOS, with Homebrew LLVM) + if: runner.os == 'macOS' + run: | cmake -S . -B build \ - -G Ninja \ - -DCMAKE_C_COMPILER=$(brew --prefix llvm)/bin/clang \ - -DCMAKE_CXX_COMPILER=$(brew --prefix llvm)/bin/clang++ \ - -DCMAKE_CXX_FLAGS="-DUSE_RANDOM_SHOTS=1" \ - -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON + -G Ninja \ + -DCMAKE_C_COMPILER=$(brew --prefix llvm)/bin/clang \ + -DCMAKE_CXX_COMPILER=$(brew --prefix llvm)/bin/clang++ \ + -DCMAKE_CXX_FLAGS="-DUSE_RANDOM_SHOTS=1" \ + -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON - name: CMake Build run: >- cmake --build build -j4 From 921aac380e8e399dd9af651ced9eb66b31a02128 Mon Sep 17 00:00:00 2001 From: to24toro Date: Thu, 2 Oct 2025 13:21:54 +0900 Subject: [PATCH 21/25] Add test_latest_versions.yml --- .github/workflows/test_latest_versions.yml | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/.github/workflows/test_latest_versions.yml b/.github/workflows/test_latest_versions.yml index 5099e59..4ee0bbd 100644 --- a/.github/workflows/test_latest_versions.yml +++ b/.github/workflows/test_latest_versions.yml @@ -46,12 +46,6 @@ jobs: compiler: g++ - os: ubuntu-22.04-arm compiler: clang++ - # macOS x86_64 - - os: macos-13 - compiler: clang++ - # macOS ARM - - os: macos-latest - compiler: clang++ steps: - uses: actions/checkout@v5 with: @@ -86,19 +80,6 @@ jobs: ${{ matrix.compiler && format('-DCMAKE_CXX_COMPILER={0}', matrix.compiler) }} ${{ matrix.cxx_standard && format('-DCMAKE_CXX_STANDARD={0}', matrix.cxx_standard) }} -DCMAKE_CXX_FLAGS="-DUSE_RANDOM_SHOTS=1" - - name: Install LLVM & libomp (macOS) - if: runner.os == 'macOS' - run: | - brew install llvm libomp - - name: Configure CMake (macOS, with Homebrew LLVM) - if: runner.os == 'macOS' - run: | - cmake -S . -B build \ - -G Ninja \ - -DCMAKE_C_COMPILER=$(brew --prefix llvm)/bin/clang \ - -DCMAKE_CXX_COMPILER=$(brew --prefix llvm)/bin/clang++ \ - -DCMAKE_CXX_FLAGS="-DUSE_RANDOM_SHOTS=1" \ - -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON - name: CMake Build run: >- cmake --build build -j4 From 488dd834b622f2fd87971e69eddd59a7c576ec9a Mon Sep 17 00:00:00 2001 From: to24toro Date: Thu, 2 Oct 2025 13:41:30 +0900 Subject: [PATCH 22/25] Fix coverage.yml --- .github/workflows/coverage.yml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index c577ae9..50c4de2 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -32,7 +32,7 @@ jobs: sudo apt-get install -y g++ clang cmake ninja-build \ libopenblas-dev liblapack-dev libeigen3-dev \ libopenmpi-dev openmpi-bin libomp-dev - - name: Install tox + - name: Install python library run: | python -m pip install --upgrade pip pip install gcovr @@ -46,9 +46,17 @@ jobs: run: | cd deps/qrmi cargo build --release - - name: Build - run: ninja -C build - + - name: Configure CMake (Linux) + if: runner.os == 'Linux' + run: >- + cmake -S . -B build + -G Ninja + -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON + -DCMAKE_CXX_FLAGS="-DUSE_RANDOM_SHOTS=1" + - name: CMake Build + run: >- + cmake --build build -j4 + --config Release - name: Run tests run: | cd build From 6dfda2bbd8b54c513547516f10f683cc8c2bde85 Mon Sep 17 00:00:00 2001 From: to24toro Date: Thu, 2 Oct 2025 14:06:38 +0900 Subject: [PATCH 23/25] Fix coverage.yml --- .github/workflows/coverage.yml | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 50c4de2..c3de6de 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -48,15 +48,15 @@ jobs: cargo build --release - name: Configure CMake (Linux) if: runner.os == 'Linux' - run: >- + run: > cmake -S . -B build -G Ninja - -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON - -DCMAKE_CXX_FLAGS="-DUSE_RANDOM_SHOTS=1" + -DCMAKE_BUILD_TYPE=Debug + -DCMAKE_CXX_FLAGS="-DUSE_RANDOM_SHOTS=1 --coverage" + - name: CMake Build - run: >- - cmake --build build -j4 - --config Release + run: cmake --build build -j4 + - name: Run tests run: | cd build @@ -67,15 +67,11 @@ jobs: --recovery 1 \ --number_of_samples 300 \ --num_shots 1000 + - name: Convert to json for coveralls if: always() - run: >- - gcovr --coveralls coveralls.json --root . - --exclude build + run: > + gcovr --coveralls coveralls.json + --root . + --object-directory build --exclude deps - - name: Upload report to Coveralls - if: always() - uses: coverallsapp/github-action@v2 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - file: coveralls.json From 5f8fa301b5f8efae71157d578c7baf7075ec8012 Mon Sep 17 00:00:00 2001 From: to24toro Date: Thu, 2 Oct 2025 14:25:53 +0900 Subject: [PATCH 24/25] Fix coverage.yml --- .github/workflows/coverage.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index c3de6de..a15dd5e 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -71,7 +71,8 @@ jobs: - name: Convert to json for coveralls if: always() run: > - gcovr --coveralls coveralls.json - --root . - --object-directory build - --exclude deps + gcovr --coveralls coveralls.json \ + --root . \ + --object-directory build \ + --exclude deps \ + --gcov-ignore-errors=no_working_dir_found,unrecognized From 86d72da032166c6199e32098147d415a9b2ed059 Mon Sep 17 00:00:00 2001 From: to24toro Date: Thu, 2 Oct 2025 14:42:10 +0900 Subject: [PATCH 25/25] Fix coverage.yml --- .github/workflows/coverage.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index a15dd5e..4adb600 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -75,4 +75,5 @@ jobs: --root . \ --object-directory build \ --exclude deps \ - --gcov-ignore-errors=no_working_dir_found,unrecognized + --gcov-ignore-errors=no_working_dir_found +