Skip to content

Commit

Permalink
Merge pull request #185 from Qulacs-Osaka/kosukemtr/noisy_evolution
Browse files Browse the repository at this point in the history
リンドブラッド方程式のモンテカルロソルバ
  • Loading branch information
kotamanegi committed Apr 6, 2022
2 parents 5cdaa24 + aca0c6f commit 09e63a3
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 2 deletions.
12 changes: 12 additions & 0 deletions pysrc/qulacs/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ class GeneralQuantumOperator():
"""
Get expectation value
"""
def get_expectation_value_single_thread(self, state: QuantumStateBase) -> complex:
"""
Get expectation value
"""
def get_qubit_count(self) -> int:
"""
Get qubit count
Expand Down Expand Up @@ -189,6 +193,10 @@ class Observable(GeneralQuantumOperator):
"""
Get expectation value
"""
def get_expectation_value_single_thread(self, state: QuantumStateBase) -> float:
"""
Get expectation value
"""
def get_qubit_count(self) -> int:
"""
Get qubit count
Expand Down Expand Up @@ -455,6 +463,10 @@ class PauliOperator():
"""
Get expectation value
"""
def get_expectation_value_single_thread(self, state: QuantumStateBase) -> complex:
"""
Get expectation value
"""
def get_index_list(self) -> typing.List[int]:
"""
Get list of target qubit indices
Expand Down
1 change: 1 addition & 0 deletions pysrc/qulacs/gate.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def Identity(index: int) -> qulacs_core.QuantumGateBase: ...
def IndependentXZNoise(index: int, prob: float) -> qulacs_core.QuantumGateBase: ...
def Instrument(kraus_list: List[qulacs_core.QuantumGateBase], register: int) -> qulacs_core.QuantumGateBase: ...
def Measurement(index: int, register: int) -> qulacs_core.QuantumGateBase: ...
def NoisyEvolution(hamiltonian: qulacs_core.Observable, c_ops: List[qulacs_core.GeneralQuantumOperator], time: float, dt: float) -> qulacs_core.QuantumGateBase: ...
def P0(index: int) -> qulacs_core.QuantumGateBase: ...
def P1(index: int) -> qulacs_core.QuantumGateBase: ...
def ParametricPauliRotation(index_list: List[int], pauli_ids: List[int], angle: float) -> qulacs_core.QuantumGate_SingleParameter: ...
Expand Down
5 changes: 5 additions & 0 deletions pysrc/qulacs/gate/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ __all__ = [
"IndependentXZNoise",
"Instrument",
"Measurement",
"NoisyEvolution",
"P0",
"P1",
"ParametricPauliRotation",
Expand Down Expand Up @@ -144,6 +145,10 @@ def Measurement(index: int, register: int) -> qulacs_core.QuantumGateBase:
"""
Create measurement gate
"""
def NoisyEvolution(hamiltonian: qulacs_core.Observable, c_ops: typing.List[qulacs_core.GeneralQuantumOperator], time: float, dt: float) -> qulacs_core.QuantumGateBase:
"""
Create noisy evolution
"""
def P0(index: int) -> qulacs_core.QuantumGateBase:
"""
Create projection gate to |0> subspace
Expand Down
7 changes: 6 additions & 1 deletion python/cppsim_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ PYBIND11_MODULE(qulacs_core, m) {
.def("get_coef", &PauliOperator::get_coef, "Get coefficient of Pauli term")
.def("add_single_Pauli", &PauliOperator::add_single_Pauli, "Add Pauli operator to this term", py::arg("index"), py::arg("pauli_string"))
.def("get_expectation_value", &PauliOperator::get_expectation_value, "Get expectation value", py::arg("state"))
.def("get_expectation_value_single_thread", &PauliOperator::get_expectation_value_single_thread, "Get expectation value", py::arg("state"))
.def("get_transition_amplitude", &PauliOperator::get_transition_amplitude, "Get transition amplitude", py::arg("state_bra"), py::arg("state_ket"))
.def("copy", &PauliOperator::copy, pybind11::return_value_policy::take_ownership, "Create copied instance of Pauli operator class")
.def("get_pauli_string", &PauliOperator::get_pauli_string, "get pauli string")
Expand Down Expand Up @@ -78,6 +79,7 @@ PYBIND11_MODULE(qulacs_core, m) {
return quantum_operator.get_term(index)->copy();
}, pybind11::return_value_policy::take_ownership, "Get Pauli term", py::arg("index"))
.def("get_expectation_value", &GeneralQuantumOperator::get_expectation_value, "Get expectation value", py::arg("state"))
.def("get_expectation_value_single_thread", &GeneralQuantumOperator::get_expectation_value, "Get expectation value", py::arg("state"))
.def("get_transition_amplitude", &GeneralQuantumOperator::get_transition_amplitude, "Get transition amplitude", py::arg("state_bra"), py::arg("state_ket"))
.def("__str__", &GeneralQuantumOperator::to_string, "to string")
//.def_static("get_split_GeneralQuantumOperator", &(GeneralQuantumOperator::get_split_observable));
Expand Down Expand Up @@ -118,6 +120,9 @@ PYBIND11_MODULE(qulacs_core, m) {
.def("get_expectation_value", [](const HermitianQuantumOperator& observable, const QuantumStateBase* state) {
double res = observable.get_expectation_value(state).real();
return res;}, "Get expectation value", py::arg("state"))
.def("get_expectation_value_single_thread", [](const HermitianQuantumOperator& observable, const QuantumStateBase* state) {
double res = observable.get_expectation_value_single_thread(state).real();
return res;}, "Get expectation value", py::arg("state"))
.def("get_transition_amplitude", &HermitianQuantumOperator::get_transition_amplitude, "Get transition amplitude", py::arg("state_bra"), py::arg("state_ket"))
//.def_static("get_split_Observable", &(HermitianQuantumOperator::get_split_observable));
.def("add_random_operator", &HermitianQuantumOperator::add_random_operator, "Add random pauli operator", py::arg("operator_count"))
Expand Down Expand Up @@ -165,7 +170,6 @@ PYBIND11_MODULE(qulacs_core, m) {
.def("to_string",&QuantumState::to_string, "Get string representation")
.def("sampling", (std::vector<ITYPE> (QuantumState::*)(UINT))&QuantumState::sampling, "Sampling measurement results", py::arg("count"))
.def("sampling", (std::vector<ITYPE>(QuantumState::*)(UINT, UINT))&QuantumState::sampling, "Sampling measurement results", py::arg("count"), py::arg("seed"))

.def("get_vector", [](const QuantumState& state) {
Eigen::VectorXcd vec = Eigen::Map<Eigen::VectorXcd>(state.data_cpp(), state.dim);
return vec;
Expand Down Expand Up @@ -507,6 +511,7 @@ PYBIND11_MODULE(qulacs_core, m) {
mgate.def("Instrument", &gate::Instrument, pybind11::return_value_policy::take_ownership, "Create instruments", py::arg("kraus_list"), py::arg("register"));
mgate.def("Adaptive", py::overload_cast<QuantumGateBase *, std::function<bool(const std::vector<unsigned int>&)>> (&gate::Adaptive), pybind11::return_value_policy::take_ownership, "Create adaptive gate", py::arg("gate"), py::arg("condition"));
mgate.def("Adaptive", py::overload_cast<QuantumGateBase *, std::function<bool(const std::vector<unsigned int>&, unsigned int)>, unsigned int> (&gate::Adaptive), pybind11::return_value_policy::take_ownership, "Create adaptive gate", py::arg("gate"), py::arg("condition"),py::arg("id"));
mgate.def("NoisyEvolution", &gate::NoisyEvolution, pybind11::return_value_policy::take_ownership, "Create noisy evolution", py::arg("hamiltonian"), py::arg("c_ops"), py::arg("time"), py::arg("dt"));

py::class_<QuantumGate_SingleParameter, QuantumGateBase>(m, "QuantumGate_SingleParameter")
.def("get_parameter_value", &QuantumGate_SingleParameter::get_parameter_value, "Get parameter value")
Expand Down
1 change: 1 addition & 0 deletions src/cppsim/state_dm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ class DensityMatrixCpu : public QuantumStateBase {

/**
* \~japanese-en 量子状態を足しこむ
* TODO: implement this in single_thread
*/
virtual void add_state_with_coef_single_thread(
CPPCTYPE coef, const QuantumStateBase* state) override {
Expand Down
2 changes: 1 addition & 1 deletion test/cppsim/test_noisyevolution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ TEST(NoisyEvolutionTest, T1T2) {
double ref = -0.3135191750739427; // generated by qutip
UINT n = 2;
UINT n_samples = 100;

Observable observable(n);
observable.add_operator(1, "X 0");
// create hamiltonian and collapse operator
Expand Down Expand Up @@ -223,7 +224,6 @@ TEST(NoisyEvolutionTest, T1T2) {
gate::H(0)->update_quantum_state(&state);
gate::H(1)->update_quantum_state(&state);
circuit.update_quantum_state(&state);
state.normalize(state.get_squared_norm());
exp += observable.get_expectation_value(&state).real() / n_samples;
}
std::cout << "NoisyEvolution: " << exp << " ref: " << ref << std::endl;
Expand Down

0 comments on commit 09e63a3

Please sign in to comment.