32 : qbit_num_(qbit_num), fixed_error_rate_(error_rate), is_parametric_(false) {
34 throw std::invalid_argument(
"DepolarizingOp: qbit_num must be >= 1");
36 if (error_rate < 0.0 || error_rate > 1.0) {
37 throw std::invalid_argument(
"DepolarizingOp: error_rate must be in [0, 1]");
44 throw std::invalid_argument(
"DepolarizingOp: qbit_num must be >= 1");
52 if (param_count < 1 || params ==
nullptr) {
53 throw std::runtime_error(
54 "DepolarizingOp: parametric mode requires 1 parameter");
56 error_rate = params[0];
71 throw std::runtime_error(
72 "DepolarizingOp: qubit number mismatch with density matrix");
79 double trace_val = tr.
real;
82 double identity_factor = (p / dim) * trace_val;
84 for (
int i = 0; i < dim; i++) {
85 for (
int j = 0; j < dim; j++) {
90 element.
real = (1.0 - p) * element.
real + identity_factor;
91 element.
imag = (1.0 - p) * element.
imag;
94 element.
real *= (1.0 - p);
95 element.
imag *= (1.0 - p);
116 if (target_qbit < 0) {
117 throw std::invalid_argument(
118 "LocalDepolarizingOp: target_qbit must be >= 0");
120 if (error_rate < 0.0 || error_rate > 1.0) {
121 throw std::invalid_argument(
122 "LocalDepolarizingOp: error_rate must be in [0, 1]");
128 if (target_qbit < 0) {
129 throw std::invalid_argument(
130 "LocalDepolarizingOp: target_qbit must be >= 0");
138 if (param_count < 1 || params ==
nullptr) {
139 throw std::runtime_error(
140 "LocalDepolarizingOp: parametric mode requires 1 parameter");
142 error_rate = params[0];
143 if (error_rate < 0.0)
145 if (error_rate > 1.0)
158 throw std::runtime_error(
159 "LocalDepolarizingOp: target_qbit out of range for density matrix");
185 const double identity_weight = 1.0 - 0.75 * error_rate;
186 const double pauli_weight = 0.25 * error_rate;
188 for (
int i = 0; i < dim * dim; ++i) {
190 identity_weight * rho.
data[i].
real +
194 identity_weight * rho.
data[i].
imag +
202 return std::unique_ptr<LocalDepolarizingOp>(
205 return std::unique_ptr<LocalDepolarizingOp>(
216 if (target_qbit < 0) {
217 throw std::invalid_argument(
218 "AmplitudeDampingOp: target_qbit must be >= 0");
220 if (gamma < 0.0 || gamma > 1.0) {
221 throw std::invalid_argument(
"AmplitudeDampingOp: gamma must be in [0, 1]");
227 if (target_qbit < 0) {
228 throw std::invalid_argument(
229 "AmplitudeDampingOp: target_qbit must be >= 0");
237 if (param_count < 1 || params ==
nullptr) {
238 throw std::runtime_error(
239 "AmplitudeDampingOp: parametric mode requires 1 parameter");
260 throw std::runtime_error(
261 "AmplitudeDampingOp: target_qbit out of range for density matrix");
275 double sqrt_one_minus_gamma = std::sqrt(1.0 - gamma);
277 for (
int i = 0; i < dim; i++) {
278 for (
int j = 0; j < dim; j++) {
279 bool i_target = (i & target_step) != 0;
280 bool j_target = (j & target_step) != 0;
283 if (i_target == j_target) {
284 double factor = i_target ? (1.0 - gamma) : 1.0;
285 rho_new(i, j).real += factor * rho(i, j).real;
286 rho_new(i, j).imag += factor * rho(i, j).imag;
289 double factor = sqrt_one_minus_gamma;
290 rho_new(i, j).real += factor * rho(i, j).real;
291 rho_new(i, j).imag += factor * rho(i, j).imag;
295 if (!i_target && !j_target) {
296 int i_flip = i | target_step;
297 int j_flip = j | target_step;
298 rho_new(i, j).real += gamma * rho(i_flip, j_flip).real;
299 rho_new(i, j).imag += gamma * rho(i_flip, j_flip).imag;
322 if (target_qbit < 0) {
323 throw std::invalid_argument(
"PhaseDampingOp: target_qbit must be >= 0");
325 if (lambda < 0.0 || lambda > 1.0) {
326 throw std::invalid_argument(
"PhaseDampingOp: lambda must be in [0, 1]");
332 if (target_qbit < 0) {
333 throw std::invalid_argument(
"PhaseDampingOp: target_qbit must be >= 0");
341 if (param_count < 1 || params ==
nullptr) {
342 throw std::runtime_error(
343 "PhaseDampingOp: parametric mode requires 1 parameter");
363 throw std::runtime_error(
364 "PhaseDampingOp: target_qbit out of range for density matrix");
371 double sqrt_one_minus_lambda = std::sqrt(1.0 - lambda);
373 for (
int i = 0; i < dim; i++) {
374 for (
int j = 0; j < dim; j++) {
375 bool i_target = (i & target_step) != 0;
376 bool j_target = (j & target_step) != 0;
379 if (i_target != j_target) {
380 rho(i, j).real *= sqrt_one_minus_lambda;
381 rho(i, j).imag *= sqrt_one_minus_lambda;
std::unique_ptr< IDensityOperation > clone() const override
Create a deep copy of this operation.
std::unique_ptr< IDensityOperation > clone() const override
Create a deep copy of this operation.
void apply_amplitude_damping(DensityMatrix &rho, double gamma)
DepolarizingOp(int qbit_num, double error_rate)
Create depolarizing noise with fixed error rate.
scalar * data
pointer to the stored data
AmplitudeDampingOp(int target_qbit, double gamma)
Create amplitude damping with fixed gamma.
void apply_phase_damping(DensityMatrix &rho, double lambda)
void apply_to_density(const double *params, int param_count, DensityMatrix &rho) override
Apply this operation to the density matrix.
scalar * get_data() const
Call to get the pointer to the stored data.
void apply_to_density(const double *params, int param_count, DensityMatrix &rho) override
Apply this operation to the density matrix.
DensityMatrix clone() const
Create deep copy.
void apply_local_depolarizing(DensityMatrix &rho, double error_rate)
PhaseDampingOp(int target_qbit, double lambda)
Create phase damping with fixed lambda.
std::unique_ptr< IDensityOperation > clone() const override
Create a deep copy of this operation.
Header file of complex array storage array with automatic and thread safe reference counting...
Quantum density matrix Ï for mixed-state representation.
QGD_Complex16 trace() const
Calculate trace: Tr(Ï)
Structure type representing complex numbers in the SQUANDER package.
int get_qbit_num() const
Get number of qubits.
Double-precision complex matrix (float64).
void apply_to_density(const double *params, int param_count, DensityMatrix &rho) override
Apply this operation to the density matrix.
int get_dim() const
Get matrix dimension (2^qbit_num)
std::unique_ptr< IDensityOperation > clone() const override
Create a deep copy of this operation.
double real
the real part of a complex number
void apply_to_density(const double *params, int param_count, DensityMatrix &rho) override
Apply this operation to the density matrix.
LocalDepolarizingOp(int target_qbit, double error_rate)
void apply_depolarizing(DensityMatrix &rho, double error_rate)
void apply_single_qubit_unitary(const matrix_base< QGD_Complex16 > &u_2x2, int target_qbit)
Apply single-qubit unitary using local kernel (optimized)
double imag
the imaginary part of a complex number