32 #ifndef CLASSES_CIRCUITS_H_ 33 #define CLASSES_CIRCUITS_H_ 49 std::unordered_map<std::size_t, cmat>
51 std::unordered_map<std::string, idx>
54 std::unordered_map<std::string, idx>
56 std::unordered_map<std::string, idx>
75 if (!equal_eigen(search->second, U))
77 "Matrix hash collision");
175 os <<
"SINGLE_CTRL_SINGLE_TARGET";
178 os <<
"SINGLE_CTRL_MULTIPLE_TARGET";
181 os <<
"MULTIPLE_CTRL_SINGLE_TARGET";
184 os <<
"MULTIPLE_CTRL_MULTIPLE_TARGET";
190 os <<
"SINGLE_cCTRL_SINGLE_TARGET";
193 os <<
"SINGLE_cCTRL_MULTIPLE_TARGET";
196 os <<
"MULTIPLE_cCTRL_SINGLE_TARGET";
199 os <<
"MULTIPLE_cCTRL_MULTIPLE_TARGET";
202 os <<
"CUSTOM_cCTRL";
233 const std::vector<idx>& ctrl,
234 const std::vector<idx>& target, std::string name =
"")
251 os <<
"ctrl = " <<
disp(gate_step.
ctrl_,
", ") <<
", ";
252 os <<
"target = " <<
disp(gate_step.
target_,
", ") <<
", ";
253 os <<
"name = " <<
'\"' << gate_step.
name_ <<
'\"';
285 switch (measure_type) {
287 os <<
"MEASURE NONE";
296 os <<
"MEASURE_V_MANY";
329 const std::vector<std::size_t>& mats_hash,
330 const std::vector<idx>& target,
idx c_reg,
331 std::string name =
"")
346 os <<
"target = " <<
disp(measure_step.
target_,
", ") <<
", ";
347 os <<
"c_reg = " << measure_step.
c_reg_ <<
", ";
348 os <<
"name = " <<
'\"' << measure_step.
name_ <<
'\"';
411 std::vector<GateStep>::const_iterator
413 std::vector<MeasureStep>::const_iterator
448 std::ostream&
display(std::ostream& os)
const override {
456 os << std::setw(text_width) <<
ip_;
465 os << std::setw(text_width) <<
ip_;
511 if (
qc_ ==
nullptr) {
513 "qpp::QCircuit::iterator::operator++()");
519 "qpp::QCircuit::iterator::operator++()");
525 "qpp::QCircuit::iterator::operator++()");
600 "qpp::QCircuit::iterator::operator*()");
615 if (
qc_ !=
nullptr) {
635 if (
qc_ !=
nullptr) {
742 throw exception::ZeroSize(
"qpp::QCircuit::QCircuit()");
744 throw exception::OutOfRange(
"qpp::QCircuit::QCircuit()");
803 std::vector<idx> result;
804 for (
idx i = 0; i <
nq_; ++i)
806 result.emplace_back(i);
817 std::vector<idx> result;
818 for (
idx i = 0; i <
nq_; ++i)
820 result.emplace_back(i);
832 for (
auto&& elem :
count_)
833 result += elem.second;
851 std::cerr <<
"In qpp::QCircuit::get_gate_count()\n";
886 result += elem.second;
904 std::cerr <<
"In qpp::QCircuit::get_measurement_count()\n";
944 if (static_cast<idx>(U.rows()) !=
d_)
957 std::vector<idx>{i}, name);
978 if (i >=
nq_ || j >=
nq_ || i == j)
987 if (static_cast<idx>(U.rows()) !=
d_ *
d_)
1000 std::vector<idx>{i, j}, name);
1022 if (i >=
nq_ || j >=
nq_ || k >=
nq_ || (i == j) || (i == k) ||
1032 if (static_cast<idx>(U.rows()) !=
d_ *
d_ *
d_)
1045 std::vector<idx>{i, j, k}, name);
1063 std::string name =
"") {
1068 if (target.size() == 0)
1070 for (
auto&& elem : target) {
1076 "qpp::QCircuit::gate_fan()");
1086 if (static_cast<idx>(U.rows()) !=
d_)
1088 "qpp::QCircuit::gate_fan()");
1102 count_[name] += target.size();
1121 std::string name =
"") {
1122 return gate_fan(U, std::vector<idx>(target), name);
1141 if (static_cast<idx>(U.rows()) !=
d_)
1143 "qpp::QCircuit::gate_fan()");
1173 std::string name =
"") {
1176 idx n =
static_cast<idx>(target.size());
1177 idx D =
static_cast<idx>(std::llround(std::pow(
d_, n)));
1181 if (target.size() == 0)
1183 for (
auto&& elem : target) {
1189 "qpp::QCircuit::gate_custom()");
1198 "qpp::QCircuit::gate_custom()");
1200 if (static_cast<idx>(U.rows()) != D)
1202 "qpp::QCircuit::gate_custom()");
1232 bool swap QPP_UNUSED_ =
true) {
1261 bool swap QPP_UNUSED_ =
true) {
1294 if (ctrl >=
nq_ || target >=
nq_ || ctrl == target)
1303 if (static_cast<idx>(U.rows()) !=
d_)
1313 name = gate_name ==
"" ?
"CTRL" :
"CTRL-" + gate_name;
1318 std::vector<idx>{ctrl}, std::vector<idx>{target},
1339 std::string name =
"") {
1350 if (target.size() == 0)
1352 for (
auto&& elem : target) {
1358 "qpp::QCircuit::CTRL()");
1365 for (
auto&& elem : target)
1373 if (static_cast<idx>(U.rows()) !=
d_)
1383 name = gate_name ==
"" ?
"CTRL" :
"CTRL-" + gate_name;
1388 std::vector<idx>{ctrl}, target, name);
1407 std::string name =
"") {
1412 for (
auto&& elem : ctrl) {
1418 "qpp::QCircuit::CTRL()");
1431 for (
auto&& elem : ctrl)
1439 if (static_cast<idx>(U.rows()) !=
d_)
1449 name = gate_name ==
"" ?
"CTRL" :
"CTRL-" + gate_name;
1454 std::vector<idx>{target}, name);
1475 const std::vector<idx>& target, std::string name =
"") {
1480 for (
auto&& elem : ctrl) {
1486 "qpp::QCircuit::CTRL()");
1493 if (target.size() == 0)
1495 for (
auto&& elem : target) {
1501 "qpp::QCircuit::CTRL()");
1508 for (
auto&& elem_ctrl : ctrl)
1509 for (
auto&& elem_target : target)
1510 if (elem_ctrl == elem_target)
1517 if (static_cast<idx>(U.rows()) !=
d_)
1527 name = gate_name ==
"" ?
"CTRL" :
"CTRL-" + gate_name;
1532 ctrl, std::vector<idx>{target}, name);
1553 const std::vector<idx>& target,
1554 std::string name =
"") {
1557 idx n =
static_cast<idx>(target.size());
1558 idx D =
static_cast<idx>(std::llround(std::pow(
d_, n)));
1562 for (
auto&& elem : ctrl) {
1568 "qpp::QCircuit::CTRL_custom()");
1575 if (target.size() == 0)
1577 for (
auto&& elem : target) {
1583 "qpp::QCircuit::CTRL_custom()");
1587 for (
auto&& elem_ctrl : ctrl)
1588 for (
auto&& elem_target : target)
1589 if (elem_ctrl == elem_target)
1591 "qpp::QCircuit::CTRL_custom()");
1596 "qpp::QCircuit::CTRL_custom()");
1598 if (static_cast<idx>(U.rows()) != D)
1600 "qpp::QCircuit::CTRL_custom()");
1609 name = gate_name ==
"" ?
"CTRL" :
"CTRL-" + gate_name;
1633 std::string name =
"") {
1638 if (ctrl_dit >=
nc_ || target >=
nq_)
1647 if (static_cast<idx>(U.rows()) !=
d_)
1657 name = gate_name ==
"" ?
"cCTRL" :
"cCTRL-" + gate_name;
1662 std::vector<idx>{ctrl_dit},
1663 std::vector<idx>{target}, name);
1683 std::string name =
"") {
1688 if (ctrl_dit >=
nc_)
1692 if (target.size() == 0)
1694 for (
auto&& elem : target) {
1700 "qpp::QCircuit::cCTRL()");
1710 if (static_cast<idx>(U.rows()) !=
d_)
1720 name = gate_name ==
"" ?
"cCTRL" :
"cCTRL-" + gate_name;
1725 std::vector<idx>{ctrl_dit}, target, name);
1744 idx target, std::string name =
"") {
1749 for (
auto&& elem : ctrl_dits) {
1768 if (static_cast<idx>(U.rows()) !=
d_)
1778 name = gate_name ==
"" ?
"cCTRL" :
"cCTRL-" + gate_name;
1783 ctrl_dits, std::vector<idx>{target}, name);
1804 const std::vector<idx>& target, std::string name =
"") {
1809 for (
auto&& elem : ctrl_dits) {
1818 if (target.size() == 0)
1820 for (
auto&& elem : target) {
1826 "qpp::QCircuit::cCTRL()");
1836 if (static_cast<idx>(U.rows()) !=
d_)
1846 name = gate_name ==
"" ?
"cCTRL" :
"cCTRL-" + gate_name;
1851 ctrl_dits, std::vector<idx>{target}, name);
1872 const std::vector<idx>& target,
1873 std::string name =
"") {
1876 idx n =
static_cast<idx>(target.size());
1877 idx D =
static_cast<idx>(std::llround(std::pow(
d_, n)));
1881 for (
auto&& elem : ctrl_dits) {
1884 "qpp::QCircuit::cCTRL_custom()");
1891 if (target.size() == 0)
1893 for (
auto&& elem : target) {
1896 "qpp::QCircuit::cCTRL_custom()");
1900 "qpp::QCircuit::cCTRL_custom()");
1909 "qpp::QCircuit::cCTRL_custom()");
1911 if (static_cast<idx>(U.rows()) != D)
1913 "qpp::QCircuit::cCTRL_custom()");
1922 name = gate_name ==
"" ?
"cCTRL" :
"cCTRL-" + gate_name;
1967 std::vector<std::size_t>{},
1968 std::vector<idx>{target}, c_reg, name);
1990 std::string name =
"") {
2014 std::vector<idx>{target}, c_reg, name);
2036 std::string name =
"") {
2041 if (target.size() == 0)
2043 for (
auto&& elem : target) {
2049 "qpp::QCircuit::measureV()");
2059 for (
auto&& elem : target)
2062 "qpp::QCircuit::measureV");
2071 for (
auto&& elem : target)
2075 target, c_reg, name);
2091 std::string
to_JSON(
bool enclosed_in_curly_brackets =
true)
const override {
2094 if (enclosed_in_curly_brackets)
2097 result +=
"\"nq\" : " + std::to_string(
nq_);
2098 result +=
", \"nc\" : " + std::to_string(
nc_);
2099 result +=
", \"d\" : " + std::to_string(
d_);
2100 result +=
", \"name\" : \"" +
name_ +
"\"";
2102 bool is_first =
true;
2103 std::ostringstream ss;
2104 result +=
", \"steps\" : [";
2105 for (
auto&& elem : *
this) {
2111 result +=
"{\"step\" : " + std::to_string(elem.ip_) +
", ";
2112 result +=
"\"type\" : ";
2115 idx pos = std::distance(std::begin(elem.value_type_qc_->gates_),
2119 ss <<
gates_[pos].gate_type_;
2120 result +=
"\"" + ss.str() +
"\", ";
2121 if (
gates_[pos].ctrl_.size() != 0) {
2125 result +=
"\"ctrl\" : " + ss.str() +
", ";
2130 result +=
"\"target\" : " + ss.str() +
", ";
2131 result +=
"\"name\" : ";
2132 result +=
"\"" +
gates_[pos].name_ +
"\"" +
"}";
2136 idx pos = std::distance(
2137 std::begin(elem.value_type_qc_->measurements_),
2138 elem.measurements_ip_);
2142 result +=
"\"" + ss.str() +
"\", ";
2146 result +=
"\"target\" : " + ss.str() +
", ";
2148 "\"c_reg\" : " + std::to_string(
measurements_[pos].c_reg_) +
2150 result +=
"\"name\" : ";
2161 result +=
"\"gate count\" : " + std::to_string(
get_gate_count()) +
", ";
2166 result +=
"\"measured positions\" : " + ss.str() +
", ";
2171 result +=
"\"non-measured positions\" : " + ss.str();
2173 if (enclosed_in_curly_brackets)
2188 std::ostream&
display(std::ostream& os)
const override {
2189 os <<
"nq = " <<
nq_ <<
", nc = " <<
nc_ <<
", d = " <<
d_;
2192 os <<
", name = \"" <<
name_ <<
"\"\n";
2194 os <<
", name = \"\"\n";
2196 for (
auto&& elem : *
this) {
2230 "qpp::QEngine::set_measured_()");
2248 idx vsize = v.size();
2249 for (
idx i = 0; i < vsize; ++i) {
2252 "qpp::QEngine::get_relative_pos_()");
2272 qc.get_nq(), qc.get_d())},
2366 std::vector<idx> result;
2369 result.emplace_back(i);
2380 std::vector<idx> result;
2383 result.emplace_back(i);
2449 std::vector<idx> ctrl_rel_pos;
2450 std::vector<idx> target_rel_pos =
2453 switch (gates[q_ip].gate_type_) {
2464 for (
idx m = 0; m < gates[q_ip].target_.size(); ++m)
2466 {target_rel_pos[m]},
qc_->
get_d());
2477 ctrl_rel_pos, target_rel_pos,
qc_->
get_d());
2484 if (
dits_.size() == 0) {
2488 bool should_apply =
true;
2489 idx first_dit =
dits_[(gates[q_ip].ctrl_)[0]];
2490 for (
idx m = 0; m < gates[q_ip].ctrl_.size(); ++m) {
2491 if (
dits_[(gates[q_ip].ctrl_)[m]] != first_dit) {
2492 should_apply =
false;
2499 powm(h_tbl[gates[q_ip].gate_hash_], first_dit),
2512 std::vector<idx> target_rel_pos =
2515 std::vector<idx> resZ;
2519 std::vector<double> probs;
2520 std::vector<cmat> states;
2522 switch (measurements[m_ip].measurement_type_) {
2526 std::tie(resZ, probZ,
psi_) =
2528 dits_[measurements[m_ip].c_reg_] = resZ[0];
2529 probs_[measurements[m_ip].c_reg_] = probZ;
2533 std::tie(mres, probs, states) =
2534 measure(
psi_, h_tbl[measurements[m_ip].mats_hash_[0]],
2536 psi_ = states[mres];
2537 dits_[measurements[m_ip].c_reg_] = mres;
2538 probs_[measurements[m_ip].c_reg_] = probs[mres];
2542 std::tie(mres, probs, states) =
2543 measure(
psi_, h_tbl[measurements[m_ip].mats_hash_[0]],
2545 psi_ = states[mres];
2546 dits_[measurements[m_ip].c_reg_] = mres;
2547 probs_[measurements[m_ip].c_reg_] = probs[mres];
2548 for (
auto&& elem : measurements[m_ip].target_)
2575 std::string
to_JSON(
bool enclosed_in_curly_brackets =
true)
const override {
2578 if (enclosed_in_curly_brackets)
2581 std::ostringstream ss;
2583 result +=
"\"measured\" : ";
2589 result +=
", \"dits\" : ";
2595 result +=
", \"probs\" : ";
2599 if (enclosed_in_curly_brackets)
2615 std::ostream&
display(std::ostream& os)
const override {
std::vector< GateStep > gates_
gates
Definition: circuits.h:364
virtual ~QEngine()=default
Default virtual destructor.
idx get_gate_depth(const std::string &name QPP_UNUSED_) const
Quantum circuit gate depth.
Definition: circuits.h:874
Dimension(s) mismatch matrix size exception.
Definition: exception.h:300
QCircuit & gate(const cmat &U, idx i, std::string name="")
Applies the single qudit gate U on single qudit i.
Definition: circuits.h:929
Invalid iterator.
Definition: exception.h:629
idx get_gate_count() const noexcept
Quantum circuit total gate count.
Definition: circuits.h:830
same unitary gate on multiple qudits
unitary gate on a single qudit
const QCircuit & get_circuit() const noexcept
Quantum circuit.
Definition: circuits.h:2393
QCircuit & measureV(const cmat &V, const std::vector< idx > &target, idx c_reg, std::string name="")
Joint measurement of multiple qudits in the orthonormal basis or rank-1 projectors specified by the c...
Definition: circuits.h:2035
ket get_psi() const
Underlying quantum state.
Definition: circuits.h:2308
ket zero(idx n, idx d=2) const
Zero state of n qudits.
Definition: states.h:121
std::vector< idx > get_dits() const
Vector with the values of the underlying classical dits.
Definition: circuits.h:2322
System (e.g. std::vector) has duplicates exception.
Definition: exception.h:585
QCircuit & CTRL(const cmat &U, idx ctrl, const std::vector< idx > &target, std::string name="")
Applies the single qudit controlled gate U with control qudit ctrl on every qudit listed in target...
Definition: circuits.h:1338
std::vector< idx > get_not_measured() const
Vector of non-measured qudit indexes.
Definition: circuits.h:2379
void set_end_(const QCircuit *qc)
Sets the iterator to std::begin(this)
Definition: circuits.h:631
MeasureType
Type of measurement being executed in a measurement step.
Definition: circuits.h:261
const_iterator cbegin() const noexcept
Constant iterator to the first element.
Definition: circuits.h:683
idx c_reg_
Definition: circuits.h:311
std::vector< idx > ctrl_
control
Definition: circuits.h:215
const QCircuit * qc_
pointer to constant quantum circuit
Definition: circuits.h:2215
QCircuit & TFQ(const std::vector< idx > &target, bool swap QPP_UNUSED_=true)
Applies the inverse quantum Fourier transform (as a series of gates) on the qudit indexes specified b...
Definition: circuits.h:1260
idx get_step_count() const noexcept
Quantum circuit total steps count, i.e. the sum of gate count and measurement count.
Definition: circuits.h:918
QEngine & operator=(const QEngine &)=default
Default copy assignment operator.
Custom exception.
Definition: exception.h:600
Qudit was already measured exception.
Definition: exception.h:571
std::vector< MeasureStep > measurements_
measurements
Definition: circuits.h:365
quantum inverse Fourier transform,
std::size_t gate_hash_
gate hash
Definition: circuits.h:214
std::string get_name() const
Quantum circuit name.
Definition: circuits.h:780
custom gate on multiple qudits
bool get_measured(idx i) const
Check whether qudit i was already measured.
Definition: circuits.h:2356
QCircuit & gate(const cmat &U, idx i, idx j, std::string name="")
Applies the two qudit gate U on qudits i and j.
Definition: circuits.h:973
std::vector< std::size_t > mats_hash_
Definition: circuits.h:308
friend std::ostream & operator<<(std::ostream &os, const MeasureType &measure_type)
Extraction operator overload for qpp::QCircuit::MeasureType enum class.
Definition: circuits.h:283
Definition: circuits.h:404
value_type_ elem_
Definition: circuits.h:480
idx ip_
instruction pointer
Definition: circuits.h:410
QCircuit & cCTRL(const cmat &U, const std::vector< idx > &ctrl_dits, const std::vector< idx > &target, std::string name="")
Applies the single qudit controlled gate U with multiple classical control dits listed in ctrl on eve...
Definition: circuits.h:1803
bool check_no_duplicates(std::vector< idx > v)
Definition: util.h:210
std::unordered_map< std::string, idx > measurement_count_
keeps track of the measurement counts
Definition: circuits.h:57
Eigen::VectorXcd ket
Complex (double precision) dynamic Eigen column vector.
Definition: types.h:54
std::vector< idx > subsys_
Definition: circuits.h:2219
std::vector< idx > target_
target where the gate is applied
Definition: circuits.h:216
GateStep()=default
Default constructor.
idx get_dit(idx i) const
Value of the classical dit at position i.
Definition: circuits.h:2331
const std::unordered_map< std::size_t, cmat > & get_cmat_hash_tbl_() const noexcept
Hash table with the matrices used in the circuit.
Definition: circuits.h:389
Quantum++ main namespace.
Definition: circuits.h:35
friend std::ostream & operator<<(std::ostream &os, const MeasureStep &measure_step)
Extraction operator overload for qpp::QCircuit::MeasureStep class.
Definition: circuits.h:343
const QCircuit * qc_
< non-owning pointer to const quantum circuit
Definition: circuits.h:402
const idx d_
qudit dimension
Definition: circuits.h:45
Code not yet implemented.
Definition: exception.h:616
StepType
Types of each step in the quantum circuit.
Definition: circuits.h:357
QCircuit & CTRL_custom(const cmat &U, const std::vector< idx > &ctrl, const std::vector< idx > &target, std::string name="")
Jointly applies the custom multiple-qudit controlled gate U with multiple control qudits listed in ct...
Definition: circuits.h:1552
const_iterator begin() const noexcept
Constant iterator to the first element.
Definition: circuits.h:671
std::vector< idx > get_measured() const
Vector of already measured qudit indexes.
Definition: circuits.h:2365
std::ostream & display(std::ostream &os) const override
qpp::IDisplay::display() override
Definition: circuits.h:2188
idx get_gate_count(const std::string &name) const
Quantum circuit gate count.
Definition: circuits.h:844
const value_type_ & operator*() const
Safe de-referencing operator.
Definition: circuits.h:593
QCircuit & gate(const cmat &U, idx i, idx j, idx k, std::string name="")
Applies the three qudit gate U on qudits i, j and k.
Definition: circuits.h:1017
Abstract class (interface) that mandates the definition of very basic JSON serialization support...
Definition: idisplay.h:106
idx get_measurement_count() const noexcept
Quantum circuit total measurement count.
Definition: circuits.h:883
iterator operator++(int)
Postfix increment operator.
Definition: circuits.h:560
std::string name_
optional circuit name
Definition: circuits.h:46
bool operator!=(iterator rhs) const
Inequality operator.
Definition: circuits.h:586
void set_measured_(idx i)
Marks qudit i as measured then re-label accordingly the remaining non-measured qudits.
Definition: circuits.h:2227
One step consisting only of measurements in the circuit.
Definition: circuits.h:306
QCircuit & measureV(const cmat &V, idx target, idx c_reg, std::string name="")
Measurement of single qudit in the orthonormal basis or rank-1 projectors specified by the columns of...
Definition: circuits.h:1989
iterator begin()
Iterator to the first element.
Definition: circuits.h:659
QCircuit & cCTRL(const cmat &U, idx ctrl_dit, idx target, std::string name="")
Applies the single qubit controlled gate U with classical control dit ctrl and target qudit target...
Definition: circuits.h:1632
dyn_mat< typename Derived1::Scalar > apply(const Eigen::MatrixBase< Derived1 > &state, const Eigen::MatrixBase< Derived2 > &A, const std::vector< idx > &target, const std::vector< idx > &dims)
Applies the gate A to the part target of the multi-partite state vector or density matrix state...
Definition: operations.h:444
QCircuit & cCTRL(const cmat &U, const std::vector< idx > &ctrl_dits, idx target, std::string name="")
Applies the single qudit controlled gate U with multiple classical control dits listed in ctrl on the...
Definition: circuits.h:1743
StepType type_
step type
Definition: circuits.h:409
std::vector< GateStep >::const_iterator gates_ip_
gates instruction pointer
Definition: circuits.h:412
Quantum circuit engine, executes qpp::QCircuit.
Definition: circuits.h:2213
value_type_(const QCircuit *value_type_qc)
Default value_type_ constructor.
Definition: circuits.h:421
dyn_mat< typename Derived1::Scalar > applyCTRL(const Eigen::MatrixBase< Derived1 > &state, const Eigen::MatrixBase< Derived2 > &A, const std::vector< idx > &ctrl, const std::vector< idx > &target, const std::vector< idx > &dims)
Applies the controlled-gate A to the part target of the multi-partite state vector or density matrix ...
Definition: operations.h:55
std::string to_JSON(bool enclosed_in_curly_brackets=true) const override
qpp::IJOSN::to_JSON() override
Definition: circuits.h:2575
QCircuit & gate_fan(const cmat &U, const std::vector< idx > &target, std::string name="")
Applies the single qudit gate U on every qudit listed in target.
Definition: circuits.h:1062
value_type_ & operator=(const value_type_ &)=default
Default copy assignment operator.
std::unordered_map< std::string, idx > count_
keeps track of the gate counts
Definition: circuits.h:53
Functor for comparing Eigen expressions for equality.
Definition: functions.h:2013
QCircuit & gate_fan(const cmat &U, std::string name="")
Applies the single qudit gate U on every remaining non-measured qudit.
Definition: circuits.h:1133
std::tuple< idx, std::vector< double >, std::vector< cmat > > measure(const Eigen::MatrixBase< Derived > &A, const std::vector< cmat > &Ks)
Measures the state vector or density operator A using the set of Kraus operators Ks.
Definition: instruments.h:206
MeasureStep(MeasureType measurement_type, const std::vector< std::size_t > &mats_hash, const std::vector< idx > &target, idx c_reg, std::string name="")
Constructs a measurement step instance.
Definition: circuits.h:328
void set_begin_(const QCircuit *qc)
Sets the iterator to std::begin(this)
Definition: circuits.h:611
void execute(const QCircuit::iterator::value_type &elem)
Executes one step in the quantum circuit.
Definition: circuits.h:2431
quantum Fourier transform,
Abstract class (interface) that mandates the definition of virtual std::ostream& display(std::ostream...
Definition: idisplay.h:47
const std::vector< MeasureStep > & get_measurements_() const noexcept
Vector of qpp::QCircuit::MeasureStep.
Definition: circuits.h:373
std::size_t hash_eigen(const Eigen::MatrixBase< Derived > &A, std::size_t seed=0)
Computes the hash of en Eigen matrix/vector/expression.
Definition: functions.h:1973
std::unordered_map< std::string, idx > depth_
keeps track of the gate depths
Definition: circuits.h:55
bool operator==(const iterator &rhs) const
Equality operator.
Definition: circuits.h:572
idx get_nc() const noexcept
Total number of classical dits in the circuit.
Definition: circuits.h:766
Quantum circuit bound-checking (safe) iterator.
Definition: circuits.h:400
std::string to_JSON(bool enclosed_in_curly_brackets=true) const override
qpp::IJOSN::to_JSON() override
Definition: circuits.h:2091
std::vector< idx > target_
target where the measurement is applied
Definition: circuits.h:310
iterator & operator=(const iterator &)=default
Default copy assignment operator.
idx get_measured(idx i) const
Check whether qudit i was already measured.
Definition: circuits.h:787
virtual ~QCircuit()=default
Default virtual destructor.
QCircuit & cCTRL_custom(const cmat &U, const std::vector< idx > &ctrl_dits, const std::vector< idx > &target, std::string name="")
Jointly applies the custom multiple-qudit controlled gate U with multiple classical control dits list...
Definition: circuits.h:1871
std::vector< idx > get_non_measured() const
Vector of non-measured qudit indexes.
Definition: circuits.h:816
Quantum circuit class.
Definition: circuits.h:41
iterator end()
Iterator to the next to the last element.
Definition: circuits.h:695
idx get_measurement_count(const std::string &name) const
Quantum circuit measurement count.
Definition: circuits.h:897
void execute(const QCircuit::iterator &it)
Executes one step in the quantum circuit.
Definition: circuits.h:2563
const std::vector< GateStep > & get_gates_() const noexcept
Vector of qpp::QCircuit::GateStep.
Definition: circuits.h:382
dyn_mat< typename Derived::Scalar > powm(const Eigen::MatrixBase< Derived > &A, idx n)
Fast matrix power based on the SQUARE-AND-MULTIPLY algorithm.
Definition: functions.h:800
ket psi_
state vector
Definition: circuits.h:2216
void reset()
Resets the engine.
Definition: circuits.h:2419
std::unordered_map< std::size_t, cmat > cmat_hash_tbl_
Definition: circuits.h:50
const_iterator cend() const noexcept
Constant iterator to the next to the last element.
Definition: circuits.h:719
MeasureType measurement_type_
measurement type
Definition: circuits.h:307
GateType gate_type_
gate type
Definition: circuits.h:213
QCircuit & CTRL(const cmat &U, const std::vector< idx > &ctrl, idx target, std::string name="")
Applies the single qudit controlled gate U with multiple control qudits listed in ctrl on the target ...
Definition: circuits.h:1406
QCircuit & QFT(const std::vector< idx > &target, bool swap QPP_UNUSED_=true)
Applies the quantum Fourier transform (as a series of gates) on the qudit indexes specified by target...
Definition: circuits.h:1231
bool check_square_mat(const Eigen::MatrixBase< Derived > &A)
Definition: util.h:99
Z measurement of single qudit.
QEngine & set_dit(idx i, idx value)
Sets the classical dit at position i.
Definition: circuits.h:2404
const_iterator end() const noexcept
Constant iterator to the next to the last element.
Definition: circuits.h:707
std::string get_name(const cmat &U) const
Get the name of the most common qubit gates.
Definition: gates.h:663
iterator()=default
Default constructor.
std::ostream & display(std::ostream &os) const override
qpp::IDisplay::display() override
Definition: circuits.h:448
QEngine(const QCircuit &qc)
Constructs a quantum engine out of a quantum circuit.
Definition: circuits.h:2270
iterator & operator++()
Prefix increment operator.
Definition: circuits.h:507
idx get_gate_depth() const
Quantum circuit total gate depth.
Definition: circuits.h:864
GateStep(GateType gate_type, std::size_t gate_hash, const std::vector< idx > &ctrl, const std::vector< idx > &target, std::string name="")
Constructs a gate step instance.
Definition: circuits.h:232
std::vector< idx > dits_
classical dits
Definition: circuits.h:2217
Argument out of range exception.
Definition: exception.h:515
QCircuit & gate_fan(const cmat &U, const std::initializer_list< idx > &target, std::string name="")
Applies the single qudit gate U on every qudit listed in target.
Definition: circuits.h:1120
GateType
Type of gate being executed in a gate step.
Definition: circuits.h:87
void add_hash_(const cmat &U, std::size_t hashU)
Adds matrix to the hash table.
Definition: circuits.h:67
static const Gates & get_instance() noexcept(std::is_nothrow_constructible< const Gates >::value)
Definition: singleton.h:92
std::ostream & display(std::ostream &os) const override
qpp::IDisplay::display() override
Definition: circuits.h:2615
std::string name_
custom name of the step
Definition: circuits.h:313
std::vector< double > probs_
measurement probabilities
Definition: circuits.h:2218
std::forward_iterator_tag iterator_category
iterator trait
Definition: circuits.h:649
Eigen::MatrixXcd cmat
Complex (double precision) dynamic Eigen matrix.
Definition: types.h:64
const idx nq_
number of qudits
Definition: circuits.h:43
std::tuple< std::vector< idx >, double, cmat > measure_seq(const Eigen::MatrixBase< Derived > &A, std::vector< idx > target, std::vector< idx > dims)
Sequentially measures the part target of the multi-partite state vector or density matrix A in the co...
Definition: instruments.h:697
QCircuit & CTRL(const cmat &U, const std::vector< idx > &ctrl, const std::vector< idx > &target, std::string name="")
Applies the single qudit controlled gate U with multiple control qudits listed in ctrl on every qudit...
Definition: circuits.h:1474
const idx nc_
number of classical "dits"
Definition: circuits.h:44
std::vector< double > get_probs() const
Vector of underlying measurement outcome probabilities.
Definition: circuits.h:2348
friend std::ostream & operator<<(std::ostream &os, const GateType &gate_type)
Extraction operator overload for qpp::QCircuit::GateType enum class.
Definition: circuits.h:147
One step consisting only of gates/operators in the circuit.
Definition: circuits.h:212
represents no measurement
std::vector< idx > get_relative_pos_(std::vector< idx > v)
Giving a vector V of non-measured qudits, get their relative position with respect to the measured qu...
Definition: circuits.h:2247
idx get_nq() const noexcept
Total number of qudits in the circuit.
Definition: circuits.h:759
std::size_t idx
Non-negative integer index, make sure you use an unsigned type.
Definition: types.h:39
std::vector< MeasureStep >::const_iterator measurements_ip_
measurements instruction pointer
Definition: circuits.h:414
idx get_d() const noexcept
Dimension of the comprising qudits.
Definition: circuits.h:773
Matrix is not square exception.
Definition: exception.h:149
friend std::ostream & operator<<(std::ostream &os, const GateStep &gate_step)
Extraction operator overload for qpp::QCircuit::GateStep class.
Definition: circuits.h:247
ket & get_ref_psi()
Reference to the underlying quantum state.
Definition: circuits.h:2315
QCircuit & CTRL(const cmat &U, idx ctrl, idx target, std::string name="")
Applies the single qudit controlled gate U with control qudit ctrl and target qudit target...
Definition: circuits.h:1289
QCircuit & cCTRL(const cmat &U, idx ctrl_dit, const std::vector< idx > &target, std::string name="")
Applies the single qudit controlled gate U with classical control dit ctrl on every qudit listed in t...
Definition: circuits.h:1682
std::vector< idx > get_measured() const
Vector of already measured qudit indexes.
Definition: circuits.h:802
QCircuit & gate_custom(const cmat &U, const std::vector< idx > &target, std::string name="")
Jointly applies the custom multiple qudit gate U on the qudit indexes specified by target...
Definition: circuits.h:1172
long long difference_type
iterator trait
Definition: circuits.h:645
MeasureStep()=default
Default constructor.
QCircuit(idx nq, idx nc=0, idx d=2, std::string name="")
Constructs a quantum circuit.
Definition: circuits.h:737
std::string name_
custom name of the step
Definition: circuits.h:217
std::vector< bool > measured_
keeps track of the measured qudits
Definition: circuits.h:47
QCircuit & measureZ(idx target, idx c_reg, std::string name="")
Measurement of single qudit in the computational basis (Z-basis)
Definition: circuits.h:1944
internal::IOManipEigen disp(const Eigen::MatrixBase< Derived > &A, double chop=qpp::chop)
Eigen expression ostream manipulator.
Definition: input_output.h:44
Base class for generating Quantum++ custom exceptions.
Definition: exception.h:71
const QCircuit * value_type_qc_
< non-owning pointer to the parent iterator
Definition: circuits.h:407
Object has zero size exception.
Definition: exception.h:134
std::vector< StepType > step_types_
type of each step
Definition: circuits.h:366