32 #ifndef CLASSES_NOISE_H_ 33 #define CLASSES_NOISE_H_ 45 struct StateDependent;
51 struct StateIndependent;
62 std::is_same<NoiseType::StateDependent, noise_type>::value ||
63 std::is_same<NoiseType::StateIndependent, noise_type>::value,
67 const std::vector<cmat> Ks_;
68 mutable std::vector<double> probs_;
72 mutable bool generated_{
false};
83 void compute_probs_(
const cmat& state,
84 const std::vector<idx>& target)
const {
85 if (!std::is_same<NoiseType::StateDependent, noise_type>::value)
90 if (!internal::check_nonzero_size(state))
91 throw exception::ZeroSize(
"qpp::NoiseBase::compute_probs_()");
95 idx n = internal::get_num_subsys(state.rows(), d_);
97 for (idx i = 0; i < Ks_.size(); ++i) {
98 rho_i = ptrace(state, complement(target, n), d_);
99 probs_[i] = trace(Ks_[i] * rho_i * adjoint(Ks_[i])).real();
110 cmat compute_state_(
const cmat& state,
111 const std::vector<idx>& target)
const {
113 idx D =
static_cast<idx
>(state.rows());
116 if (internal::check_cvector(state)) {
120 else if (internal::check_square_mat(state)) {
125 throw exception::MatrixNotSquareNorCvector(
126 "qpp::NoiseBase::compute_state_()");
129 std::discrete_distribution<idx> dd{std::begin(probs_),
132 #ifdef NO_THREAD_LOCAL_ 133 RandomDevices::get_instance().get_prng();
135 RandomDevices::get_thread_local_instance().get_prng();
138 result = apply(state, Ks_[i_], target, d_);
141 return normalize(result);
152 template <
typename U = noise_type>
154 const std::vector<cmat>& Ks,
155 typename std::enable_if<
156 std::is_same<NoiseType::StateDependent, U>::value>::type* =
nullptr)
157 : Ks_{Ks}, probs_(Ks.size()) {
161 throw exception::ZeroSize(
"qpp::NoiseBase::NoiseBase()");
162 if (!internal::check_nonzero_size(Ks[0]))
163 throw exception::ZeroSize(
"qpp::NoiseBase::NoiseBase()");
164 if (!internal::check_square_mat(Ks[0]))
165 throw exception::MatrixNotSquare(
"qpp::NoiseBase::NoiseBase()");
166 for (
auto&& elem : Ks)
167 if (elem.rows() != Ks[0].rows() || elem.cols() != Ks[0].rows())
168 throw exception::DimsNotEqual(
"qpp::NoiseBase::NoiseBase()");
182 template <
typename U = noise_type>
184 const std::vector<cmat>& Ks,
const std::vector<double>& probs,
185 typename std::enable_if<std::is_same<NoiseType::StateIndependent,
186 U>::value>::type* =
nullptr)
187 : Ks_{Ks}, probs_(probs) {
191 throw exception::ZeroSize(
"qpp::NoiseBase::NoiseBase()");
192 if (Ks.size() != probs.size())
193 throw exception::SizeMismatch(
"qpp::NoiseBase::NoiseBase");
194 if (!internal::check_nonzero_size(Ks[0]))
195 throw exception::ZeroSize(
"qpp::NoiseBase::NoiseBase()");
196 if (!internal::check_square_mat(Ks[0]))
197 throw exception::MatrixNotSquare(
"qpp::NoiseBase::NoiseBase()");
198 for (
auto&& elem : Ks)
199 if (elem.rows() != Ks[0].rows() || elem.cols() != Ks[0].rows())
200 throw exception::DimsNotEqual(
"qpp::NoiseBase::NoiseBase()");
201 for (
auto&& elem : probs)
202 if (elem < 0 || elem > 1)
203 throw exception::OutOfRange(
"qpp::NoiseBase::NoiseBase");
213 virtual ~NoiseBase() =
default;
221 idx get_d() const noexcept {
return d_; };
228 std::vector<cmat> get_Ks()
const {
return Ks_; }
235 std::vector<double> get_probs()
const {
237 std::is_same<NoiseType::StateIndependent, noise_type>::value) {
240 throw exception::CustomException(
241 "qpp::NoiseBase::get_probs()",
242 "NoiseBase::operator() was not yet invoked");
250 idx get_last_idx()
const {
254 throw exception::CustomException(
255 "qpp::NoiseBase::get_last_idx()",
256 "NoiseBase::operator() was not yet invoked");
264 double get_last_p()
const {
268 throw exception::CustomException(
269 "qpp::NoiseBase::get_last_p()",
270 "NoiseBase::operator() was not yet invoked");
278 cmat get_last_K()
const {
282 throw exception::CustomException(
283 "qpp::NoiseBase::get_last_K()",
284 "NoiseBase::operator() was not yet invoked");
295 virtual cmat operator()(
const cmat& state)
const {
299 compute_probs_(state, std::vector<idx>{0});
300 result = compute_state_(state, std::vector<idx>{0});
301 }
catch (exception::Exception&) {
302 std::cerr <<
"In qpp::NoiseBase::operator()\n";
318 virtual cmat operator()(
const cmat& state, idx target)
const {
321 compute_probs_(state, std::vector<idx>{target});
322 result = compute_state_(state, std::vector<idx>{target});
323 }
catch (exception::Exception&) {
324 std::cerr <<
"In qpp::NoiseBase::operator()\n";
340 virtual cmat operator()(
const cmat& state,
341 const std::vector<idx>& target)
const {
344 compute_probs_(state, target);
345 result = compute_state_(state, target);
346 }
catch (exception::Exception&) {
347 std::cerr <<
"In qpp::NoiseBase::operator()\n";
361 class QubitDepolarizingNoise :
public NoiseBase<NoiseType::StateIndependent> {
368 explicit QubitDepolarizingNoise(
double p)
369 : NoiseBase({Gates::get_instance().Id2, Gates::get_instance().X,
370 Gates::get_instance().Y, Gates::get_instance().Z},
371 {1 - p, p / 3, p / 3, p / 3}) {
375 throw exception::OutOfRange(
376 "qpp::QubitDepolarizingNoise::QubitDepolarizingNoise()");
385 class QubitPhaseFlipNoise :
public NoiseBase<NoiseType::StateIndependent> {
392 explicit QubitPhaseFlipNoise(
double p)
393 : NoiseBase({Gates::get_instance().Id2, Gates::get_instance().Z},
398 throw exception::OutOfRange(
399 "qpp::QubitPhaseFlipNoise::QubitPhaseFlipNoise()");
408 class QubitBitFlipNoise :
public NoiseBase<NoiseType::StateIndependent> {
415 explicit QubitBitFlipNoise(
double p)
416 : NoiseBase({Gates::get_instance().Id2, Gates::get_instance().X},
421 throw exception::OutOfRange(
422 "qpp::QubitBitFlipNoise::QubitBitFlipNoise()");
431 class QubitBitPhaseFlipNoise :
public NoiseBase<NoiseType::StateIndependent> {
438 explicit QubitBitPhaseFlipNoise(
double p)
439 : NoiseBase({Gates::get_instance().Id2, Gates::get_instance().Y},
444 throw exception::OutOfRange(
445 "qpp::QubitBitPhaseFlipNoise::QubitBitPhaseFlipNoise()");
454 class QubitAmplitudeDampingNoise :
public NoiseBase<NoiseType::StateDependent> {
461 explicit QubitAmplitudeDampingNoise(
double gamma)
462 : NoiseBase(std::vector<cmat>{
463 ((cmat(2, 2)) << 1, 0, 0, std::sqrt(gamma)).finished(),
464 ((cmat(2, 2)) << 0, std::sqrt(1 - gamma), 0, 0).finished()}) {
467 if (gamma < 0 || gamma > 1)
468 throw exception::OutOfRange(
"qpp::QubitAmplitudeDampingNoise::" 469 "QubitAmplitudeDampingNoise()");
478 class QubitPhaseDampingNoise :
public NoiseBase<NoiseType::StateDependent> {
485 explicit QubitPhaseDampingNoise(
double lambda)
486 : NoiseBase(std::vector<cmat>{
487 ((cmat(2, 2)) << 1, 0, 0, std::sqrt(1 - lambda)).finished(),
488 ((cmat(2, 2)) << 0, 0, 0, std::sqrt(lambda)).finished()}) {
491 if (lambda < 0 || lambda > 1)
492 throw exception::OutOfRange(
"qpp::QubitPhaseDampingNoise::" 493 "QubitPhaseDampingNoise()");
504 class QuditDepolarizingNoise :
public NoiseBase<NoiseType::StateIndependent> {
511 std::vector<cmat> fill_Ks_(idx d)
const {
512 std::vector<cmat> Ks(d * d);
514 for (idx i = 0; i < d; ++i)
515 for (idx j = 0; j < d; ++j)
516 Ks[cnt++] = powm(Gates::get_instance().Xd(d), i) *
517 powm(Gates::get_instance().Zd(d), j);
529 std::vector<double> fill_probs_(
double p, idx d)
const {
530 std::vector<double> probs(d * d);
532 for (idx i = 1; i < d * d; ++i)
533 probs[i] = p / (d - 1) * (d - 1);
545 explicit QuditDepolarizingNoise(
double p, idx d)
546 : NoiseBase(fill_Ks_(d), fill_probs_(p, d)) {
549 if (d < 2 || p < 0 || p > 1)
550 throw exception::OutOfRange(
551 "qpp::QuditDepolarizingNoise::QuditDepolarizingNoise()");
Quantum++ main namespace.
Definition: circuits.h:35