|
52 | 52 | #include "qpp/classes/gates.hpp" |
53 | 53 | #include "qpp/internal/kernels/qubit/apply.hpp" |
54 | 54 | #include "qpp/internal/kernels/qubit/apply_ctrl.hpp" |
| 55 | +#include "qpp/internal/kernels/qubit/apply_ctrl_fan.hpp" |
55 | 56 | #include "qpp/internal/kernels/qubit/ptrace.hpp" |
56 | 57 | #include "qpp/internal/kernels/qubit/ptranspose.hpp" |
57 | 58 | #include "qpp/internal/kernels/qubit/syspermute.hpp" |
@@ -730,7 +731,8 @@ applyCTRL(const Eigen::MatrixBase<Derived1>& state, |
730 | 731 | if (elem >= d) { |
731 | 732 | throw exception::OutOfRange("qpp::applyCTRL()", "shift"); |
732 | 733 | } |
733 | | - elem = d - elem; |
| 734 | + // invert shift mod D |
| 735 | + elem = (d - elem) % d; |
734 | 736 | } |
735 | 737 | } |
736 | 738 | // END EXCEPTION CHECKS |
@@ -806,7 +808,7 @@ applyCTRL(const Eigen::MatrixBase<Derived1>& state, |
806 | 808 | D); |
807 | 809 | // project on complement |
808 | 810 | dyn_col_vect<typename Derived1::Scalar> chopped_psi_bar = |
809 | | - state / d - chopped_psi; |
| 811 | + (state / d) - chopped_psi; |
810 | 812 | // apply gates on target if non-zero |
811 | 813 | if (chopped_psi != |
812 | 814 | dyn_col_vect<typename Derived1::Scalar>::Zero(D)) { |
@@ -1084,14 +1086,42 @@ applyCTRL_fan(const Eigen::MatrixBase<Derived1>& state, |
1084 | 1086 | if (elem >= d) { |
1085 | 1087 | throw exception::OutOfRange("qpp::applyCTRL_fan()", "shift"); |
1086 | 1088 | } |
1087 | | - elem = d - elem; |
| 1089 | + // invert shift mod D |
| 1090 | + elem = (d - elem) % d; |
1088 | 1091 | } |
1089 | 1092 | } |
1090 | 1093 | // END EXCEPTION CHECKS |
1091 | 1094 | if (!shift.has_value()) { |
1092 | 1095 | shift = std::vector<idx>(ctrl.size(), 0); |
1093 | 1096 | } |
1094 | 1097 |
|
| 1098 | + // qubit optimizations |
| 1099 | +#ifdef QPP_QUBIT_OPTIMIZATIONS |
| 1100 | + if (internal::all_qubits(dims)) { |
| 1101 | + idx n = dims.size(); |
| 1102 | + // ket |
| 1103 | + if (internal::check_cvector(rstate)) { |
| 1104 | + // check that dims match state vector |
| 1105 | + if (!internal::check_dims_match_cvect(dims, rstate)) { |
| 1106 | + throw exception::DimsMismatchCvector("qpp::applyCTRL_fan()", |
| 1107 | + "dims/state"); |
| 1108 | + } |
| 1109 | + return internal::kernels::qubit::apply_ctrl_fan_psi( |
| 1110 | + state, A, ctrl, target, shift.value(), n); |
| 1111 | + |
| 1112 | + } |
| 1113 | + // density matrix |
| 1114 | + else { |
| 1115 | + // check that dims match density matrix |
| 1116 | + if (!internal::check_dims_match_mat(dims, rstate)) { |
| 1117 | + throw exception::DimsMismatchCvector("qpp::applyCTRL_fan()", |
| 1118 | + "dims/state"); |
| 1119 | + } |
| 1120 | + return internal::kernels::qubit::apply_ctrl_fan_rho( |
| 1121 | + state, A, ctrl, target, shift.value(), n); |
| 1122 | + } |
| 1123 | + } |
| 1124 | +#endif // QPP_QUBIT_OPTIMIZATIONS |
1095 | 1125 | // construct the table of A^k |
1096 | 1126 | std::vector<dyn_mat<typename Derived1::Scalar>> Ak; |
1097 | 1127 | for (idx k = 0; k < d; ++k) { |
@@ -1124,7 +1154,7 @@ applyCTRL_fan(const Eigen::MatrixBase<Derived1>& state, |
1124 | 1154 | D); |
1125 | 1155 | // project on complement |
1126 | 1156 | dyn_col_vect<typename Derived1::Scalar> chopped_psi_bar = |
1127 | | - state / d - chopped_psi; |
| 1157 | + (state / d) - chopped_psi; |
1128 | 1158 | // apply gates on target if non-zero |
1129 | 1159 | if (chopped_psi != |
1130 | 1160 | dyn_col_vect<typename Derived1::Scalar>::Zero(D)) { |
@@ -1198,7 +1228,7 @@ applyCTRL_fan(const Eigen::MatrixBase<Derived1>& state, |
1198 | 1228 | #pragma omp critical |
1199 | 1229 | #endif // QPP_OPENMP |
1200 | 1230 | { |
1201 | | - result += kron(psi_i, phi_i_bra); |
| 1231 | + result += psi_i * phi_i_bra; |
1202 | 1232 | } |
1203 | 1233 | } // end for(i) |
1204 | 1234 |
|
@@ -1300,7 +1330,7 @@ applyCTRL_fan(const Eigen::MatrixBase<Derived1>& state, |
1300 | 1330 | #pragma omp parallel for |
1301 | 1331 | #endif // QPP_OPENMP |
1302 | 1332 | for (idx a = 0; a < Din; ++a) { |
1303 | | - MES(a * Din + a, 0) = 1; |
| 1333 | + MES((a * Din) + a, 0) = 1; |
1304 | 1334 | } |
1305 | 1335 |
|
1306 | 1336 | cmat Omega = MES * adjoint(MES); |
@@ -1436,8 +1466,8 @@ inline std::vector<cmat> choi2kraus(const cmat& A) { |
1436 | 1466 | for (idx b = 0; b < Dout; ++b) { |
1437 | 1467 | for (idx m = 0; m < Din; ++m) { |
1438 | 1468 | for (idx n = 0; n < Din; ++n) { |
1439 | | - result(a * Dout + b, m * Din + n) = |
1440 | | - A(m * Dout + a, n * Dout + b); |
| 1469 | + result((a * Dout) + b, (m * Din) + n) = |
| 1470 | + A((m * Dout) + a, (n * Dout) + b); |
1441 | 1471 | } |
1442 | 1472 | } |
1443 | 1473 | } |
@@ -1510,8 +1540,8 @@ inline cmat choi2super(const cmat& A) { |
1510 | 1540 | for (idx b = 0; b < Dout; ++b) { |
1511 | 1541 | for (idx m = 0; m < Din; ++m) { |
1512 | 1542 | for (idx n = 0; n < Din; ++n) { |
1513 | | - result(m * Dout + a, n * Dout + b) = |
1514 | | - A(a * Dout + b, m * Din + n); |
| 1543 | + result((m * Dout) + a, (n * Dout) + b) = |
| 1544 | + A((a * Dout) + b, (m * Din) + n); |
1515 | 1545 | } |
1516 | 1546 | } |
1517 | 1547 | } |
@@ -1581,7 +1611,7 @@ inline cmat choi2super(const cmat& A) { |
1581 | 1611 | for (idx b = 0; b < Dout; ++b) { |
1582 | 1612 | // compute result(ab,mn)=<a|E(|m><n)|b> |
1583 | 1613 | B(b) = 1; |
1584 | | - result(a * Dout + b, m * Din + n) = |
| 1614 | + result((a * Dout) + b, (m * Din) + n) = |
1585 | 1615 | static_cast<cmat>(A * EMN * B).value(); |
1586 | 1616 | B(b) = 0; |
1587 | 1617 | } |
|
0 commit comments