From d7c95b78ee7db87fb050048691f17afc9256c3e4 Mon Sep 17 00:00:00 2001 From: KowerKoint Date: Tue, 30 Jan 2024 11:18:36 +0900 Subject: [PATCH] implement circuit base --- qulacs/CMakeLists.txt | 1 + qulacs/all.hpp | 3 +++ qulacs/circuit/circuit.cpp | 43 ++++++++++++++++++++++++++++++++++++++ qulacs/circuit/circuit.hpp | 40 +++++++++++++++++++++++++++++++++++ 4 files changed, 87 insertions(+) create mode 100644 qulacs/circuit/circuit.cpp create mode 100644 qulacs/circuit/circuit.hpp diff --git a/qulacs/CMakeLists.txt b/qulacs/CMakeLists.txt index 97d765d5..c60405fb 100644 --- a/qulacs/CMakeLists.txt +++ b/qulacs/CMakeLists.txt @@ -1,6 +1,7 @@ cmake_minimum_required(VERSION 3.21) target_sources(qulacs PRIVATE + circuit/circuit.cpp gate/gate_npair_qubit.cpp gate/gate_one_control_one_target.cpp gate/gate_one_qubit.cpp diff --git a/qulacs/all.hpp b/qulacs/all.hpp index 2aa0bc49..7de1c32e 100644 --- a/qulacs/all.hpp +++ b/qulacs/all.hpp @@ -1,3 +1,6 @@ +#pragma once + +#include "circuit/circuit.hpp" #include "gate/constant.hpp" #include "gate/gate.hpp" #include "gate/gate_npair_qubit.hpp" diff --git a/qulacs/circuit/circuit.cpp b/qulacs/circuit/circuit.cpp new file mode 100644 index 00000000..4d1779ce --- /dev/null +++ b/qulacs/circuit/circuit.cpp @@ -0,0 +1,43 @@ +#include "circuit.hpp" + +#include + +namespace qulacs { +void Circuit::add_gate(const Gate& gate) { + check_gate_is_valid(gate); + _gate_list.push_back(gate); +} + +void Circuit::update_quantum_state(StateVector& state) const { + for (const auto& gate : _gate_list) { + gate->update_quantum_state(state); + } +} + +Circuit Circuit::copy() const { + Circuit ccircuit(_n_qubits); + for (const auto& gate : _gate_list) { + ccircuit.add_gate(gate->copy()); + } + return ccircuit; +} + +Circuit Circuit::get_inverse() const { + Circuit icircuit(_n_qubits); + for (const auto& gate : _gate_list | std::views::reverse) { + icircuit.add_gate(gate->get_inverse()); + } + return icircuit; +} + +void Circuit::check_gate_is_valid(const Gate& gate) const { + auto targets = gate->get_target_qubit_list(); + auto controls = gate->get_control_qubit_list(); + bool valid = true; + if (!targets.empty()) valid &= *std::max_element(targets.begin(), targets.end()) < _n_qubits; + if (!controls.empty()) valid &= *std::max_element(controls.begin(), controls.end()) < _n_qubits; + if (!valid) { + throw std::runtime_error("Gate to be added to the circuit has invalid qubit range"); + } +} +} // namespace qulacs diff --git a/qulacs/circuit/circuit.hpp b/qulacs/circuit/circuit.hpp new file mode 100644 index 00000000..def15206 --- /dev/null +++ b/qulacs/circuit/circuit.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include "../gate/gate.hpp" +#include "../types.hpp" + +namespace qulacs { +class Circuit { +public: + explicit Circuit(UINT n_qubits) : _n_qubits(n_qubits) {} + + [[nodiscard]] inline UINT n_qubits() const { return _n_qubits; } + [[nodiscard]] inline const std::vector& gate_list() const { return _gate_list; } + [[nodiscard]] inline const Gate& get(UINT idx) const { + if (idx >= _gate_list.size()) { + throw std::runtime_error("Circuit::get(UINT): index out of bounds"); + } + return _gate_list[idx]; + } + [[nodiscard]] inline Gate& get(UINT idx) { + if (idx >= _gate_list.size()) { + throw std::runtime_error("Circuit::get(UINT): index out of bounds"); + } + return _gate_list[idx]; + } + + void add_gate(const Gate& gate); + + void update_quantum_state(StateVector& state) const; + + Circuit copy() const; + Circuit get_inverse() const; + +private: + UINT _n_qubits; + + std::vector _gate_list; + + void check_gate_is_valid(const Gate& gate) const; +}; +} // namespace qulacs