114 for(std::vector<Gate*>::iterator it =
gates.begin(); it !=
gates.end(); ++it) {
134 if ( idx>= (
int)
gates.size() )
return;
174 std::stringstream sstream;
179 apply_to(parameters, block_mtx, parallel);
182 if (block_mtx.
isnan()) {
183 std::stringstream sstream;
184 sstream <<
"Gates_block::get_matrix: block_mtx contains NaN." << std::endl;
205 if ( parallel == 0 ) {
206 work_batch = inputs.size();
213 tbb::parallel_for( tbb::blocked_range<int>(0,inputs.size(),work_batch), [&](tbb::blocked_range<int> r) {
214 for (
int idx=r.begin(); idx<r.end(); ++idx) {
216 Matrix* input = &inputs[idx];
218 apply_to( parameters_mtx, *input, parallel );
240 std::string err(
"Gates_block::apply_to: Wrong input size in Gates_block gate apply.");
248 std::string error(
"Gates_block::apply_to: GATE fusion has not been adopted to reversed parameter ordering!!!!!!!!!!!!!!!!!!!");
257 int outer_idx =
gates.size()-1;
258 for (
int block_idx=0; block_idx<
involved_qbits.size(); block_idx++){
265 int* indices = (
int*)_malloca(
qbit_num*
sizeof(
int));
270 for (
int jdx=0; jdx<(
int)qbits.size(); jdx++){
271 indices[qbits[jdx]]=jdx;
274 for (
int idx=outer_idx; idx>=
block_end[block_idx]; idx--){
279 int target_qubit_new = indices[trgt_qbit];
282 int control_qubit_new = (ctrl_qbit==-1) ? -1:indices[ctrl_qbit];
291 gates_block_mini.
apply_to(parameters_mtx, Umtx_mini);
298 apply_large_kernel_to_state_vector_input(Umtx_mini, input, qbits, input.
size() );
307 for (
int idx=outer_idx;idx>=0;idx--){
313 gates_block_mini.
apply_to(parameters_mtx, input);
317 else if ( involved_qubits.size() == 1 &&
gates.size() > 1 &&
qbit_num > 1 ) {
322 for (
int idx=0; idx<
gates.size(); idx++){
334 gates_block_mini.
apply_to(parameters_mtx_loc, Umtx_mini);
342 for(
int idx=0; idx<
gates.size(); idx++) {
349 operation->
apply_to(input, parallel);
352 operation->
apply_to( parameters_mtx_loc, input, parallel );
356 std::stringstream sstream;
357 sstream <<
"Gates_block::apply_to: transformed matrix contains NaN." << std::endl;
379 bool is_qbit_present(std::vector<int> involved_qubits,
int new_qbit,
int num_of_qbits){
381 bool contained=
false;
383 for (
int idx=0; idx<num_of_qbits; idx++) {
385 if(involved_qubits[idx] == new_qbit) {
400 std::vector<int> qbits;
404 for (
int idx =
gates.size()-1; idx>=0; idx--){
410 if (num_of_qbits == 0) {
411 qbits.push_back(target_new);
416 bool target_contained =
is_qbit_present(qbits,target_new,num_of_qbits);
417 bool control_contained = (control_new==-1) ?
true :
is_qbit_present(qbits, control_new, num_of_qbits);
419 if (num_of_qbits == max_fusion_temp && (target_contained ==
false || control_contained ==
false)){
422 while(vidx<num_of_qbits){
425 while(jdx>0 && qbits[jdx-1]>qbits[jdx]){
426 int qbit_temp = qbits[jdx];
427 qbits[jdx] = qbits[jdx-1];
428 qbits[jdx-1] = qbit_temp;
440 qbits=std::vector<int>{};
445 if (num_of_qbits<max_fusion_temp && target_contained==
false){
446 qbits.push_back(target_new);
450 if (num_of_qbits<max_fusion_temp && control_contained==
false){
451 qbits.push_back(control_new);
458 if (num_of_qbits == 1){
466 while(vidx<num_of_qbits){
469 while(jdx>0 && qbits[jdx-1]>qbits[jdx]){
470 int qbit_temp = qbits[jdx];
471 qbits[jdx] = qbits[jdx-1];
472 qbits[jdx-1] = qbit_temp;
494 for(
int op_idx = 0; op_idx<
gates.size(); op_idx++) {
500 parameter_idx = parameter_idx + 1;
505 data[parameter_idx+1] = 2 * M_PI;
506 parameter_idx = parameter_idx + 2;
511 data[parameter_idx+1] = 2 * M_PI;
512 data[parameter_idx+2] = 2 * M_PI;
513 parameter_idx = parameter_idx + 3;
517 CROT* crot_gate =
static_cast<CROT*
>(gate);
519 data[parameter_idx-2] = 4 * M_PI;
520 data[parameter_idx-1] = 2 * M_PI;
521 parameter_idx = parameter_idx - 2;
524 data[parameter_idx-4] = 4 * M_PI;
525 data[parameter_idx-3] = 2 * M_PI;
526 data[parameter_idx-2] = 4 * M_PI;
527 data[parameter_idx-1] = 2 * M_PI;
528 parameter_idx = parameter_idx - 4;
532 data[parameter_idx-1] = 4*M_PI;
533 data[parameter_idx-2] = 2*M_PI;
534 parameter_idx = parameter_idx - 2;
541 parameter_idx = parameter_idx + 1;
545 parameter_idx = parameter_idx + 1;
555 data[parameter_idx+i] = 2 * M_PI;
573 std::stringstream sstream;
578 int parameters_num_total = 0;
579 for (
int idx=0; idx<
gates.size(); idx++) {
592 for(
int idx=0; idx<(
int)
gates.size(); idx++) {
607 U1* u1_operation =
static_cast<U1*
>(operation);
612 U2* u2_operation =
static_cast<U2*
>(operation);
617 U3* u3_operation =
static_cast<U3*
>(operation);
622 R* r_operation =
static_cast<R*
>(operation);
627 RX* rx_operation =
static_cast<RX*
>(operation);
632 RY* ry_operation =
static_cast<RY*
>(operation);
637 CRY* cry_operation =
static_cast<CRY*
>(operation);
642 RZ* rz_operation =
static_cast<RZ*
>(operation);
647 UN* un_operation =
static_cast<UN*
>(operation);
652 ON* on_operation =
static_cast<ON*
>(operation);
662 CZ_NU* cz_nu_operation =
static_cast<CZ_NU*
>(operation);
677 std::string err(
"Gates_block::apply_from_right: unimplemented gate");
685 std::stringstream sstream;
686 sstream <<
"Gates_block::apply_from_right: transformed matrix contains NaN." << std::endl;
708 std::stringstream sstream;
713 if ( parallel == 0 ) {
714 work_batch =
gates.size();
722 tbb::parallel_for( tbb::blocked_range<int>(0,
gates.size(),work_batch), [&](tbb::blocked_range<int> r) {
723 for (
int deriv_idx=r.begin(); deriv_idx<r.end(); ++deriv_idx) {
741 std::vector<Matrix> grad_loc;
743 for(
int idx=0; idx<
gates.size(); idx++) {
756 std::string err(
"Gates_block::apply_derivate_to: Given operation not supported in gardient calculation");
764 if( idx < deriv_idx ) {
765 operation->
apply_to( input_loc, parallel );
774 if( idx < deriv_idx ) {
775 operation->
apply_to( parameters_mtx, input_loc, parallel );
777 else if ( idx == deriv_idx ) {
781 operation->
apply_to_list(parameters_mtx, grad_loc, parallel );
790 for (
int idx = 0; idx<(
int)grad_loc.size(); idx++ ) {
791 grad[deriv_parameter_idx+idx] = grad_loc[idx];
1009 Gate* operation =
static_cast<Gate*
>(
new CROT(
qbit_num, target_qbit, control_qbit, subtype_in));
1447 for(std::vector<Gate*>::iterator it = gates_in.begin(); it != gates_in.end(); ++it) {
1461 for(std::vector<Gate*>::iterator it = gates_in.end(); it != gates_in.begin(); --it) {
1593 gates.push_back(gate);
1677 for(std::vector<Gate*>::iterator it =
gates.begin(); it !=
gates.end(); ++it) {
1688 std::string gate_name = gate->
get_name();
1690 if( gate_nums.find(gate_name) == gate_nums.end() ) {
1691 gate_nums[ gate_name ] = 1;
1694 gate_nums[ gate_name ] = gate_nums[ gate_name ] + 1;
1709 std::map<std::string, int> gate_nums;
1734 return gates.size();
1747 std::stringstream sstream;
1748 sstream << std::endl <<
"The gates in the list of gates:" << std::endl;
1751 int gate_idx = start_index;
1753 double *parameters_data = parameters.
get_data();
1757 for(
int op_idx = 0; op_idx<
gates.size(); op_idx++) {
1762 CNOT* cnot_gate =
static_cast<CNOT*
>(gate);
1763 std::stringstream sstream;
1764 sstream << gate_idx <<
"th gate: CNOT with control qubit: " << cnot_gate->
get_control_qbit() <<
" and target qubit: " << cnot_gate->
get_target_qbit() << std::endl;
1766 gate_idx = gate_idx + 1;
1769 CROT* crot_gate =
static_cast<CROT*
>(gate);
1770 std::stringstream sstream;
1773 theta0 = std::fmod( 2*parameters_data[parameter_idx-2], 4*M_PI);
1774 phi0 = std::fmod( parameters_data[parameter_idx-1], 2*M_PI);
1775 parameter_idx = parameter_idx - 2;
1776 sstream << gate_idx <<
"th gate: CROT_CONTROL_R with control qubit: " << crot_gate->
get_control_qbit() <<
" and target qubit: " << crot_gate->
get_target_qbit()<<
" and parameters theta=" << theta0 <<
" and phi="<< phi0 << std::endl;
1781 theta0 = std::fmod( 2*parameters_data[parameter_idx-2], 4*M_PI);
1782 phi0 = std::fmod( parameters_data[parameter_idx-1], 2*M_PI);
1783 parameter_idx = parameter_idx - 2;
1784 sstream << gate_idx <<
"th gate: CROT_OPPOSITE with control qubit: " << crot_gate->
get_control_qbit() <<
" and target qubit: " << crot_gate->
get_target_qbit()<<
" and parameters theta=" << theta0 <<
" and phi="<< phi0 << std::endl;
1788 double theta0,phi0,theta1,phi1;
1789 theta0 = std::fmod( 2*parameters_data[parameter_idx-4], 4*M_PI);
1790 phi0 = std::fmod( parameters_data[parameter_idx-3], 2*M_PI);
1791 theta1 = std::fmod( 2*parameters_data[parameter_idx-2], 4*M_PI);
1792 phi1 = std::fmod( parameters_data[parameter_idx-1], 2*M_PI);
1793 sstream << gate_idx <<
"th gate: CROT_INDEPENDENT with control qubit: " << crot_gate->
get_control_qbit() <<
" and target qubit: " << crot_gate->
get_target_qbit()<<
" and parameters theta0=" << theta0 <<
", phi0="<< phi0 <<
", theta1=" << theta1 <<
" and phi1="<< phi1 << std::endl;
1795 parameter_idx = parameter_idx - 4;
1797 gate_idx = gate_idx + 1;
1800 CZ* cz_gate =
static_cast<CZ*
>(gate);
1801 std::stringstream sstream;
1802 sstream << gate_idx <<
"th gate: CZ with control qubit: " << cz_gate->
get_control_qbit() <<
" and target qubit: " << cz_gate->
get_target_qbit() << std::endl;
1804 gate_idx = gate_idx + 1;
1807 CH* ch_gate =
static_cast<CH*
>(gate);
1808 std::stringstream sstream;
1809 sstream << gate_idx <<
"th gate: CH with control qubit: " << ch_gate->
get_control_qbit() <<
" and target qubit: " << ch_gate->
get_target_qbit() << std::endl;
1811 gate_idx = gate_idx + 1;
1814 SYC* syc_gate =
static_cast<SYC*
>(gate);
1815 std::stringstream sstream;
1816 sstream << gate_idx <<
"th gate: Sycamore gate with control qubit: " << syc_gate->
get_control_qbit() <<
" and target qubit: " << syc_gate->
get_target_qbit() << std::endl;
1818 gate_idx = gate_idx + 1;
1821 U1* u1_gate =
static_cast<U1*
>(gate);
1822 double lambda = std::fmod(parameters_data[parameter_idx], 2*M_PI);
1823 parameter_idx = parameter_idx + 1;
1824 std::stringstream sstream;
1825 sstream << gate_idx <<
"th gate: U1 on target qubit: " << u1_gate->
get_target_qbit() <<
" with parameter lambda = " << lambda << std::endl;
1827 gate_idx = gate_idx + 1;
1830 U2* u2_gate =
static_cast<U2*
>(gate);
1831 double phi = std::fmod(parameters_data[parameter_idx], 2*M_PI);
1832 double lambda = std::fmod(parameters_data[parameter_idx+1], 2*M_PI);
1833 parameter_idx = parameter_idx + 2;
1834 std::stringstream sstream;
1835 sstream << gate_idx <<
"th gate: U2 on target qubit: " << u2_gate->
get_target_qbit() <<
" with parameters phi = " << phi <<
" and lambda = " << lambda << std::endl;
1837 gate_idx = gate_idx + 1;
1840 U3* u3_gate =
static_cast<U3*
>(gate);
1841 double theta = std::fmod(parameters_data[parameter_idx], 4*M_PI);
1842 double phi = std::fmod(parameters_data[parameter_idx+1], 2*M_PI);
1843 double lambda = std::fmod(parameters_data[parameter_idx+2], 2*M_PI);
1844 parameter_idx = parameter_idx + 3;
1845 std::stringstream sstream;
1846 sstream << gate_idx <<
"th gate: U3 on target qubit: " << u3_gate->
get_target_qbit() <<
" with parameters theta = " << theta <<
", phi = " << phi <<
" and lambda = " << lambda << std::endl;
1848 gate_idx = gate_idx + 1;
1852 double vartheta,varphi;
1854 R* r_gate =
static_cast<R*
>(gate);
1855 vartheta = std::fmod( 2*parameters_data[parameter_idx], 4*M_PI);
1856 varphi = std::fmod( parameters_data[parameter_idx+1], 2*M_PI);
1857 parameter_idx = parameter_idx + 2;
1859 std::stringstream sstream;
1860 sstream << gate_idx <<
"th gate: R on target qubit: " << r_gate->
get_target_qbit() <<
" and with parameters theta = " << vartheta <<
" and phi:" << varphi << std::endl;
1862 gate_idx = gate_idx + 1;
1868 RX* rx_gate =
static_cast<RX*
>(gate);
1869 vartheta = std::fmod( 2*parameters_data[parameter_idx], 4*M_PI);
1870 parameter_idx = parameter_idx + 1;
1872 std::stringstream sstream;
1873 sstream << gate_idx <<
"th gate: RX on target qubit: " << rx_gate->
get_target_qbit() <<
" and with parameters theta = " << vartheta << std::endl;
1875 gate_idx = gate_idx + 1;
1881 RY* ry_gate =
static_cast<RY*
>(gate);
1882 vartheta = std::fmod( 2*parameters_data[parameter_idx], 4*M_PI);
1883 parameter_idx = parameter_idx + 1;
1885 std::stringstream sstream;
1886 sstream << gate_idx <<
"th gate: RY on target qubit: " << ry_gate->
get_target_qbit() <<
" and with parameters theta = " << vartheta << std::endl;
1888 gate_idx = gate_idx + 1;
1894 CRY* cry_gate =
static_cast<CRY*
>(gate);
1895 vartheta = std::fmod( 2*parameters_data[parameter_idx], 4*M_PI);
1896 parameter_idx = parameter_idx + 1;
1898 std::stringstream sstream;
1899 sstream << gate_idx <<
"th gate: CRY on target qubit: " << cry_gate->
get_target_qbit() <<
", control qubit" << cry_gate->
get_control_qbit() <<
" and with parameters theta = " << vartheta << std::endl;
1901 gate_idx = gate_idx + 1;
1907 RZ* rz_gate =
static_cast<RZ*
>(gate);
1908 varphi = std::fmod( 2*parameters_data[parameter_idx], 2*M_PI);
1909 parameter_idx = parameter_idx + 1;
1911 std::stringstream sstream;
1912 sstream << gate_idx <<
"th gate: RZ on target qubit: " << rz_gate->
get_target_qbit() <<
" and with parameters varphi = " << varphi << std::endl;
1914 gate_idx = gate_idx + 1;
1918 H* h_gate =
static_cast<H*
>(gate);
1919 std::stringstream sstream;
1920 sstream << gate_idx <<
"th gate: Hadamard on target qubit: " << h_gate->
get_target_qbit() << std::endl;
1922 gate_idx = gate_idx + 1;
1926 X* x_gate =
static_cast<X*
>(gate);
1927 std::stringstream sstream;
1928 sstream << gate_idx <<
"th gate: X on target qubit: " << x_gate->
get_target_qbit() << std::endl;
1930 gate_idx = gate_idx + 1;
1934 Y* y_gate =
static_cast<Y*
>(gate);
1935 std::stringstream sstream;
1936 sstream << gate_idx <<
"th gate: Y on target qubit: " << y_gate->
get_target_qbit() << std::endl;
1938 gate_idx = gate_idx + 1;
1942 Z* z_gate =
static_cast<Z*
>(gate);
1943 std::stringstream sstream;
1944 sstream << gate_idx <<
"th gate: Z on target qubit: " << z_gate->
get_target_qbit() << std::endl;
1946 gate_idx = gate_idx + 1;
1950 SX* sx_gate =
static_cast<SX*
>(gate);
1952 std::stringstream sstream;
1953 sstream << gate_idx <<
"th gate: SX on target qubit: " << sx_gate->
get_target_qbit() << std::endl;
1955 gate_idx = gate_idx + 1;
1960 block_gate->
list_gates( parameters_layer, gate_idx );
1967 std::stringstream sstream;
1968 sstream << gate_idx <<
"th gate: UN " << gate->
get_parameter_num() <<
" parameters" << std::endl;
1970 gate_idx = gate_idx + 1;
1976 CZ_NU* cz_nu_gate =
static_cast<CZ_NU*
>(gate);
1977 Theta = std::fmod( parameters_data[parameter_idx], 2*M_PI);
1978 parameter_idx = parameter_idx +1;
1980 std::stringstream sstream;
1981 sstream << gate_idx <<
"th gate: CZ_NU gate on target qubit: " << cz_nu_gate->
get_target_qbit() <<
", control qubit " << cz_nu_gate->
get_control_qbit() <<
" and with parameters Theta = " << Theta << std::endl;
1983 gate_idx = gate_idx + 1;
1987 std::stringstream sstream;
1988 sstream << gate_idx <<
"th gate: ON " << gate->
get_parameter_num() <<
" parameters" << std::endl;
1990 gate_idx = gate_idx + 1;
1995 std::stringstream sstream;
1996 sstream << gate_idx <<
"th gate: Composite " << gate->
get_parameter_num() <<
" parameters" << std::endl;
1998 gate_idx = gate_idx + 1;
2005 Theta = std::fmod( 2*parameters_data[parameter_idx], 4*M_PI);
2006 parameter_idx = parameter_idx + 1;
2008 std::stringstream sstream;
2009 sstream << gate_idx <<
"th gate: Adaptive gate on target qubit: " << ad_gate->
get_target_qbit() <<
", control qubit " << ad_gate->
get_control_qbit() <<
" and with parameters Theta = " << Theta << std::endl;
2011 gate_idx = gate_idx + 1;
2014 std::string err(
"Gates_block::list_gates: unimplemented gate");
2048 for(std::vector<Gate*>::iterator it =
gates.begin(); it !=
gates.end(); ++it) {
2076 if (qbit_map.find( target_qbit ) != qbit_map.end()) {
2079 std::string err(
"Gates_block::create_remapped_circuit: Missing target qubit from the qbit map.");
2084 if ( control_qbit != -1 ) {
2085 if ( qbit_map.find( control_qbit ) != qbit_map.end() ) {
2088 std::string err(
"Gates_block::create_remapped_circuit: Missing control qubit from the qbit map.");
2103 std::string err(
"Gates_block::create_remapped_circuit: unimplemented gate");
2119 for(std::vector<Gate*>::iterator it =
gates.begin(); it !=
gates.end(); ++it) {
2124 CNOT* cnot_gate =
static_cast<CNOT*
>(gate);
2128 CZ* cz_gate =
static_cast<CZ*
>(gate);
2132 CH* ch_gate =
static_cast<CH*
>(gate);
2136 SYC* syc_gate =
static_cast<SYC*
>(gate);
2140 U1* u1_gate =
static_cast<U1*
>(gate);
2144 U2* u2_gate =
static_cast<U2*
>(gate);
2148 U3* u3_gate =
static_cast<U3*
>(gate);
2152 R* r_gate =
static_cast<R*
>(gate);
2156 RX* rx_gate =
static_cast<RX*
>(gate);
2160 RY* ry_gate =
static_cast<RY*
>(gate);
2164 CRY* cry_gate =
static_cast<CRY*
>(gate);
2168 CROT* crot_gate =
static_cast<CROT*
>(gate);
2172 RZ* rz_gate =
static_cast<RZ*
>(gate);
2176 H* h_gate =
static_cast<H*
>(gate);
2180 X* x_gate =
static_cast<X*
>(gate);
2184 Y* y_gate =
static_cast<Y*
>(gate);
2188 Z* z_gate =
static_cast<Z*
>(gate);
2192 T* t_gate =
static_cast<T*
>(gate);
2196 Tdg* tdg_gate =
static_cast<Tdg*
>(gate);
2200 SX* sx_gate =
static_cast<SX*
>(gate);
2208 UN* un_gate =
static_cast<UN*
>(gate);
2212 ON* on_gate =
static_cast<ON*
>(gate);
2224 std::string err(
"Gates_block::reorder_qubits: unimplemented gate");
2244 for(std::vector<Gate*>::iterator it =
gates.begin(); it !=
gates.end(); ++it) {
2280 if (idx > (
int)
gates.size() ) {
2295 std::vector<Gate*> gates_in = op_block->
get_gates();
2299 std::string err(
"Gates_block::combine: number of qubits in the circuits must be the same");
2303 for(std::vector<Gate*>::iterator it = (gates_in).begin(); it != (gates_in).end(); ++it) {
2318 if (qbit_num_in > 30) {
2319 std::string err(
"Gates_block::set_qbit_num: Number of qubits supported up to 30");
2327 for(std::vector<Gate*>::iterator it =
gates.begin(); it !=
gates.end(); ++it) {
2346 std::string err(
"Gates_block::set_qbit_num: unimplemented gate");
2368 std::string err(
"Gates_block::clone(): extracting gates was not succesfull");
2386 for ( std::vector<Gate*>::iterator it=
gates.begin(); it !=
gates.end(); ++it ) {
2407 std::string err(
"Gates_block::extract_gates: unimplemented gate");
2425 for ( std::vector<Gate*>::iterator it=
gates.begin(); it !=
gates.end(); ++it ) {
2434 if ( ret )
return true;
2480 if (input_state.
cols != 1) {
2481 std::string error(
"Gates_block::get_reduced_density_matrix: The number of columns in input state should be 1");
2487 std::string error(
"Gates_block::get_reduced_density_matrix: The number of rows in input state should be 2^qbit_num");
2493 if ( parameters_mtx.
size() > 0 ) {
2494 bool parallel =
true;
2495 apply_to( parameters_mtx, transformed_state, parallel );
2499 int subset_qbit_num = qbit_list_subset.
size();
2500 int complementary_qbit_num =
qbit_num - subset_qbit_num;
2505 int qbit_idx_count = 0;
2506 for (
int qbit_idx=0; qbit_idx<
qbit_num; qbit_idx++) {
2508 bool qbit_idx_in_subset =
false;
2510 for (
int subset_qbit_idx=0; subset_qbit_idx<subset_qbit_num; subset_qbit_idx++) {
2511 if ( qbit_idx == qbit_list_subset[subset_qbit_idx] ) {
2512 qbit_idx_in_subset =
true;
2518 if ( qbit_idx_in_subset ) {
2522 qbit_list_complementary[qbit_idx_count] = qbit_idx;
2529 for (
int qbit_idx=0; qbit_idx<
qbit_num; qbit_idx++) {
2530 qbit_masks[ qbit_idx ] = 1 << qbit_idx;
2536 int rho_matrix_size = 1 << subset_qbit_num;
2538 Matrix rho(rho_matrix_size, rho_matrix_size);
2544 int complementary_basis_num = 1 << complementary_qbit_num;
2545 for (
int row_idx=0; row_idx<rho_matrix_size; row_idx++ ) {
2549 for (
int qbit_idx=0; qbit_idx<subset_qbit_num; qbit_idx++) {
2550 if ( row_idx & qbit_masks[ qbit_idx ] ) {
2551 idx = idx | qbit_masks[ qbit_list_subset[qbit_idx] ];
2555 for (
int col_idx=row_idx; col_idx<rho_matrix_size; col_idx++ ) {
2559 for (
int qbit_idx=0; qbit_idx<subset_qbit_num; qbit_idx++) {
2560 if ( col_idx & qbit_masks[ qbit_idx ] ) {
2561 jdx = jdx | qbit_masks[ qbit_list_subset[qbit_idx] ];
2567 tbb::combinable<QGD_Complex16> priv_addend {[](){
QGD_Complex16 ret; ret.
real = 0.0; ret.
imag = 0.0;
return ret;}};
2570 tbb::parallel_for( tbb::blocked_range<int>(0, complementary_basis_num, 1024), [&](tbb::blocked_range<int> r) {
2574 for (
int compl_idx=r.begin(); compl_idx<r.end(); compl_idx++) {
2580 for (
int qbit_idx=0; qbit_idx<complementary_qbit_num; qbit_idx++) {
2581 if ( compl_idx & qbit_masks[ qbit_idx ] ) {
2582 idx_loc = idx_loc | qbit_masks[ qbit_list_complementary[qbit_idx] ];
2583 jdx_loc = jdx_loc | qbit_masks[ qbit_list_complementary[qbit_idx] ];
2591 element_idx.
imag = -element_idx.
imag;
2595 rho_element_priv.
real = rho_element_priv.
real + addend.
real;
2596 rho_element_priv.
imag = rho_element_priv.
imag + addend.
imag;
2605 rho_element.
real = 0.0;
2606 rho_element.imag = 0.0;
2609 rho_element.real = rho_element.real + a.
real;
2610 rho_element.imag = rho_element.imag + a.
imag;
2613 rho[ row_idx * rho.
stride + col_idx ].real += rho_element.real;
2614 rho[ row_idx * rho.
stride + col_idx ].imag += rho_element.imag;
2616 if ( row_idx == col_idx ) {
2620 rho[ col_idx * rho.
stride + row_idx ].real += rho_element.real;
2621 rho[ col_idx * rho.
stride + row_idx ].imag -= rho_element.imag;
2631 for(
int idx=0; idx<rho_matrix_size; idx++) {
2632 trace = trace + rho[idx*rho.
stride+idx].real;
2635 if ( abs( trace-1.0 ) > 1e-6 ) {
2636 std::stringstream sstream;
2637 sstream <<
"Warning: Gates_block::get_reduced_density_matrix: The error of the trace of the reduced density matrix is " << abs( trace-1.0 ) << std::endl;
2662 double trace_rho_square = 0.0;
2664 for (
int idx=0; idx<rho.
rows; idx++) {
2666 double trace_tmp = 0.0;
2668 for (
int jdx=0; jdx<rho.
rows; jdx++) {
2672 trace_tmp = trace_tmp + tmp;
2676 trace_rho_square = trace_rho_square + trace_tmp;
2684 double entropy = -log(trace_rho_square);
2700 std::vector<int> ret = list1;
2702 for( std::vector<int>::iterator it2 = list2.begin(); it2 != list2.end(); it2++ ) {
2704 std::vector<int>::iterator element_found = std::find(ret.begin(), ret.end(), *it2);
2706 if( element_found != ret.end() ) {
2707 ret.erase( element_found );
2736 for(
int idx=
gates.size()-1; idx>=0; idx-- ) {
2742 if( reduced_qbit_list.size() < involved_qubits.size() ) {
2748 involved_qubits = std::move(reduced_qbit_list);
2755 if( involved_qubits.size() == 0 ) {
2776 for(
int idx=0; idx<
gates.size(); idx++ ) {
2782 if( reduced_qbit_list.size() < involved_qubits.size() ) {
2788 involved_qubits = std::move(reduced_qbit_list);
2795 if( involved_qubits.size() == 0 ) {
2811 for( std::vector<Gate*>::iterator gate_it =
gates.begin(); gate_it !=
gates.end(); gate_it++ ) {
2813 Gate* gate = *gate_it;
2831 for( std::vector<Gate*>::iterator gate_it =
gates.begin(); gate_it !=
gates.end(); gate_it++ ) {
2832 Gate* gate = *gate_it;
2839 for( std::vector<Gate*>::iterator gate_it =
gates.begin(); gate_it !=
gates.end(); gate_it++ ) {
2840 Gate* gate = *gate_it;
2861 for( std::vector<Gate*>::iterator gate_it=
gates.begin(); gate_it !=
gates.end(); gate_it++ ) {
2863 Gate* gate = *gate_it;
2870 flat_circuit->
combine( flat_circuit_inner );
2872 delete( flat_circuit_inner );
2882 return flat_circuit;
2898 std::string err(
"Gates_block::extract_parameters: Cant extract parameters, since th einput arary has not enough elements.");
2906 return extracted_parameters;
2918 DFEgate_kernel_type* Gates_block::convert_to_DFE_gates_with_derivates(
Matrix_real& parameters_mtx,
int& gatesNum,
int& gateSetNum,
int& redundantGateSets,
bool only_derivates ) {
2921 if ( parameter_num != parameters_mtx.
size() ) {
2922 std::string error(
"Gates_block::convert_to_DFE_gates: wrong number of parameters");
2927 int gates_total_num = 0;
2928 for(
auto it=gate_nums.begin(); it != gate_nums.end(); it++ ) {
2929 gates_total_num = gates_total_num + it->second;
2933 int gate_padding = gates_total_num % chained_gates_num == 0 ? 0 : chained_gates_num - (gates_total_num % chained_gates_num);
2934 gatesNum = gates_total_num+gate_padding;
2941 gateSetNum = only_derivates ?
parameter_num : parameter_num+1;
2946 redundantGateSets = 0;
2950 gateSetNum = gateSetNum + redundantGateSets;
2953 int rem = gateSetNum % 4;
2955 redundantGateSets = 0;
2958 redundantGateSets = 4 - (gateSetNum % 4);
2959 gateSetNum = gateSetNum + redundantGateSets;
2968 convert_to_DFE_gates( parameters_mtx, DFEgates, gate_idx );
2972 for (
int idx=gate_idx; idx<gatesNum; idx++ ){
2981 DFEGate.
Phi = (int32_t)(0);
2982 DFEGate.
Lambda = (int32_t)(0);
2994 if (only_derivates ) {
2995 for (
int idx=1; idx<(gateSetNum-1); idx++) {
3000 for (
int idx=0; idx<(gateSetNum-1); idx++) {
3006 int gate_set_index = parameter_num-1;
3007 if (only_derivates) {
3008 adjust_parameters_for_derivation( DFEgates, gatesNum, gate_idx, gate_set_index );
3011 adjust_parameters_for_derivation( DFEgates+gatesNum, gatesNum, gate_idx, gate_set_index );
3029 void Gates_block::adjust_parameters_for_derivation(
DFEgate_kernel_type* DFEgates,
const int gatesNum,
int& gate_idx,
int& gate_set_index) {
3034 int32_t parameter_shift = (int32_t)(M_PI/2*(1<<25));
3036 for(
int op_idx =
gates.size()-1; op_idx>=0; op_idx--) {
3042 gate_idx = gate_idx + 1;
3045 gate_idx = gate_idx + 1;
3048 gate_idx = gate_idx + 1;
3051 std::string error(
"Gates_block::convert_to_DFE_gates: SYC_gate not implemented");
3059 gate_set_index = gate_set_index - 1;
3061 parameter_idx = parameter_idx - 1;
3062 gate_idx = gate_idx + 1;
3069 gate_set_index = gate_set_index - 1;
3073 DFEGate.
Phi = DFEGate.
Phi + parameter_shift;
3075 gate_set_index = gate_set_index - 1;
3077 parameter_idx = parameter_idx - 2;
3078 gate_idx = gate_idx + 1;
3085 gate_set_index = gate_set_index - 1;
3089 DFEGate2.
Phi = DFEGate2.
Phi + parameter_shift;
3091 gate_set_index = gate_set_index - 1;
3097 gate_set_index = gate_set_index - 1;
3099 parameter_idx = parameter_idx - 3;
3100 gate_idx = gate_idx + 1;
3107 gate_set_index = gate_set_index - 1;
3109 parameter_idx = parameter_idx - 1;
3111 gate_idx = gate_idx + 1;
3118 gate_set_index = gate_set_index - 1;
3120 parameter_idx = parameter_idx - 1;
3123 gate_idx = gate_idx + 1;
3130 gate_set_index = gate_set_index - 1;
3132 parameter_idx = parameter_idx - 1;
3134 gate_idx = gate_idx + 1;
3138 std::string error(
"Gates_block::adjust_parameters_for_derivation: RZ gate not implemented for DFE");
3144 DFEGate.
Phi = DFEGate.
Phi + parameter_shift;
3146 gate_set_index = gate_set_index - 1;
3148 parameter_idx = parameter_idx - 1;
3150 gate_idx = gate_idx + 1;
3153 std::string error(
"Gates_block::convert_to_DFE_gates: H_gate not implemented");
3158 std::string error(
"Gates_block::convert_to_DFE_gates: X_gate not implemented");
3163 std::string error(
"Gates_block::convert_to_DFE_gates: Y_gate not implemented");
3168 std::string error(
"Gates_block::convert_to_DFE_gates: Z_gate not implemented");
3173 std::string error(
"Gates_block::convert_to_DFE_gates: T_gate not implemented");
3178 std::string error(
"Gates_block::convert_to_DFE_gates: Tdg_gate not implemented");
3182 std::string error(
"Gates_block::convert_to_DFE_gates: SX_gate not implemented");
3188 block_gate->adjust_parameters_for_derivation( DFEgates, gatesNum, gate_idx, gate_set_index);
3194 std::string error(
"Gates_block::convert_to_DFE_gates: UN_gate not implemented");
3200 std::string error(
"Gates_block::convert_to_DFE_gates: ON_gate not implemented");
3204 std::string error(
"Gates_block::convert_to_DFE_gates: Composite_gate not implemented");
3208 std::string error(
"Gates_block::convert_to_DFE_gates: general_gate not implemented");
3216 gate_set_index = gate_set_index - 1;
3218 parameter_idx = parameter_idx - 1;
3220 gate_idx = gate_idx + 1;
3223 std::string err(
"Gates_block::adjust_parameters_for_derivation: unimplemented gate");
3238 Gates_block::convert_to_batched_DFE_gates( std::vector<Matrix_real>& parameters_mtx_vec,
int& gatesNum,
int& gateSetNum,
int& redundantGateSets ) {
3242 int gates_total_num = 0;
3243 for(
auto it=gate_nums.begin(); it != gate_nums.end(); it++ ) {
3244 gates_total_num = gates_total_num + it->second;
3248 int gate_padding = gates_total_num % chained_gates_num == 0 ? 0 : chained_gates_num - (gates_total_num % chained_gates_num);
3249 gatesNum = gates_total_num+gate_padding;
3256 gateSetNum = parameters_mtx_vec.size();
3261 redundantGateSets = 0;
3265 gateSetNum = gateSetNum + redundantGateSets;
3268 int rem = gateSetNum % 4;
3270 redundantGateSets = 0;
3273 redundantGateSets = 4 - (gateSetNum % 4);
3274 gateSetNum = gateSetNum + redundantGateSets;
3281 tbb::parallel_for( 0, gateSetNum, 1, [&](
int gateset_idx) {
3283 int gate_idx = gateset_idx * gatesNum;
3285 if ( gateset_idx < parameters_mtx_vec.size() ) {
3286 Matrix_real& parameters_mtx = parameters_mtx_vec[gateset_idx];
3287 convert_to_DFE_gates( parameters_mtx, DFEgates, gate_idx );
3291 for (
int idx=gate_idx; idx<(gateset_idx+1)*gatesNum; idx++ ){
3300 DFEGate.
Phi = (int32_t)(0);
3301 DFEGate.
Lambda = (int32_t)(0);
3322 if ( parameter_num != parameters_mtx.
size() ) {
3323 std::string error(
"Gates_block::convert_to_DFE_gates: wrong number of parameters");
3329 int gates_total_num = 0;
3330 for(
auto it=gate_nums.begin(); it != gate_nums.end(); it++ ) {
3331 gates_total_num = gates_total_num + it->second;
3335 int gate_padding = chained_gates_num - (gates_total_num % chained_gates_num);
3336 gatesNum = gates_total_num+gate_padding;
3343 convert_to_DFE_gates( parameters_mtx, DFEgates, gate_idx );
3347 for (
int idx=gate_idx; idx<gatesNum; idx++ ){
3356 DFEGate.
Phi = (int32_t)(0);
3357 DFEGate.
Lambda = (int32_t)(0);
3382 int& gate_idx = start_index;
3384 double *parameters_data = parameters_mtx.
get_data();
3388 for(
int op_idx =
gates.size()-1; op_idx>=0; op_idx--) {
3394 CNOT* cnot_gate =
static_cast<CNOT*
>(gate);
3398 DFEGate.
ThetaOver2 = (int32_t)(M_PI/2*(1<<25));
3399 DFEGate.
Phi = (int32_t)(0);
3400 DFEGate.
Lambda = (int32_t)(M_PI*(1<<25));
3402 gate_idx = gate_idx + 1;
3405 CZ* cz_gate =
static_cast<CZ*
>(gate);
3410 DFEGate.
Phi = (int32_t)(0);
3411 DFEGate.
Lambda = (int32_t)(M_PI*(1<<25));
3413 gate_idx = gate_idx + 1;
3416 CH* ch_gate =
static_cast<CH*
>(gate);
3420 DFEGate.
ThetaOver2 = (int32_t)(M_PI/4*(1<<25));
3421 DFEGate.
Phi = (int32_t)(0);
3422 DFEGate.
Lambda = (int32_t)(M_PI*(1<<25));
3424 gate_idx = gate_idx + 1;
3427 std::string error(
"Gates_block::convert_to_DFE_gates: SYC_gate not implemented");
3431 double lambda = std::fmod(parameters_data[parameter_idx-1], 2*M_PI);
3432 parameter_idx = parameter_idx - 1;
3438 DFEGate.
Phi = (int32_t)(0);
3439 DFEGate.
Lambda = (int32_t)(lambda*(1<<25));
3441 gate_idx = gate_idx + 1;
3444 double phi = std::fmod(parameters_data[parameter_idx-2], 2*M_PI);
3445 double lambda = std::fmod(parameters_data[parameter_idx-1], 2*M_PI);
3446 parameter_idx = parameter_idx - 2;
3451 DFEGate.
ThetaOver2 = (int32_t)(M_PI/4*(1<<25));
3452 DFEGate.
Phi = (int32_t)(phi*(1<<25));
3453 DFEGate.
Lambda = (int32_t)(lambda*(1<<25));
3455 gate_idx = gate_idx + 1;
3458 double theta = std::fmod(parameters_data[parameter_idx-3], 4*M_PI);
3459 double phi = std::fmod(parameters_data[parameter_idx-2], 2*M_PI);
3460 double lambda = std::fmod(parameters_data[parameter_idx-1], 2*M_PI);
3461 parameter_idx = parameter_idx - 3;
3466 DFEGate.
ThetaOver2 = (int32_t)(theta/2.0*(1<<25));
3467 DFEGate.
Phi = (int32_t)(phi*(1<<25));
3468 DFEGate.
Lambda = (int32_t)(lambda*(1<<25));
3470 gate_idx = gate_idx + 1;
3474 double varthetaOver2;
3476 RX* rx_gate =
static_cast<RX*
>(gate);
3477 varthetaOver2 = std::fmod( parameters_data[parameter_idx-1], 2*M_PI);
3478 parameter_idx = parameter_idx - 1;
3483 DFEGate.
ThetaOver2 = (int32_t)(varthetaOver2*(1<<25));
3484 DFEGate.
Phi = (int32_t)(-M_PI/2*(1<<25));
3485 DFEGate.
Lambda = (int32_t)(M_PI/2*(1<<25));
3488 gate_idx = gate_idx + 1;
3492 double varthetaOver2;
3494 RY* ry_gate =
static_cast<RY*
>(gate);
3495 varthetaOver2 = std::fmod( parameters_data[parameter_idx-1], 2*M_PI);
3496 parameter_idx = parameter_idx - 1;
3501 DFEGate.
ThetaOver2 = (int32_t)(varthetaOver2*(1<<25));
3502 DFEGate.
Phi = (int32_t)(0);
3503 DFEGate.
Lambda = (int32_t)(0);
3506 gate_idx = gate_idx + 1;
3512 CRY* cry_gate =
static_cast<CRY*
>(gate);
3513 double varthetaOver2 = std::fmod( parameters_data[parameter_idx-1], 2*M_PI);
3514 parameter_idx = parameter_idx - 1;
3518 DFEGate.
ThetaOver2 = (int32_t)(varthetaOver2*(1<<25));
3519 DFEGate.
Phi = (int32_t)(0);
3520 DFEGate.
Lambda = (int32_t)(0);
3523 gate_idx = gate_idx + 1;
3527 std::string error(
"Gates_block::convert_to_DFE_gates: RZ gate not implemented for DFE. Use RZ_P gate instead that differs from RZ gate by a global phase");
3536 RZ* rz_gate =
static_cast<RZ*
>(gate);
3537 varphi = std::fmod( parameters_data[parameter_idx-1], 2*M_PI);
3538 parameter_idx = parameter_idx - 1;
3544 DFEGate.
Phi = (int32_t)(varphi*(1<<25));
3545 DFEGate.
Lambda = (int32_t)(0);
3548 gate_idx = gate_idx + 1;
3552 H* h_gate =
static_cast<H*
>(gate);
3554 std::string error(
"Gates_block::convert_to_DFE_gates: Hadamard gate not implemented");
3557 gate_idx = gate_idx + 1;
3561 X* x_gate =
static_cast<X*
>(gate);
3566 DFEGate.
ThetaOver2 = (int32_t)(M_PI/2*(1<<25));
3567 DFEGate.
Phi = (int32_t)(0);
3568 DFEGate.
Lambda = (int32_t)(M_PI*(1<<25));
3571 gate_idx = gate_idx + 1;
3575 Y* y_gate =
static_cast<Y*
>(gate);
3580 DFEGate.
ThetaOver2 = (int32_t)(M_PI/2*(1<<25));
3581 DFEGate.
Phi = (int32_t)(M_PI/2*(1<<25));
3582 DFEGate.
Lambda = (int32_t)(M_PI/2*(1<<25));
3585 gate_idx = gate_idx + 1;
3589 Z* z_gate =
static_cast<Z*
>(gate);
3595 DFEGate.
Phi = (int32_t)(0);
3596 DFEGate.
Lambda = (int32_t)(M_PI*(1<<25));
3599 gate_idx = gate_idx + 1;
3603 SX* sx_gate =
static_cast<SX*
>(gate);
3604 std::string error(
"Gates_block::convert_to_DFE_gates: SX_gate not implemented");
3610 block_gate->convert_to_DFE_gates( parameters_layer_mtx, DFEgates, gate_idx );
3614 std::string error(
"Gates_block::convert_to_DFE_gates: UN_gate not implemented");
3620 std::string error(
"Gates_block::convert_to_DFE_gates: ON_gate not implemented");
3624 std::string error(
"Gates_block::convert_to_DFE_gates: Composite_gate not implemented");
3628 std::string error(
"Gates_block::convert_to_DFE_gates: general_gate not implemented");
3637 parameter_idx = parameter_idx - 1;
3641 DFEGate.
ThetaOver2 = (int32_t)(varthetaOver2*(1<<25));
3642 DFEGate.
Phi = (int32_t)(0);
3643 DFEGate.
Lambda = (int32_t)(0);
3646 gate_idx = gate_idx + 1;
3649 std::string err(
"Gates_block::convert_to_DFE_gates: unimplemented gate");
3668 Gates_block::extract_gate_kernels_target_and_control_qubits(std::vector<Matrix> &u3_qbit, std::vector<int> &
target_qbit, std::vector<int> &
control_qbit,
Matrix_real& parameters_mtx)
3671 if ( u3_qbit.size() == 0 ) {
3673 int gates_total_num = 0;
3674 for(
auto it=gate_nums.begin(); it != gate_nums.end(); it++ ) {
3675 gates_total_num = gates_total_num + it->second;
3678 u3_qbit.reserve( gates_total_num );
3690 for(
int idx=0; idx<
gates.size(); idx++) {
3699 CNOT* cnot_operation =
static_cast<CNOT*
>(operation);
3704 H* h_operation =
static_cast<H*
>(operation);
3709 X* x_operation =
static_cast<X*
>(operation);
3714 Y* y_operation =
static_cast<Y*
>(operation);
3719 Z* z_operation =
static_cast<Z*
>(operation);
3724 T* t_operation =
static_cast<T*
>(operation);
3729 Tdg* tdg_operation =
static_cast<Tdg*
>(operation);
3734 SX* sx_operation =
static_cast<SX*
>(operation);
3739 U1* u1_operation =
static_cast<U1*
>(operation);
3744 U2* u2_operation =
static_cast<U2*
>(operation);
3745 u3_qbit.push_back(u2_operation->
calc_one_qubit_u3(params_mtx[0], params_mtx[1]));
3749 U3* u3_operation =
static_cast<U3*
>(operation);
3750 u3_qbit.push_back(u3_operation->
calc_one_qubit_u3(params_mtx[0], params_mtx[1], params_mtx[2]));
3754 RX* rx_operation =
static_cast<RX*
>(operation);
3756 double ThetaOver2 = params_mtx[0];
3757 double Phi = -M_PI/2;
3764 RY* ry_operation =
static_cast<RY*
>(operation);
3765 double ThetaOver2 = params_mtx[0];
3773 CRY* cry_operation =
static_cast<CRY*
>(operation);
3775 ThetaOver2 = params_mtx[0];
3781 RZ* rz_operation =
static_cast<RZ*
>(operation);
3802 if ( involved_qubits.size() == 1 && block_operation->
gates.size() > 1 && block_operation->
get_qbit_num() > 1 ) {
3807 for (
int idx=0; idx<block_operation->
gates.size(); idx++){
3808 Gate* gate = block_operation->
gates[idx]->clone();
3817 gates_block_mini.
apply_to(params_mtx, merged_kernel);
3819 u3_qbit.push_back( merged_kernel );
3825 block_operation->extract_gate_kernels_target_and_control_qubits(u3_qbit,
target_qbit,
control_qbit, params_mtx);
3836 std::string err(
"Optimization_Interface::apply_to: unimplemented gate (" + std::to_string(operation->
get_type()) +
")");
3858 std::stringstream sstream;
3859 sstream <<
"Exporting circuit into binary format. Filename: " << filename << std::endl;
3862 log.
print(sstream, 3);
3865 const char* c_filename = filename.c_str();
3867 pFile = fopen(c_filename,
"wb");
3868 if (pFile==NULL) {fputs (
"File error",stderr); exit (1);}
3887 fwrite(&qbit_num,
sizeof(
int), 1, pFile);
3890 fwrite(¶meter_num,
sizeof(
int), 1, pFile);
3894 fwrite(&gates_num,
sizeof(
int), 1, pFile);
3899 double* parameters_data = parameters.
get_data();
3901 for ( std::vector<Gate*>::iterator it=gates.begin(); it != gates.end(); ++it ) {
3906 fwrite(>_type,
sizeof(
gate_type), 1, pFile);
3913 fwrite(&target_qbit,
sizeof(
int), 1, pFile);
3914 fwrite(&control_qbit,
sizeof(
int), 1, pFile);
3918 fwrite(&target_qbit,
sizeof(
int), 1, pFile);
3919 fwrite(parameters_data,
sizeof(
double), parameter_num, pFile);
3923 fwrite(&target_qbit,
sizeof(
int), 1, pFile);
3925 fwrite(parameters_data,
sizeof(
double), parameter_num, pFile);
3930 fwrite(&target_qbit,
sizeof(
int), 1, pFile);
3931 fwrite(&control_qbit,
sizeof(
int), 1, pFile);
3933 fwrite(parameters_data,
sizeof(
double), parameter_num, pFile);
3938 fwrite(&target_qbit,
sizeof(
int), 1, pFile);
3942 Matrix_real parameters_loc(parameters_data, 1, parameter_num);
3949 fwrite(&target_qbit,
sizeof(
int), 1, pFile);
3950 fwrite(&control_qbit,
sizeof(
int), 1, pFile);
3952 fwrite(parameters_data,
sizeof(
double), parameter_num, pFile);
3955 std::string err(
"export_gate_list_to_binary: unimplemented gate");
3973 std::stringstream sstream;
3974 sstream <<
"Importing quantum circuit from binary file " << filename << std::endl;
3977 log.
print(sstream, 2);
3980 const char* c_filename = filename.c_str();
3982 pFile = fopen(c_filename,
"rb");
3983 if (pFile==NULL) {fputs (
"File error",stderr); exit (1);}
3997 std::stringstream sstream;
4000 size_t fread_status;
4002 fread_status = fread(&qbit_num,
sizeof(
int), 1, pFile);
4003 sstream <<
"qbit_num: " << qbit_num << std::endl;
4007 fread_status = fread(¶meter_num,
sizeof(
int), 1, pFile);
4008 sstream <<
"parameter_num: " << parameter_num << std::endl;
4010 double* parameters_data = parameters.
get_data();
4013 fread_status = fread(&gates_num,
sizeof(
int), 1, pFile);
4014 sstream <<
"gates_num: " << gates_num << std::endl;
4016 std::vector<int> gate_block_level_gates_num;
4017 std::vector<Gates_block*> gate_block_levels;
4018 gate_block_level_gates_num.push_back( gates_num );
4019 gate_block_levels.push_back(gate_block);
4020 int current_level = 0;
4026 while ( gate_block_level_gates_num[0] > 0 && iter < iter_max) {
4029 fread_status = fread(>_type,
sizeof(
gate_type), 1, pFile);
4034 sstream <<
"importing CNOT gate" << std::endl;
4037 fread_status = fread(&target_qbit,
sizeof(
int), 1, pFile);
4038 sstream <<
"target_qbit: " << target_qbit << std::endl;
4041 fread_status = fread(&control_qbit,
sizeof(
int), 1, pFile);
4042 sstream <<
"control_qbit: " << control_qbit << std::endl;
4044 gate_block_levels[current_level]->add_cnot(target_qbit, control_qbit);
4045 gate_block_level_gates_num[current_level]--;
4048 sstream <<
"importing CZ gate" << std::endl;
4051 fread_status = fread(&target_qbit,
sizeof(
int), 1, pFile);
4052 sstream <<
"target_qbit: " << target_qbit << std::endl;
4055 fread_status = fread(&control_qbit,
sizeof(
int), 1, pFile);
4056 sstream <<
"control_qbit: " << control_qbit << std::endl;
4058 gate_block_levels[current_level]->add_cz(target_qbit, control_qbit);
4059 gate_block_level_gates_num[current_level]--;
4062 sstream <<
"importing CH gate" << std::endl;
4065 fread_status = fread(&target_qbit,
sizeof(
int), 1, pFile);
4066 sstream <<
"target_qbit: " << target_qbit << std::endl;
4069 fread_status = fread(&control_qbit,
sizeof(
int), 1, pFile);
4070 sstream <<
"control_qbit: " << control_qbit << std::endl;
4072 gate_block_levels[current_level]->add_ch(target_qbit, control_qbit);
4073 gate_block_level_gates_num[current_level]--;
4076 sstream <<
"importing SYCAMORE gate" << std::endl;
4079 fread_status = fread(&target_qbit,
sizeof(
int), 1, pFile);
4080 sstream <<
"target_qbit: " << target_qbit << std::endl;
4083 fread_status = fread(&control_qbit,
sizeof(
int), 1, pFile);
4084 sstream <<
"control_qbit: " << control_qbit << std::endl;
4086 gate_block_levels[current_level]->add_syc(target_qbit, control_qbit);
4087 gate_block_level_gates_num[current_level]--;
4090 sstream <<
"importing U1 gate" << std::endl;
4093 fread_status = fread(&target_qbit,
sizeof(
int), 1, pFile);
4094 sstream <<
"target_qbit: " << target_qbit << std::endl;
4096 fread_status = fread(parameters_data,
sizeof(
double), 1, pFile);
4099 gate_block_levels[current_level]->add_u1(target_qbit);
4100 gate_block_level_gates_num[current_level]--;
4103 sstream <<
"importing U2 gate" << std::endl;
4106 fread_status = fread(&target_qbit,
sizeof(
int), 1, pFile);
4107 sstream <<
"target_qbit: " << target_qbit << std::endl;
4109 fread_status = fread(parameters_data,
sizeof(
double), 2, pFile);
4112 gate_block_levels[current_level]->add_u2(target_qbit);
4113 gate_block_level_gates_num[current_level]--;
4116 sstream <<
"importing U3 gate" << std::endl;
4119 fread_status = fread(&target_qbit,
sizeof(
int), 1, pFile);
4120 sstream <<
"target_qbit: " << target_qbit << std::endl;
4122 fread_status = fread(parameters_data,
sizeof(
double), 3, pFile);
4124 parameters_data += 3;
4125 gate_block_levels[current_level]->add_u3(target_qbit);
4126 gate_block_level_gates_num[current_level]--;
4130 sstream <<
"importing RX gate" << std::endl;
4133 fread_status = fread(&target_qbit,
sizeof(
int), 1, pFile);
4134 sstream <<
"target_qbit: " << target_qbit << std::endl;
4136 fread_status = fread(parameters_data,
sizeof(
double), 1, pFile);
4139 gate_block_levels[current_level]->add_rx(target_qbit);
4140 gate_block_level_gates_num[current_level]--;
4145 sstream <<
"importing RY gate" << std::endl;
4148 fread_status = fread(&target_qbit,
sizeof(
int), 1, pFile);
4149 sstream <<
"target_qbit: " << target_qbit << std::endl;
4151 fread_status = fread(parameters_data,
sizeof(
double), 1, pFile);
4154 gate_block_levels[current_level]->add_ry(target_qbit);
4155 gate_block_level_gates_num[current_level]--;
4160 sstream <<
"importing CRY gate" << std::endl;
4163 fread_status = fread(&target_qbit,
sizeof(
int), 1, pFile);
4164 sstream <<
"target_qbit: " << target_qbit << std::endl;
4167 fread_status = fread(&control_qbit,
sizeof(
int), 1, pFile);
4168 sstream <<
"control_qbit: " << control_qbit << std::endl;
4170 fread_status = fread(parameters_data,
sizeof(
double), 1, pFile);
4173 gate_block_levels[current_level]->add_cry(target_qbit, control_qbit);
4174 gate_block_level_gates_num[current_level]--;
4179 sstream <<
"importing RZ gate" << std::endl;
4182 fread_status = fread(&target_qbit,
sizeof(
int), 1, pFile);
4183 sstream <<
"target_qbit: " << target_qbit << std::endl;
4185 fread_status = fread(parameters_data,
sizeof(
double), 1, pFile);
4188 gate_block_levels[current_level]->add_rz(target_qbit);
4189 gate_block_level_gates_num[current_level]--;
4194 sstream <<
"importing Hadamard gate" << std::endl;
4197 fread_status = fread(&target_qbit,
sizeof(
int), 1, pFile);
4198 sstream <<
"target_qbit: " << target_qbit << std::endl;
4200 gate_block_levels[current_level]->add_h(target_qbit);
4201 gate_block_level_gates_num[current_level]--;
4206 sstream <<
"importing X gate" << std::endl;
4209 fread_status = fread(&target_qbit,
sizeof(
int), 1, pFile);
4210 sstream <<
"target_qbit: " << target_qbit << std::endl;
4212 gate_block_levels[current_level]->add_x(target_qbit);
4213 gate_block_level_gates_num[current_level]--;
4218 sstream <<
"importing Y gate" << std::endl;
4221 fread(&target_qbit,
sizeof(
int), 1, pFile);
4222 sstream <<
"target_qbit: " << target_qbit << std::endl;
4224 gate_block_levels[current_level]->add_y(target_qbit);
4225 gate_block_level_gates_num[current_level]--;
4230 sstream <<
"importing Z gate" << std::endl;
4233 fread(&target_qbit,
sizeof(
int), 1, pFile);
4234 sstream <<
"target_qbit: " << target_qbit << std::endl;
4236 gate_block_levels[current_level]->add_z(target_qbit);
4237 gate_block_level_gates_num[current_level]--;
4242 sstream <<
"importing T gate" << std::endl;
4245 fread(&target_qbit,
sizeof(
int), 1, pFile);
4246 sstream <<
"target_qbit: " << target_qbit << std::endl;
4248 gate_block_levels[current_level]->add_t(target_qbit);
4249 gate_block_level_gates_num[current_level]--;
4254 sstream <<
"importing Tdg gate" << std::endl;
4257 fread(&target_qbit,
sizeof(
int), 1, pFile);
4258 sstream <<
"target_qbit: " << target_qbit << std::endl;
4260 gate_block_levels[current_level]->add_t(target_qbit);
4261 gate_block_level_gates_num[current_level]--;
4266 sstream <<
"importing SX gate" << std::endl;
4269 fread_status = fread(&target_qbit,
sizeof(
int), 1, pFile);
4270 sstream <<
"target_qbit: " << target_qbit << std::endl;
4272 gate_block_levels[current_level]->add_sx(target_qbit);
4273 gate_block_level_gates_num[current_level]--;
4279 sstream <<
"******* importing gates block ********" << std::endl;
4282 fread_status = fread(&qbit_num_loc,
sizeof(
int), 1, pFile);
4286 int parameter_num_loc;
4287 fread_status = fread(¶meter_num_loc,
sizeof(
int), 1, pFile);
4292 fread_status = fread(&gates_num_loc,
sizeof(
int), 1, pFile);
4295 gate_block_levels.push_back( gate_block_inner );
4296 gate_block_level_gates_num.push_back(gates_num_loc);
4301 sstream <<
"importing adaptive gate" << std::endl;
4304 fread_status = fread(&target_qbit,
sizeof(
int), 1, pFile);
4305 sstream <<
"target_qbit: " << target_qbit << std::endl;
4308 fread_status = fread(&control_qbit,
sizeof(
int), 1, pFile);
4309 sstream <<
"control_qbit: " << control_qbit << std::endl;
4311 fread_status = fread(parameters_data,
sizeof(
double), 1, pFile);
4314 gate_block_levels[current_level]->add_adaptive(target_qbit, control_qbit);
4315 gate_block_level_gates_num[current_level]--;
4319 std::string err(
"import_gate_list_from_binary: unimplemented gate");
4324 if ( gate_block_level_gates_num[current_level] == 0 ) {
4325 gate_block_levels[ current_level-1 ]->add_gate( static_cast<Gate*>(gate_block_levels[ current_level ]) );
4326 gate_block_levels.pop_back();
4327 gate_block_level_gates_num.pop_back();
4329 gate_block_level_gates_num[current_level]--;
4330 sstream <<
"finishing gates block" << std::endl;
4339 log.
print(sstream, 4);
4342 if ( iter == iter_max ) {
4343 std::string error(
"Corrupted input file, reached end of the file before contructing the whole gate structure");
4361 if ( parameters_in.
cols > 1 && parameters_in.
rows > 1 ) {
4362 std::string error(
"reverse_parameters: Input array should have a single column or a single row.");
4369 int parameters_num_total = 0;
4370 for (
int idx=0; idx<num_of_gates; idx++) {
4373 Gate* gate = *(gates_it++);
4379 if ( parameters_num_total == 0) {
4387 Matrix_real parameters_ret(1, parameters_num_total);
4388 int parameter_num_copied = 0;
4391 for (
int idx=num_of_gates-0; idx>0; idx--) {
4394 Gate* gate = *(--gates_it);
4398 if ( parameter_num_gate == 0 ) {
4407 Matrix_real parameters_of_block( parameters_in.
get_data()+parameters_num_total, 1, parameter_num_gate );
4412 std::vector<Gate*> gates_loc = block_gate->
get_gates();
4418 memcpy( parameters_ret.
get_data()+parameter_num_copied, parameters_of_block_reversed.
get_data(), parameters_of_block_reversed.
size()*
sizeof(double) );
4419 parameter_num_copied = parameter_num_copied + parameters_of_block_reversed.
size();
4441 return parameters_ret;
4459 if ( parameters_in.
cols > 1 && parameters_in.
rows > 1 ) {
4460 std::string error(
"reverse_parameters: Input array should have a single column or a single row.");
4466 int parameters_num_total = 0;
4467 for (
int idx=0; idx<num_of_gates; idx++) {
4470 Gate* gate = *(gates_it++);
4476 if ( parameters_num_total == 0) {
4484 Matrix_real parameters_ret(1, parameters_num_total);
4485 int parameter_num_copied = 0;
4488 for (
int idx=num_of_gates-0; idx>0; idx--) {
4491 Gate* gate = *(--gates_it);
4495 if ( parameter_num_gate == 0 ) {
4504 Matrix_real parameters_of_block( parameters_in.
get_data()+parameters_num_total, 1, parameter_num_gate );
4509 std::vector<Gate*> gates_loc = block_gate->
get_gates();
4515 memcpy( parameters_ret.
get_data()+parameter_num_copied, parameters_of_block_reversed.
get_data(), parameters_of_block_reversed.
size()*
sizeof(double) );
4516 parameter_num_copied = parameter_num_copied + parameters_of_block_reversed.
size();
4538 return parameters_ret;
Matrix calc_one_qubit_u3()
Set static values for matrix of the gates.
std::vector< Gate * > parents
list of parent gates to be applied in the circuit prior to this current gate
bool isnan()
Call to check the array for NaN entries.
Header file for a class representing the T gate.
Gates_block * get_flat_circuit()
Method to generate a flat circuit.
A class representing a U3 gate.
void add_adaptive(int target_qbit, int control_qbit)
Append a Adaptive gate to the list of gates.
A class representing a U3 gate.
virtual void apply_from_right(Matrix_real ¶meters, Matrix &input)
Call to apply the gate on the input array/matrix by input*U3.
Header file for a class representing a single qubit gate with custom gate kernel. ...
virtual void reorder_qubits(std::vector< int > qbit_list)
Call to reorder the qubits in the matrix of the operation.
void add_composite_to_front()
Add a Composite gate to the front of the list of gates.
int get_chained_gates_num()
Call to retrieve the number of gates that should be chained up during the execution of the DFE librar...
Base class for the representation of general gate operations.
void parameters_for_calc_one_qubit(double &ThetaOver2, double &Phi, double &Lambda)
Calculate the matrix of a U3 gate gate corresponding to the given parameters acting on a single qbit ...
void add_cz_nu(int target_qbit, int control_qbit)
Append a CZ_NU gate to the list of gates.
Matrix calc_one_qubit_u3()
Set static values for matrix of the gates.
void apply_to_list(Matrix_real ¶meters, std::vector< Matrix > &inputs, int parallel)
Call to apply the gate on the input array/matrix by U3*input.
void print(const std::stringstream &sstream, int verbose_level=1) const
Call to print output messages in the function of the verbosity level.
Header file for a class representing a rotation gate around the X axis.
void release_gate(int idx)
Call to release one gate in the list.
void determine_parents(Gate *gate)
Call to obtain the parent gates in the circuit.
void add_z_to_front(int target_qbit)
Add a Z gate to the front of the list of gates.
Header file for a class for a composite gate operation.
void add_child(Gate *child)
Call to add a child gate to the current gate.
void add_h(int target_qbit)
Append a Hadamard gate to the list of gates.
A class representing a U2 gate.
virtual Matrix get_matrix()
Call to retrieve the operation matrix.
void clear_children()
Call to erase data on children.
A class representing a custom_kernel_1qubit_gate gate.
Header file for a class representing the X gate.
Matrix calc_one_qubit_u3()
Set static values for matrix of the gates.
std::map< std::string, int > get_gate_nums()
Call to get the number of the individual gate types in the list of gates.
Header file for a class representing the Y gate.
void add_x(int target_qbit)
Append a X gate to the list of gates.
void reorder_qubits(std::vector< int > qbit_list)
Call to reorder the qubits in the matrix of the gate.
int control_qbit
The index of the qubit which acts as a control qubit (control_qbit >= 0) in controlled operations...
virtual std::vector< Matrix > apply_derivate_to(Matrix_real ¶meters_mtx_in, Matrix &input, int parallel)
Call to evaluate the derivate of the circuit on an inout with respect to all of the free parameters...
Matrix calc_one_qubit_u3()
Set static values for matrix of the gates.
void add_cz_nu_to_front(int target_qbit, int control_qbit)
Add a CZ_NU gate to the front of the list of gates.
virtual Gate * clone()
Call to create a clone of the present class.
void add_gate(Gate *gate)
Append a general gate to the list of gates.
int stride
The column stride of the array. (The array elements in one row are a_0, a_1, ... a_{cols-1}, 0, 0, 0, 0. The number of zeros is stride-cols)
void set_children(std::vector< Gate *> &children_)
Call to set the children of the current gate.
void apply_from_right(Matrix_real ¶meters, Matrix &input)
Call to apply the gate on the input array/matrix by input*U3.
Header file for a class representing a controlled rotation gate around the Y axis.
void add_u2(int target_qbit)
Append a U2 gate to the list of gates.
virtual void set_qbit_num(int qbit_num_in)
Set the number of qubits spanning the matrix of the operation.
Header file for a class representing the SX axis.
std::vector< int > get_involved_qubits()
Call to get the qubits involved in the gates stored in the block of gates.
virtual void reorder_qubits(std::vector< int > qbit_list)
Call to reorder the qubits in the matrix of the operation.
void add_cnot_to_front(int target_qbit, int control_qbit)
Add a C_NOT gate gate to the front of the list of gates.
void parameters_for_calc_one_qubit(double &ThetaOver2, double &Phi, double &Lambda)
Calculate the matrix of a U3 gate gate corresponding to the given parameters acting on a single qbit ...
int max_fusion
maximal number of qubits in partitions
void add_u1(int target_qbit)
Append a U1 gate to the list of gates.
void add_on_to_front()
Add a OUN gate to the front of the list of gates.
Header file for a class representing a controlled rotation gate around the Y axis.
void apply_from_right(Matrix_real ¶meters, Matrix &input)
Call to apply the gate on the input array/matrix by input*CZ.
int target_qbit
The index of the qubit on which the operation acts (target_qbit >= 0)
Matrix_real reverse_parameters(const Matrix_real ¶meters_in, std::vector< Gate *>::iterator gates_it, int num_of_gates)
Call to reverse the order of the parameters in an array.
void apply_from_right(Matrix_real ¶meters, Matrix &input)
Call to apply the gate on the input array/matrix by input*Gate.
std::vector< Gate * > get_gates()
Call to get the gates stored in the class.
Gates_block * create_remapped_circuit(const std::map< int, int > &qbit_map)
Call to create a new circuit with remapped qubits.
void release_gates()
Call to release the stored gates.
virtual void reorder_qubits(std::vector< int > qbit_list)
Call to reorder the qubits in the matrix of the gates (Obsolete function)
std::vector< int > block_type
Header file for a class representing a CH operation.
void get_parameter_max(Matrix_real &range_max)
data
load the unitary from file
void add_r(int target_qbit)
Append a R gate to the list of gates.
std::vector< std::vector< int > > involved_qbits
Header file for a class responsible for grouping gates into subcircuits. (Subcircuits can be nested) ...
A class representing a U3 gate.
Header file for a class representing the Tdg gate.
int layer_num
number of gate layers
void add_cnot(int target_qbit, int control_qbit)
Append a CNOT gate gate to the list of gates.
QGD_Complex16 mult(QGD_Complex16 &a, QGD_Complex16 &b)
Call to calculate the product of two complex scalars.
A class representing a U3 gate.
Matrix calc_one_qubit_u3()
Set static values for matrix of the gates.
bool fragmented
boolean variable indicating whether the circuit was already partitioned or not
void add_cz_to_front(int target_qbit, int control_qbit)
Add a CZ gate gate to the front of the list of gates.
virtual void apply_to(Matrix_real ¶meters_mtx, Matrix &input, int parallel=0)
Call to apply the gate on the input array/matrix Gates_block*input.
int matrix_size
The size N of the NxN matrix associated with the operations.
scalar * get_data() const
Call to get the pointer to the stored data.
void add_crot(int target_qbit, int control_qbit, crot_type subtype_in)
Append a CNOT gate gate to the list of gates.
void add_rz_to_front(int target_qbit)
Add a RZ gate to the front of the list of gates.
void add_r_to_front(int target_qbit)
Add a R gate to the front of the list of gates.
void add_un_to_front()
Add a UN gate to the front of the list of gates.
Gates_block * import_gate_list_from_binary(Matrix_real ¶meters, const std::string &filename, int verbosity)
?????????
int get_gate_num()
Call to get the number of gates grouped in the class.
void add_h_to_front(int target_qbit)
Add a Hadamard gate to the front of the list of gates.
virtual void reorder_qubits(std::vector< int > qbit_list)
Call to reorder the qubits in the matrix of the gate.
std::vector< Gate * > gates
The list of stored gates.
A class representing a CROT gate.
void add_x_to_front(int target_qbit)
Add a X gate to the front of the list of gates.
void add_sx_to_front(int target_qbit)
Add a SX gate to the front of the list of gates.
void apply_from_right(Matrix_real ¶meters, Matrix &input)
Call to apply the gate on the input array/matrix by input*Gate.
A class representing a CZ operation.
Header file for a class representing a CNOT operation.
std::vector< int > block_end
A class containing basic methods for setting up the verbosity level.
void apply_from_right(Matrix_real ¶meters, Matrix &input)
Call to apply the gate on the input array/matrix by input*U3.
Matrix calc_one_qubit_u3()
Set static values for matrix of the gates.
void reorder_qubits(std::vector< int > qbit_list)
Call to reorder the qubits in the matrix of the gate.
virtual void reorder_qubits(std::vector< int > qbit_list)
Call to reorder the qubits in the matrix of the gate.
void add_y_to_front(int target_qbit)
Add a Y gate to the front of the list of gates.
A class representing a U3 gate.
void add_syc(int target_qbit, int control_qbit)
Append a Sycamore gate (i.e.
A class representing a RZ gate.
gate_type type
The type of the operation (see enumeration gate_type)
int get_parameter_num()
Call to get the number of free parameters.
double get_second_Renyi_entropy(Matrix_real ¶meters_mtx, Matrix &input_state, matrix_base< int > &qbit_list)
Call to evaluate the seconf Rényi entropy.
void add_syc_to_front(int target_qbit, int control_qbit)
Add a Sycamore gate (i.e.
virtual void apply_from_right(Matrix_real ¶meters, Matrix &input)
Call to apply the gate on the input array/matrix by input*U3.
void add_ch(int target_qbit, int control_qbit)
Append a CH gate (i.e.
A class representing a CRY gate.
virtual void apply_from_right(Matrix &input)
Call to apply the gate on the input array/matrix by input*Gate.
int rows
The number of rows.
A class representing a CH operation.
int cols
The number of columns.
Header file for a class representing a rotation gate around the Z axis.
void add_ch_to_front(int target_qbit, int control_qbit)
Add a CH gate (i.e.
void reorder_qubits(std::vector< int > qbit_list)
Call to reorder the qubits in the matrix of the operation.
void add_composite()
Append a Composite gate to the list of gates.
Header file for a class representing the Hadamard gate.
virtual Matrix calc_one_qubit_u3(double Theta, double Phi, double Lambda)
Calculate the matrix of a U3 gate gate corresponding to the given parameters acting on a single qbit ...
void add_u2_to_front(int target_qbit)
Add a U2 gate to the front of the list of gates.
gate_type get_type()
Call to get the type of the operation.
virtual void reorder_qubits(std::vector< int > qbit_list)
Call to reorder the qubits in the matrix of the operation.
void add_u3(int target_qbit)
Append a U3 gate to the list of gates.
void reorder_qubits(std::vector< int > qbit_list)
Call to reorder the qubits in the matrix of the gate.
void add_rz(int target_qbit)
Append a RZ gate to the list of gates.
Header file for a class for the representation of general gate operations on the first qbit_num-1 qub...
void apply_to(Matrix &input)
Call to apply the gate on the input array/matrix by U3*input.
void add_y(int target_qbit)
Append a Y gate to the list of gates.
void reset_dependency_graph()
Method to reset the dependency graph of the gates in the circuit.
void combine(Gates_block *op_block)
Call to append the gates of an gate block to the current block.
void add_ry(int target_qbit)
Append a RY gate to the list of gates.
void set_control_qbit(int control_qbit_in)
Call to set the control qubit for the gate operation.
void set_parameter_start_idx(int start_idx)
Call to set the starting index of the parameters in the parameter array corresponding to the circuit ...
void reorder_qubits(std::vector< int > qbit_list)
Call to reorder the qubits in the matrix of the gate.
Header file for a class representing a CZ operation.
int get_parameter_start_idx()
Call to get the starting index of the parameters in the parameter array corresponding to the circuit ...
void add_parent(Gate *parent)
Call to add a parent gate to the current gate.
void apply_from_right(Matrix_real ¶meters, Matrix &input)
Call to apply the gate on the input array/matrix by input*U3.
void set_target_qbit(int target_qbit_in)
Call to set the target qubit for the gate operation.
void add_on()
Append a ON gate to the list of gates.
Structure type representing complex numbers in the SQUANDER package.
A class representing a CNOT operation.
int verbose
Set the verbosity level of the output messages.
virtual std::vector< Matrix > apply_derivate_to(Matrix_real ¶meters_mtx, Matrix &input, int parallel)
Call to evaluate the derivate of the circuit on an inout with respect to all of the free parameters...
virtual void apply_from_right(Matrix_real ¶meters, Matrix &input)
Call to apply the gate on the input array/matrix by input*CRY.
void clear_parents()
Call to erase data on parents.
void determine_children(Gate *gate)
Call to obtain the child gates in the circuit.
void add_u1_to_front(int target_qbit)
Add a U1 gate to the front of the list of gates.
int extract_gates(Gates_block *op_block)
Call to extract the gates stored in the class.
void add_cry_to_front(int target_qbit, int control_qbit)
Add a CRY gate to the front of the list of gates.
int Power_of_2(int n)
Calculates the n-th power of 2.
void reorder_qubits(std::vector< int > qbit_list)
Call to reorder the qubits in the matrix of the operation.
void add_crot_to_front(int target_qbit, int control_qbit, crot_type subtype_in)
Add a C_NOT gate gate to the front of the list of gates.
virtual Gates_block * clone()
Create a clone of the present class.
void apply_from_right(Matrix_real ¶meters, Matrix &input)
Call to apply the gate on the input array/matrix by input*U3.
virtual void apply_from_right(Matrix_real ¶meters_mtx, Matrix &input)
Call to apply the gate on the input array/matrix by input*CNOT.
bool contains_adaptive_gate()
Call to determine, whether the circuit contains daptive gate or not.
Class to store data of complex arrays and its properties.
void add_gates_to_front(std::vector< Gate *> gates_in)
Add an array of gates to the front of the list of gates.
void add_gate_to_front(Gate *gate)
Add an gate to the front of the list of gates.
A class representing a Hadamard gate.
A class representing a U3 gate.
void add_z(int target_qbit)
Append a Z gate to the list of gates.
Header file for a class representing a U2 gate.
Header file for a class representing a gate used in adaptive decomposition.
A class representing a U3 gate.
int size() const
Call to get the number of the allocated elements.
void add_cry(int target_qbit, int control_qbit)
Append a CRY gate to the list of gates.
void reorder_qubits(std::vector< int > qbit_list)
Call to reorder the qubits in the matrix of the gate.
Gates_block()
Default constructor of the class.
void add_rx_to_front(int target_qbit)
Add a RX gate to the front of the list of gates.
int get_parameter_num()
Call to get the number of free parameters.
void add_tdg_to_front(int target_qbit)
Add a Tdg gate to the front of the list of gates.
A class responsible for grouping two-qubit (CNOT,CZ,CH) and one-qubit gates into layers.
Header file for a class representing a U3 gate.
void add_tdg(int target_qbit)
Append a Tdg gate to the list of gates.
A class representing a CZ operation.
void add_u3_to_front(int target_qbit)
Add a U3 gate to the front of the list of gates.
Matrix calc_one_qubit_u3()
Set static values for matrix of the gates.
std::string name
A string labeling the gate operation.
void add_cz(int target_qbit, int control_qbit)
Append a CZ gate gate to the list of gates.
A class representing a U3 gate.
std::vector< Gate * > children
list of child gates to be applied after this current gate
Fixed point data related to a gate operation.
bool is_qbit_present(std::vector< int > involved_qubits, int new_qbit, int num_of_qbits)
Call to check whether the given qubit is involved in the sub-circuit or not.
int get_target_qbit()
Call to get the index of the target qubit.
std::vector< int > remove_list_intersection(std::vector< int > &list1, std::vector< int > &list2)
Call to remove those integer elements from list1 which are present in list.
Header file for a class representing a rotation gate around the X axis.
Base class for the representation of general gate operations.
Base class for the representation of general gate operations.
Header file for a class representing a rotation gate around the Y axis.
std::string get_name()
Call to get the name label of the gate.
virtual std::vector< int > get_involved_qubits()
Call to get the qubits involved in the gate operation.
Matrix create_identity(int matrix_size)
Call to create an identity matrix.
void add_gate_nums(std::map< std::string, int > &gate_nums)
Call to add the number of the individual gate types in the circuit to the map given in the argument...
int get_limit()
???????????
void add_ry_to_front(int target_qbit)
Add a RY gate to the front of the list of gates.
int parameter_num
the number of free parameters of the operation
virtual ~Gates_block()
Destructor of the class.
virtual void apply_to_list(std::vector< Matrix > &inputs, int parallel)
Call to apply the gate on a list of inputs.
void add_rx(int target_qbit)
Append a RX gate to the list of gates.
void apply_from_right(Matrix_real ¶meters, Matrix &input)
Call to apply the gate on the input array/matrix by input*Gate.
Matrix calc_one_qubit_u3(double PhiOver2)
Calculate the matrix of a U3 gate gate corresponding to the given parameters acting on a single qbit ...
void apply_from_right(Matrix_real ¶meters, Matrix &input)
Call to apply the gate on the input array/matrix by input*U3.
void reorder_qubits(std::vector< int > qbit_list)
Call to reorder the qubits in the matrix of the operation.
void set_parents(std::vector< Gate *> &parents_)
Call to set the parents of the current gate.
double activation_function(double Phi, int limit)
?????
void add_un()
Append a UN gate to the list of gates.
void export_gate_list_to_binary(Matrix_real ¶meters, Gates_block *gates_block, const std::string &filename, int verbosity)
?????????
Matrix copy()
Call to create a copy of the matrix.
A class representing a SYC operation.
void insert_gate(Gate *gate, int idx)
Call to insert a gate at a given position.
void add_unique_elelement(std::vector< int > &involved_qbits, int qbit)
Add an integer to a vector of integers if the integer is not already an element of the vector...
double real
the real part of a complex number
virtual Matrix_real extract_parameters(Matrix_real ¶meters)
Call to extract parameters from the parameter array corresponding to the circuit, in which the gate i...
void reset_parameter_start_indices()
Method to reset the parameter start indices of gate operations incorporated in the circuit...
A class representing a CRY gate.
Header file for a class representing the Z gate.
int qbit_num
number of qubits spanning the matrix of the operation
Header file for a class for the representation of general gate operations on the first qbit_num-1 qub...
void add_t_to_front(int target_qbit)
Add a T gate to the front of the list of gates.
A class representing a U3 gate.
int get_qbit_num()
Call to get the number of qubits composing the unitary.
gate_type
Type definition of operation types (also generalized for decomposition classes derived from the class...
A class representing a U3 gate.
Gate * get_gate(int idx)
Call to get the gates stored in the class.
Base class for the representation of general gate operations.
A class representing a U3 gate.
virtual void apply_to(Matrix &input, int parallel)
Call to apply the gate on the input array/matrix.
void list_gates(const Matrix_real ¶meters, int start_index)
Call to print the list of gates stored in the block of gates for a specific set of parameters...
Matrix get_reduced_density_matrix(Matrix_real ¶meters_mtx, Matrix &input_state, matrix_base< int > &qbit_list_subset)
Call to evaluate the reduced densiy matrix.
void add_adaptive_to_front(int target_qbit, int control_qbit)
Add a Adaptive gate to the front of the list of gates.
virtual void reorder_qubits(std::vector< int > qbit_list)
Call to reorder the qubits in the matrix of the operation.
void add_gates(std::vector< Gate *> gates_in)
Append a list of gates to the list of gates.
Header file for a class representing a U1 gate.
Matrix_real inverse_reverse_parameters(const Matrix_real ¶meters_in, std::vector< Gate *>::iterator gates_it, int num_of_gates)
Call to inverse-reverse the order of the parameters in an array.
void add_t(int target_qbit)
Append a T gate to the list of gates.
Matrix calc_one_qubit_u3()
Set static values for matrix of the gates.
int get_control_qbit()
Call to get the index of the control qubit.
Class to store data of complex arrays and its properties.
void reorder_qubits(std::vector< int > qbit_list)
Call to reorder the qubits in the matrix of the gate.
double imag
the imaginary part of a complex number
void add_sx(int target_qbit)
Append a SX gate to the list of gates.
virtual void set_qbit_num(int qbit_num_in)
Set the number of qubits spanning the matrix of the gates stored in the block of gates.
void apply_from_right(Matrix_real ¶meters, Matrix &input)
Call to apply the gate on the input array/matrix by input*U2.
Header file for a class representing a Sycamore gate.
void reorder_qubits(std::vector< int > qbit_list)
Call to reorder the qubits in the matrix of the gate.