diff --git a/ccsrc/include/simulator/vector/vector_state.tpp b/ccsrc/include/simulator/vector/vector_state.tpp index 1003fcda98ab72a480f36714dcdca432cfe01f07..1e938ed19f79b517491d0527267eb63aab281ce0 100644 --- a/ccsrc/include/simulator/vector/vector_state.tpp +++ b/ccsrc/include/simulator/vector/vector_state.tpp @@ -1346,6 +1346,7 @@ auto VectorState::GetExpectationWithGradParameterShiftOneMulti( if (gate->GradRequired()) { auto p_gate = static_cast(gate.get()); std::shared_ptr tmp_gate; + bool is_multi_pr = false; switch (gate->id_) { case (GateID::RX): { tmp_gate = CONVERT_GATE(RXGate, p_gate); @@ -1397,10 +1398,12 @@ auto VectorState::GetExpectationWithGradParameterShiftOneMulti( } case (GateID::U3): { tmp_gate = CONVERT_GATE(U3, p_gate); + is_multi_pr = true; break; } case (GateID::FSim): { tmp_gate = CONVERT_GATE(FSim, p_gate); + is_multi_pr = true; break; } case (GateID::CUSTOM): { @@ -1444,16 +1447,10 @@ auto VectorState::GetExpectationWithGradParameterShiftOneMulti( VT intrin_grad_list(tmp_p_gate->prs_.size()); for (int k = 0; k < tmp_p_gate->prs_.size(); k++) { tmp_p_gate->prs_[k] += -pr_shift; - if (gate->id_ == GateID::U3 || gate->id_ == GateID::FSim) { - parameter::tn::Tensor coeff; - parameter::tn::Tensor tmp; - std::string key; - for (auto& [key_, v] : tmp_p_gate->prs_[k].data_) { - key = key_; - coeff = v; - tmp = pr.GetItem(key_); - } - tmp += -pr_shift / coeff; + if (is_multi_pr) { + std::string key = tmp_p_gate->prs_[k].data_.begin()->first; + parameter::tn::Tensor tmp = pr.GetItem(key); + tmp += -pr_shift / tmp_p_gate->prs_[k].data_.begin()->second; tmp_pr.SetItem(key, tmp); } sim_l = *this; @@ -1464,16 +1461,10 @@ auto VectorState::GetExpectationWithGradParameterShiftOneMulti( sim_rs[j - start].ApplyHamiltonian(*hams[j]); auto expect0 = qs_policy_t::Vdot(sim_l.qs, sim_rs[j - start].qs, dim); tmp_p_gate->prs_[k] += 2 * pr_shift; - if (gate->id_ == GateID::U3 || gate->id_ == GateID::FSim) { - parameter::tn::Tensor coeff; - parameter::tn::Tensor tmp; - std::string key; - for (auto& [key_, v] : tmp_p_gate->prs_[k].data_) { - key = key_; - coeff = v; - tmp = pr.GetItem(key_); - } - tmp += pr_shift / coeff; + if (is_multi_pr) { + std::string key = tmp_p_gate->prs_[k].data_.begin()->first; + parameter::tn::Tensor tmp = pr.GetItem(key); + tmp += pr_shift / tmp_p_gate->prs_[k].data_.begin()->second; tmp_pr.SetItem(key, tmp); } sim_l = *this; @@ -1484,16 +1475,9 @@ auto VectorState::GetExpectationWithGradParameterShiftOneMulti( sim_rs[j - start].ApplyHamiltonian(*hams[j]); auto expect1 = qs_policy_t::Vdot(sim_l.qs, sim_rs[j - start].qs, dim); tmp_p_gate->prs_[k] += -pr_shift; - if (gate->id_ == GateID::U3 || gate->id_ == GateID::FSim) { - parameter::tn::Tensor coeff; - parameter::tn::Tensor tmp; - std::string key; - for (auto& [key_, v] : tmp_p_gate->prs_[k].data_) { - key = key_; - coeff = v; - tmp = pr.GetItem(key_); - } - tmp_pr.SetItem(key, tmp); + if (is_multi_pr) { + std::string key = tmp_p_gate->prs_[k].data_.begin()->first; + tmp_pr.SetItem(key, pr.GetItem(key)); } intrin_grad_list[k] = {coeff * std::real(expect1 - expect0), 0}; } diff --git a/docs/api_python/core/circuit/mindquantum.core.circuit.Circuit.rst b/docs/api_python/core/circuit/mindquantum.core.circuit.Circuit.rst index 0af61083c5bbc05cd9ff47aa3281dd7e9374244c..347f5548023f260230e457cf8e9d750616841dcf 100644 --- a/docs/api_python/core/circuit/mindquantum.core.circuit.Circuit.rst +++ b/docs/api_python/core/circuit/mindquantum.core.circuit.Circuit.rst @@ -59,6 +59,10 @@ mindquantum.core.circuit.Circuit 删除所有未使用的量子比特,并将量子比特映射到 `range(n_qubits)` 。 + .. py:method:: copy() + + 返回该量子线路的浅拷贝。 + .. py:method:: encoder_params_name :property: diff --git a/mindquantum/core/circuit/circuit.py b/mindquantum/core/circuit/circuit.py index 25945d04c7c38b1f5331ff81fe0d0ba0f58154b1..35f2db3084646a6f5a68f903bb12235228437b4c 100644 --- a/mindquantum/core/circuit/circuit.py +++ b/mindquantum/core/circuit/circuit.py @@ -363,6 +363,10 @@ class Circuit(list): # pylint: disable=too-many-instance-attributes,too-many-pu self.append(gate) self.has_cpp_obj = False + def copy(self): + """Returns a shallow copy of the circuit.""" + return copy.copy(self) + def __add__(self, gates): """Addition operator.""" out = Circuit() diff --git a/mindquantum/core/gates/channel.py b/mindquantum/core/gates/channel.py index e8f7e516c93ecbbb10a8709580f48cee7e0a277b..c53d213ea3b3483bfffeb3b8a678b2d41aff0da9 100644 --- a/mindquantum/core/gates/channel.py +++ b/mindquantum/core/gates/channel.py @@ -174,6 +174,8 @@ class PauliChannel(NoiseGate, SelfHermitianGate): raise TypeError(f"Unsupported type for py, get {type(py)}.") if not isinstance(pz, (int, float)): raise TypeError(f"Unsupported type for pz, get {type(pz)}.") + if np.any(np.array([px, py, pz]) < 0.0): + raise ValueError("Probability cannot be negative value.") if 0 <= px + py + pz <= 1: self.px = float(px) self.py = float(py)