27 #define PY_SSIZE_T_CLEAN 31 #include <numpy/arrayobject.h> 32 #include "structmember.h" 90 if (instance != NULL ) {
113 if ( self->decomp != NULL ) {
120 if ( self->Umtx != NULL ) {
122 Py_DECREF(self->Umtx);
126 Py_TYPE(
self)->tp_free((PyObject *)
self);
146 return (PyObject *)
self;
160 static char *kwlist[] = {(
char*)
"Umtx", (
char*)
"qbit_num", (
char*)
"level_limit_min", (
char*)
"method", (
char*)
"topology", (
char*)
"config", (
char*)
"accelerator_num", NULL};
163 PyArrayObject *Umtx_arg = NULL;
164 PyObject *config_arg = NULL;
167 int level_limit_min = 0;
169 int accelerator_num = 0;
172 if (!PyArg_ParseTupleAndKeywords(args, kwds,
"|OiiiOOi", kwlist,
173 &Umtx_arg, &qbit_num, &level_limit, &level_limit_min, &topology, &config_arg, &accelerator_num))
177 if ( Umtx_arg == NULL )
return -1;
178 self->Umtx = (PyArrayObject*)PyArray_FROM_OTF( (PyObject*) Umtx_arg, NPY_COMPLEX128, NPY_ARRAY_IN_ARRAY);
181 if ( !PyArray_IS_C_CONTIGUOUS(self->Umtx) ) {
182 std::cout <<
"Umtx is not memory contiguous" << std::endl;
190 bool is_None = topology == Py_None;
191 bool is_list = PyList_Check(topology);
194 if (!is_list && !is_None) {
195 printf(
"Input topology must be a list!\n");
200 std::vector<matrix_base<int>> topology_Cpp;
205 Py_ssize_t element_num = PyList_GET_SIZE(topology);
207 for ( Py_ssize_t idx=0; idx<element_num; idx++ ) {
208 PyObject *item = PyList_GetItem(topology, idx );
211 if (!PyTuple_Check(item)) {
212 printf(
"Elements of topology must be a tuple!\n");
217 item_Cpp[0] = (
int) PyLong_AsLong( PyTuple_GetItem(item, 0 ) );
218 item_Cpp[1] = (
int) PyLong_AsLong( PyTuple_GetItem(item, 1 ) );
220 topology_Cpp.push_back( item_Cpp );
227 bool is_dict = PyDict_Check( config_arg );
229 printf(
"Config object must be a python dictionary!\n");
234 std::map<std::string, Config_Element>
config;
238 PyObject *key, *value;
241 while (PyDict_Next(config_arg, &pos, &key, &value)) {
244 PyObject* key_string = PyObject_Str(key);
245 PyObject* key_string_unicode = PyUnicode_AsEncodedString(key_string,
"utf-8",
"~E~");
246 const char* key_C = PyBytes_AS_STRING(key_string_unicode);
248 std::string key_Cpp( key_C );
251 if ( PyLong_Check( value ) ) {
252 element.
set_property( key_Cpp, PyLong_AsLongLong( value ) );
253 config[ key_Cpp ] = element;
255 else if ( PyFloat_Check( value ) ) {
256 element.
set_property( key_Cpp, PyFloat_AsDouble( value ) );
257 config[ key_Cpp ] = element;
271 catch (std::string err ) {
272 PyErr_SetString(PyExc_Exception, err.c_str());
277 std::cout <<
"The number of qubits should be given as a positive integer, " << qbit_num <<
" was given" << std::endl;
296 static char *kwlist[] = {NULL};
300 if (!PyArg_ParseTupleAndKeywords(args, kwds,
"|", kwlist))
301 return Py_BuildValue(
"i", -1);
305 self->decomp->start_decomposition();
307 catch (std::string err) {
308 PyErr_SetString(PyExc_Exception, err.c_str());
309 std::cout << err << std::endl;
313 std::string err(
"Invalid pointer to decomposition class");
314 PyErr_SetString(PyExc_Exception, err.c_str());
320 return Py_BuildValue(
"i", 0);
330 self->decomp->get_initial_circuit();
332 catch (std::string err) {
333 PyErr_SetString(PyExc_Exception, err.c_str());
334 std::cout << err << std::endl;
338 std::string err(
"Invalid pointer to decomposition class");
339 PyErr_SetString(PyExc_Exception, err.c_str());
345 return Py_BuildValue(
"i", 0);
355 self->decomp->compress_circuit();
357 catch (std::string err) {
358 PyErr_SetString(PyExc_Exception, err.c_str());
359 std::cout << err << std::endl;
363 std::string err(
"Invalid pointer to decomposition class");
364 PyErr_SetString(PyExc_Exception, err.c_str());
370 return Py_BuildValue(
"i", 0);
379 static char *kwlist[] = {NULL};
383 if (!PyArg_ParseTupleAndKeywords(args, kwds,
"|", kwlist))
384 return Py_BuildValue(
"i", -1);
388 self->decomp->finalize_circuit();
390 catch (std::string err) {
391 PyErr_SetString(PyExc_Exception, err.c_str());
392 std::cout << err << std::endl;
396 std::string err(
"Invalid pointer to decomposition class");
397 PyErr_SetString(PyExc_Exception, err.c_str());
403 return Py_BuildValue(
"i", 0);
416 int ret =
self->decomp->get_gate_num();
419 return Py_BuildValue(
"i", ret);
436 QGD_Complex16 global_phase_factor_C =
self->decomp->get_global_phase_factor();
437 PyObject* global_phase = PyFloat_FromDouble( std::atan2(global_phase_factor_C.
imag,global_phase_factor_C.
real));
450 double new_global_phase;
451 if (!PyArg_ParseTuple(args,
"|d", &new_global_phase ))
return Py_BuildValue(
"i", -1);
452 self->decomp->set_global_phase(new_global_phase);
454 return Py_BuildValue(
"i", 0);
465 self->decomp->apply_global_phase_factor();
467 return Py_BuildValue(
"i", 0);
480 PyObject* qgd_Circuit = PyImport_ImportModule(
"squander.gates.qgd_Circuit");
482 if ( qgd_Circuit == NULL ) {
483 PyErr_SetString(PyExc_Exception,
"Module import error: squander.gates.qgd_Circuit" );
493 PyObject* qgd_circuit_Dict = PyModule_GetDict( qgd_Circuit );
496 PyObject* py_circuit_class = PyDict_GetItemString( qgd_circuit_Dict,
"qgd_Circuit");
500 PyObject* circuit_input = Py_BuildValue(
"(O)", qbit_num);
502 PyObject* py_circuit = PyObject_CallObject(py_circuit_class, circuit_input);
508 delete( py_circuit_C->
gate );
525 self->decomp->list_gates( 0 );
543 self->decomp->get_optimized_parameters(parameters);
549 return parameter_arr;
564 return Py_BuildValue(
"i", parameter_num);
573 int number_of_iters =
self->decomp->get_num_iters();
575 return Py_BuildValue(
"i", number_of_iters);
586 PyArrayObject* parameters_arr = NULL;
590 if (!PyArg_ParseTuple(args,
"|O", ¶meters_arr ))
591 return Py_BuildValue(
"i", -1);
594 if ( PyArray_IS_C_CONTIGUOUS(parameters_arr) ) {
595 Py_INCREF(parameters_arr);
598 parameters_arr = (PyArrayObject*)PyArray_FROM_OTF( (PyObject*)parameters_arr, NPY_DOUBLE, NPY_ARRAY_IN_ARRAY);
605 self->decomp->set_optimized_parameters(parameters_mtx.
get_data(), parameters_mtx.
size());
607 catch (std::string err ) {
608 PyErr_SetString(PyExc_Exception, err.c_str());
612 std::string err(
"Invalid pointer to decomposition class");
613 PyErr_SetString(PyExc_Exception, err.c_str());
619 Py_DECREF(parameters_arr);
621 return Py_BuildValue(
"i", 0);
636 PyObject* max_layer_num;
639 if (!PyArg_ParseTuple(args,
"|O", &max_layer_num ))
return Py_BuildValue(
"i", -1);
642 if (!PyDict_Check(max_layer_num)) {
643 printf(
"Input must be dictionary!\n");
644 return Py_BuildValue(
"i", -1);
648 PyObject* key = NULL;
649 PyObject* value = NULL;
653 while (PyDict_Next(max_layer_num, &pos, &key, &value)) {
656 assert(PyLong_Check(value) == 1);
657 int value_int = (
int) PyLong_AsLong(value);
660 assert(PyLong_Check(key) == 1);
661 int key_int = (
int) PyLong_AsLong(key);
664 self->decomp->set_max_layer_num( key_int, value_int );
668 return Py_BuildValue(
"i", 0);
686 PyObject* iteration_loops;
689 if (!PyArg_ParseTuple(args,
"|O", &iteration_loops ))
return Py_BuildValue(
"i", -1);
692 if (!PyDict_Check(iteration_loops)) {
693 printf(
"Input must be dictionary!\n");
694 return Py_BuildValue(
"i", -1);
698 PyObject* key = NULL;
699 PyObject* value = NULL;
703 while (PyDict_Next(iteration_loops, &pos, &key, &value)) {
706 assert(PyLong_Check(value) == 1);
707 int value_int = (
int) PyLong_AsLong(value);
710 assert(PyLong_Check(key) == 1);
711 int key_int = (
int) PyLong_AsLong(key);
714 self->decomp->set_iteration_loops( key_int, value_int );
718 return Py_BuildValue(
"i", 0);
733 if (!PyArg_ParseTuple(args,
"|i", &max_iters_input ))
return Py_BuildValue(
"i", -1);
737 self->decomp->set_max_inner_iterations(max_iters_input);
740 return Py_BuildValue(
"i", 0);
756 if (!PyArg_ParseTuple(args,
"|i", &verbose ))
return Py_BuildValue(
"i", -1);
760 self->decomp->set_verbose( verbose );
763 return Py_BuildValue(
"i", 0);
777 PyObject *debugfile = NULL;
780 if (!PyArg_ParseTuple(args,
"|O", &debugfile ))
return Py_BuildValue(
"s", -1);
783 PyObject* debugfile_string = PyObject_Str(debugfile);
784 PyObject* debugfile_string_unicode = PyUnicode_AsEncodedString(debugfile_string,
"utf-8",
"~E~");
785 const char* debugfile_C = PyBytes_AS_STRING(debugfile_string_unicode);
788 Py_XDECREF(debugfile_string);
789 Py_XDECREF(debugfile_string_unicode);
792 Py_ssize_t string_length = PyBytes_Size(debugfile_string_unicode);
793 std::string debugfile_Cpp(debugfile_C, string_length);
796 self->decomp->set_debugfile( debugfile_Cpp );
799 return Py_BuildValue(
"s", NULL);
817 if (!PyArg_ParseTuple(args,
"|d", &tolerance ))
return Py_BuildValue(
"i", -1);
821 self->decomp->set_optimization_tolerance( tolerance );
824 return Py_BuildValue(
"i", 0);
842 if (!PyArg_ParseTuple(args,
"|d", &threshold ))
return Py_BuildValue(
"i", -1);
846 self->decomp->set_convergence_threshold( threshold );
848 return Py_BuildValue(
"i", 0);
862 double optimization_block;
865 if (!PyArg_ParseTuple(args,
"|d", &optimization_block ))
return Py_BuildValue(
"i", -1);
869 self->decomp->set_optimization_blocks( optimization_block );
872 return Py_BuildValue(
"i", 0);
886 PyObject* gate_structure_py;
889 if (!PyArg_ParseTuple(args,
"|O", &gate_structure_py ))
return Py_BuildValue(
"i", -1);
896 self->decomp->set_custom_gate_structure( qgd_op_block->
gate );
898 catch (std::string err ) {
899 PyErr_SetString(PyExc_Exception, err.c_str());
903 std::string err(
"Invalid pointer to decomposition class");
904 PyErr_SetString(PyExc_Exception, err.c_str());
909 return Py_BuildValue(
"i", 0);
925 PyObject* filename_py=NULL;
928 if (!PyArg_ParseTuple(args,
"|O", &filename_py ))
return Py_BuildValue(
"i", -1);
931 PyObject* filename_string = PyObject_Str(filename_py);
932 PyObject* filename_string_unicode = PyUnicode_AsEncodedString(filename_string,
"utf-8",
"~E~");
933 const char* filename_C = PyBytes_AS_STRING(filename_string_unicode);
934 std::string filename_str( filename_C );
938 self->decomp->add_adaptive_gate_structure( filename_str );
940 catch (std::string err ) {
941 PyErr_SetString(PyExc_Exception, err.c_str());
945 std::string err(
"Invalid pointer to decomposition class");
946 PyErr_SetString(PyExc_Exception, err.c_str());
951 return Py_BuildValue(
"i", 0);
966 PyObject* filename_py=NULL;
969 if (!PyArg_ParseTuple(args,
"|O", &filename_py ))
return Py_BuildValue(
"i", -1);
972 PyObject* filename_string = PyObject_Str(filename_py);
973 PyObject* filename_string_unicode = PyUnicode_AsEncodedString(filename_string,
"utf-8",
"~E~");
974 const char* filename_C = PyBytes_AS_STRING(filename_string_unicode);
975 std::string filename_str( filename_C );
979 self->decomp->set_adaptive_gate_structure( filename_str );
981 catch (std::string err ) {
982 PyErr_SetString(PyExc_Exception, err.c_str());
986 std::string err(
"Invalid pointer to decomposition class");
987 PyErr_SetString(PyExc_Exception, err.c_str());
993 return Py_BuildValue(
"i", 0);
1000 PyObject* filename_py=NULL;
1003 if (!PyArg_ParseTuple(args,
"|O", &filename_py ))
return Py_BuildValue(
"i", -1);
1005 PyObject* filename_string = PyObject_Str(filename_py);
1006 PyObject* filename_string_unicode = PyUnicode_AsEncodedString(filename_string,
"utf-8",
"~E~");
1007 const char* filename_C = PyBytes_AS_STRING(filename_string_unicode);
1008 std::string filename_str( filename_C );
1012 self->decomp->set_unitary_from_file( filename_str );
1014 catch (std::string err ) {
1015 PyErr_SetString(PyExc_Exception, err.c_str());
1019 std::string err(
"Invalid pointer to decomposition class");
1020 PyErr_SetString(PyExc_Exception, err.c_str());
1025 return Py_BuildValue(
"i", 0);
1036 self->decomp->add_finalyzing_layer();
1038 catch (std::string err ) {
1039 PyErr_SetString(PyExc_Exception, err.c_str());
1043 std::string err(
"Invalid pointer to decomposition class");
1044 PyErr_SetString(PyExc_Exception, err.c_str());
1050 return Py_BuildValue(
"i", 0);
1065 self->decomp->apply_imported_gate_structure();
1067 catch (std::string err ) {
1068 PyErr_SetString(PyExc_Exception, err.c_str());
1072 std::string err(
"Invalid pointer to decomposition class");
1073 PyErr_SetString(PyExc_Exception, err.c_str());
1080 return Py_BuildValue(
"i", 0);
1092 std::string
project_name =
self->decomp->get_project_name();
1095 PyObject* project_name_pyhton = PyUnicode_FromString(project_name.c_str());
1097 return project_name_pyhton;
1107 PyObject* project_name_new=NULL;
1110 if (!PyArg_ParseTuple(args,
"|O", &project_name_new))
return Py_BuildValue(
"i", -1);
1113 PyObject* project_name_new_string = PyObject_Str(project_name_new);
1114 PyObject* project_name_new_unicode = PyUnicode_AsEncodedString(project_name_new_string,
"utf-8",
"~E~");
1115 const char* project_name_new_C = PyBytes_AS_STRING(project_name_new_unicode);
1116 std::string project_name_new_str = ( project_name_new_C );
1119 self->decomp->set_project_name(project_name_new_str);
1121 return Py_BuildValue(
"i", 0);
1136 return Py_BuildValue(
"d", decomposition_error);
1149 if (!PyArg_ParseTuple(args,
"|O", &filename))
return Py_BuildValue(
"i", -1);
1152 PyObject* filename_string = PyObject_Str(filename);
1153 PyObject* filename_unicode = PyUnicode_AsEncodedString(filename_string,
"utf-8",
"~E~");
1154 const char* filename_C = PyBytes_AS_STRING(filename_unicode);
1155 std::string filename_str = ( filename_C );
1158 self->decomp->export_unitary(filename_str);
1160 return Py_BuildValue(
"i", 0);
1174 Unitary_mtx =
self->decomp->get_Umtx().
copy();
1176 catch (std::string err ) {
1177 PyErr_SetString(PyExc_Exception, err.c_str());
1181 std::string err(
"Invalid pointer to decomposition class");
1182 PyErr_SetString(PyExc_Exception, err.c_str());
1204 PyArrayObject* parameters_arg = NULL;
1208 if (!PyArg_ParseTuple(args,
"|O", ¶meters_arg )) {
1210 std::string err(
"Unsuccessful argument parsing not ");
1211 PyErr_SetString(PyExc_Exception, err.c_str());
1217 if ( PyArray_IS_C_CONTIGUOUS(parameters_arg) && PyArray_TYPE(parameters_arg) == NPY_FLOAT64 ){
1218 Py_INCREF(parameters_arg);
1220 else if (PyArray_TYPE(parameters_arg) == NPY_FLOAT64 ) {
1221 parameters_arg = (PyArrayObject*)PyArray_FROM_OTF( (PyObject*)parameters_arg, NPY_FLOAT64, NPY_ARRAY_IN_ARRAY);
1224 std::string err(
"Parameters should be should be real (given in float64 format)");
1225 PyErr_SetString(PyExc_Exception, err.c_str());
1234 f0 =
self->decomp->optimization_problem(parameters_mtx );
1236 catch (std::string err ) {
1237 PyErr_SetString(PyExc_Exception, err.c_str());
1241 std::string err(
"Invalid pointer to decomposition class");
1242 PyErr_SetString(PyExc_Exception, err.c_str());
1246 Py_DECREF(parameters_arg);
1249 return Py_BuildValue(
"d", f0);
1262 PyArrayObject* parameters_arg = NULL;
1266 if (!PyArg_ParseTuple(args,
"|O", ¶meters_arg )) {
1268 std::string err(
"Unsuccessful argument parsing not ");
1269 PyErr_SetString(PyExc_Exception, err.c_str());
1275 if ( PyArray_IS_C_CONTIGUOUS(parameters_arg) && PyArray_TYPE(parameters_arg) == NPY_FLOAT64 ){
1276 Py_INCREF(parameters_arg);
1278 else if (PyArray_TYPE(parameters_arg) == NPY_FLOAT64 ) {
1279 parameters_arg = (PyArrayObject*)PyArray_FROM_OTF( (PyObject*)parameters_arg, NPY_FLOAT64, NPY_ARRAY_IN_ARRAY);
1282 std::string err(
"Parameters should be should be real (given in float64 format)");
1283 PyErr_SetString(PyExc_Exception, err.c_str());
1292 self->decomp->optimization_problem_grad(parameters_mtx, self->decomp, grad_mtx );
1294 catch (std::string err ) {
1295 PyErr_SetString(PyExc_Exception, err.c_str());
1299 std::string err(
"Invalid pointer to decomposition class");
1300 PyErr_SetString(PyExc_Exception, err.c_str());
1305 grad_mtx.set_owner(
false);
1308 Py_DECREF(parameters_arg);
1323 PyArrayObject* parameters_arg = NULL;
1327 if (!PyArg_ParseTuple(args,
"|O", ¶meters_arg )) {
1329 std::string err(
"Unsuccessful argument parsing not ");
1330 PyErr_SetString(PyExc_Exception, err.c_str());
1336 if ( PyArray_IS_C_CONTIGUOUS(parameters_arg) && PyArray_TYPE(parameters_arg) == NPY_FLOAT64 ){
1337 Py_INCREF(parameters_arg);
1339 else if (PyArray_TYPE(parameters_arg) == NPY_FLOAT64 ) {
1340 parameters_arg = (PyArrayObject*)PyArray_FROM_OTF( (PyObject*)parameters_arg, NPY_FLOAT64, NPY_ARRAY_IN_ARRAY);
1343 std::string err(
"Parameters should be should be real (given in float64 format)");
1344 PyErr_SetString(PyExc_Exception, err.c_str());
1354 self->decomp->optimization_problem_combined(parameters_mtx, &f0, grad_mtx );
1356 catch (std::string err ) {
1357 PyErr_SetString(PyExc_Exception, err.c_str());
1361 std::string err(
"Invalid pointer to decomposition class");
1362 PyErr_SetString(PyExc_Exception, err.c_str());
1367 grad_mtx.set_owner(
false);
1370 Py_DECREF(parameters_arg);
1373 PyObject* p = Py_BuildValue(
"(dO)", f0, grad_py);
1387 PyArrayObject* parameters_arg = NULL;
1391 if (!PyArg_ParseTuple(args,
"|O", ¶meters_arg )) {
1393 std::string err(
"Unsuccessful argument parsing not ");
1394 PyErr_SetString(PyExc_Exception, err.c_str());
1400 if ( PyArray_IS_C_CONTIGUOUS(parameters_arg) && PyArray_TYPE(parameters_arg) == NPY_FLOAT64 ){
1401 Py_INCREF(parameters_arg);
1403 else if (PyArray_TYPE(parameters_arg) == NPY_FLOAT64 ) {
1404 parameters_arg = (PyArrayObject*)PyArray_FROM_OTF( (PyObject*)parameters_arg, NPY_FLOAT64, NPY_ARRAY_IN_ARRAY);
1407 std::string err(
"Parameters should be should be real (given in float64 format)");
1408 PyErr_SetString(PyExc_Exception, err.c_str());
1415 std::vector<Matrix> Umtx_deriv;
1418 self->decomp->optimization_problem_combined_unitary(parameters_mtx, Umtx, Umtx_deriv );
1420 catch (std::string err ) {
1421 PyErr_SetString(PyExc_Exception, err.c_str());
1425 std::string err(
"Invalid pointer to decomposition class");
1426 PyErr_SetString(PyExc_Exception, err.c_str());
1433 PyObject* graduni_py = PyList_New(Umtx_deriv.size());
1434 for (
size_t i = 0; i < Umtx_deriv.size(); i++) {
1435 Umtx_deriv[i].set_owner(
false);
1439 Py_DECREF(parameters_arg);
1442 PyObject* p = Py_BuildValue(
"(OO)", unitary_py, graduni_py);
1443 Py_DECREF(unitary_py); Py_DECREF(graduni_py);
1456 PyArrayObject* parameters_arg = NULL;
1460 if (!PyArg_ParseTuple(args,
"|O", ¶meters_arg )) {
1462 std::string err(
"Unsuccessful argument parsing not ");
1463 PyErr_SetString(PyExc_Exception, err.c_str());
1469 if ( PyArray_IS_C_CONTIGUOUS(parameters_arg) && PyArray_TYPE(parameters_arg) == NPY_FLOAT64 ){
1470 Py_INCREF(parameters_arg);
1472 else if (PyArray_TYPE(parameters_arg) == NPY_FLOAT64 ) {
1473 parameters_arg = (PyArrayObject*)PyArray_FROM_OTF( (PyObject*)parameters_arg, NPY_FLOAT64, NPY_ARRAY_IN_ARRAY);
1476 std::string err(
"Parameters should be should be real (given in float64 format)");
1477 PyErr_SetString(PyExc_Exception, err.c_str());
1486 std::vector<Matrix_real> parameters_vec;
1487 parameters_vec.resize(parameters_mtx.
rows);
1488 for(
int row_idx=0; row_idx<parameters_mtx.
rows; row_idx++ ) {
1491 result_mtx =
self->decomp->optimization_problem_batched( parameters_vec );
1493 catch (std::string err ) {
1494 PyErr_SetString(PyExc_Exception, err.c_str());
1498 std::string err(
"Invalid pointer to decomposition class");
1499 PyErr_SetString(PyExc_Exception, err.c_str());
1507 Py_DECREF(parameters_arg);
1518 if ( self->Umtx != NULL ) {
1520 Py_DECREF(self->Umtx);
1524 PyArrayObject *Umtx_arg = NULL;
1526 if (!PyArg_ParseTuple(args,
"|O", &Umtx_arg ))
return Py_BuildValue(
"i", -1);
1529 if ( Umtx_arg == NULL ) {
1530 PyErr_SetString(PyExc_Exception,
"Umtx argument in empty");
1534 self->Umtx = (PyArrayObject*)PyArray_FROM_OTF( (PyObject*)Umtx_arg, NPY_COMPLEX128, NPY_ARRAY_IN_ARRAY);
1537 if ( !PyArray_IS_C_CONTIGUOUS(self->Umtx) ) {
1538 std::cout <<
"Umtx is not memory contiguous" << std::endl;
1544 self->decomp->set_unitary(Umtx_mtx);
1546 return Py_BuildValue(
"i", 0);
1557 PyObject* qbit_list;
1560 if (!PyArg_ParseTuple(args,
"|O", &qbit_list ))
return Py_BuildValue(
"i", -1);
1562 bool is_tuple = PyTuple_Check(qbit_list);
1563 bool is_list = PyList_Check(qbit_list);
1566 if (!is_list && !is_tuple) {
1567 printf(
"Input must be tuple or list!\n");
1568 return Py_BuildValue(
"i", -1);
1572 Py_ssize_t element_num;
1575 element_num = PyTuple_GET_SIZE(qbit_list);
1578 element_num = PyList_GET_SIZE(qbit_list);
1583 std::vector<int> qbit_list_C( (
int) element_num);
1584 for ( Py_ssize_t idx=0; idx<element_num; idx++ ) {
1586 qbit_list_C[(
int) idx] = (
int) PyLong_AsLong( PyTuple_GetItem(qbit_list, idx ) );
1589 qbit_list_C[(
int) idx] = (
int) PyLong_AsLong( PyList_GetItem(qbit_list, idx ) );
1596 self->decomp->reorder_qubits( qbit_list_C );
1601 return Py_BuildValue(
"i", 0);
1614 self->decomp->add_adaptive_layers();
1617 return Py_BuildValue(
"i", 0);
1630 self->decomp->add_layer_to_imported_gate_structure();
1633 return Py_BuildValue(
"i", 0);
1647 PyArrayObject* parameters_arr = NULL;
1651 if (!PyArg_ParseTuple(args,
"|O", ¶meters_arr ))
1652 return Py_BuildValue(
"i", -1);
1655 if ( PyArray_IS_C_CONTIGUOUS(parameters_arr) ) {
1656 Py_INCREF(parameters_arr);
1659 parameters_arr = (PyArrayObject*)PyArray_FROM_OTF( (PyObject*)parameters_arr, NPY_DOUBLE, NPY_ARRAY_IN_ARRAY);
1669 unitary_mtx =
self->decomp->get_matrix( parameters_mtx );
1677 Py_DECREF(parameters_arr);
1694 static char *kwlist[] = {(
char*)
"optimizer", NULL};
1696 PyObject* optimizer_arg = NULL;
1700 if (!PyArg_ParseTupleAndKeywords(args, kwds,
"|O", kwlist, &optimizer_arg)) {
1702 std::string err(
"Unsuccessful argument parsing not ");
1703 PyErr_SetString(PyExc_Exception, err.c_str());
1709 if ( optimizer_arg == NULL ) {
1710 std::string err(
"optimizer argument not set");
1711 PyErr_SetString(PyExc_Exception, err.c_str());
1717 PyObject* optimizer_string = PyObject_Str(optimizer_arg);
1718 PyObject* optimizer_string_unicode = PyUnicode_AsEncodedString(optimizer_string,
"utf-8",
"~E~");
1719 const char* optimizer_C = PyBytes_AS_STRING(optimizer_string_unicode);
1722 if ( strcmp(
"bfgs", optimizer_C) == 0 || strcmp(
"BFGS", optimizer_C) == 0) {
1723 qgd_optimizer =
BFGS;
1725 else if ( strcmp(
"adam", optimizer_C)==0 || strcmp(
"ADAM", optimizer_C)==0) {
1726 qgd_optimizer =
ADAM;
1728 else if ( strcmp(
"grad_descend", optimizer_C)==0 || strcmp(
"GRAD_DESCEND", optimizer_C)==0) {
1731 else if ( strcmp(
"adam_batched", optimizer_C)==0 || strcmp(
"ADAM_BATCHED", optimizer_C)==0) {
1734 else if ( strcmp(
"bfgs2", optimizer_C)==0 || strcmp(
"BFGS2", optimizer_C)==0) {
1735 qgd_optimizer =
BFGS2;
1737 else if ( strcmp(
"agents", optimizer_C)==0 || strcmp(
"AGENTS", optimizer_C)==0) {
1740 else if ( strcmp(
"cosine", optimizer_C)==0 || strcmp(
"COSINE", optimizer_C)==0) {
1743 else if ( strcmp(
"grad_descend_phase_shift_rule", optimizer_C)==0 || strcmp(
"GRAD_DESCEND_PARAMETER_SHIFT_RULE", optimizer_C)==0) {
1746 else if ( strcmp(
"agents_combined", optimizer_C)==0 || strcmp(
"AGENTS_COMBINED", optimizer_C)==0) {
1749 else if ( strcmp(
"bayes_opt", optimizer_C)==0 || strcmp(
"BAYES_OPT", optimizer_C)==0) {
1753 std::cout <<
"Wrong optimizer: " << optimizer_C <<
". Using default: BFGS" << std::endl;
1754 qgd_optimizer =
BFGS;
1759 self->decomp->set_optimizer(qgd_optimizer);
1761 catch (std::string err) {
1762 PyErr_SetString(PyExc_Exception, err.c_str());
1763 std::cout << err << std::endl;
1767 std::string err(
"Invalid pointer to decomposition class");
1768 PyErr_SetString(PyExc_Exception, err.c_str());
1773 return Py_BuildValue(
"i", 0);
1789 static char *kwlist[] = {(
char*)
"costfnc", NULL};
1791 int costfnc_arg = 0;
1795 if (!PyArg_ParseTupleAndKeywords(args, kwds,
"|i", kwlist, &costfnc_arg)) {
1797 std::string err(
"Unsuccessful argument parsing");
1798 PyErr_SetString(PyExc_Exception, err.c_str());
1807 self->decomp->set_cost_function_variant(qgd_costfnc);
1809 catch (std::string err) {
1810 PyErr_SetString(PyExc_Exception, err.c_str());
1811 std::cout << err << std::endl;
1815 std::string err(
"Invalid pointer to decomposition class");
1816 PyErr_SetString(PyExc_Exception, err.c_str());
1821 return Py_BuildValue(
"i", 0);
1839 static char *kwlist[] = {(
char*)
"trace_offset", NULL};
1841 int trace_offset_arg = 0;
1845 if (!PyArg_ParseTupleAndKeywords(args, kwds,
"|i", kwlist, &trace_offset_arg)) {
1847 std::string err(
"Unsuccessful argument parsing");
1848 PyErr_SetString(PyExc_Exception, err.c_str());
1855 self->decomp->set_trace_offset(trace_offset_arg);
1857 catch (std::string err) {
1858 PyErr_SetString(PyExc_Exception, err.c_str());
1859 std::cout << err << std::endl;
1863 std::string err(
"Invalid pointer to decomposition class");
1864 PyErr_SetString(PyExc_Exception, err.c_str());
1869 return Py_BuildValue(
"i", 0);
1883 int trace_offset = 0;
1886 trace_offset =
self->decomp->get_trace_offset();
1888 catch (std::string err) {
1889 PyErr_SetString(PyExc_Exception, err.c_str());
1890 std::cout << err << std::endl;
1894 std::string err(
"Invalid pointer to decomposition class");
1895 PyErr_SetString(PyExc_Exception, err.c_str());
1900 return Py_BuildValue(
"i", trace_offset);
1916 self->decomp->upload_Umtx_to_DFE();
1918 catch (std::string err) {
1919 PyErr_SetString(PyExc_Exception, err.c_str());
1920 std::cout << err << std::endl;
1924 std::string err(
"Invalid pointer to decomposition class");
1925 PyErr_SetString(PyExc_Exception, err.c_str());
1931 return Py_BuildValue(
"i", 0);
1949 PyArrayObject * parameters_arr = NULL;
1950 PyArrayObject * input_state_arg = NULL;
1951 PyObject * qubit_list_arg = NULL;
1955 if (!PyArg_ParseTuple(args,
"|OOO", ¶meters_arr, &input_state_arg, &qubit_list_arg ))
1956 return Py_BuildValue(
"i", -1);
1959 if ( PyArray_IS_C_CONTIGUOUS(parameters_arr) ) {
1960 Py_INCREF(parameters_arr);
1963 parameters_arr = (PyArrayObject*)PyArray_FROM_OTF((PyObject*)parameters_arr, NPY_DOUBLE, NPY_ARRAY_IN_ARRAY);
1971 if ( input_state_arg == NULL ) {
1972 PyErr_SetString(PyExc_Exception,
"Input matrix was not given");
1976 PyArrayObject* input_state = (PyArrayObject*)PyArray_FROM_OTF((PyObject*)input_state_arg, NPY_COMPLEX128, NPY_ARRAY_IN_ARRAY);
1979 if ( !PyArray_IS_C_CONTIGUOUS(input_state) ) {
1980 PyErr_SetString(PyExc_Exception,
"input mtrix is not memory contiguous");
1990 if ( qubit_list_arg == NULL || (!PyList_Check( qubit_list_arg )) ) {
1991 PyErr_SetString(PyExc_Exception,
"qubit_list should be a list");
1995 Py_ssize_t reduced_qbit_num = PyList_Size( qubit_list_arg );
1998 for (
int idx=0; idx<reduced_qbit_num; idx++ ) {
2000 PyObject* item = PyList_GET_ITEM( qubit_list_arg, idx );
2001 qbit_list_mtx[idx] = (
int) PyLong_AsLong( item );
2010 entropy =
self->decomp->get_second_Renyi_entropy( parameters_mtx, input_state_mtx, qbit_list_mtx );
2012 catch (std::string err) {
2013 PyErr_SetString(PyExc_Exception, err.c_str());
2014 std::cout << err << std::endl;
2018 std::string err(
"Invalid pointer to decomposition class");
2019 PyErr_SetString(PyExc_Exception, err.c_str());
2024 Py_DECREF(parameters_arr);
2025 Py_DECREF(input_state);
2029 PyObject* p = Py_BuildValue(
"d", entropy);
2044 qbit_num =
self->decomp->get_qbit_num();
2046 catch (std::string err) {
2047 PyErr_SetString(PyExc_Exception, err.c_str());
2048 std::cout << err << std::endl;
2052 std::string err(
"Invalid pointer to decomposition class");
2053 PyErr_SetString(PyExc_Exception, err.c_str());
2058 return Py_BuildValue(
"i", qbit_num );
2076 "Method to start the decomposition." 2079 "Method to get initial circuit in decomposition." 2082 "Method to compress gate structure." 2085 "Method to finalize the decomposition." 2088 "Method to get the number of decomposing gates." 2091 "Call to get the number of free parameters in the gate structure used for the decomposition" 2094 "Method to get the array of optimized parameters." 2097 "Method to set the initial array of optimized parameters." 2100 "Method to get the incorporated circuit." 2103 "Call to print the decomposing nitaries on standard output" 2106 "Method to get the number of iterations." 2109 "Call to set the maximal number of layers used in the subdecomposition of the qbit-th qubit." 2112 "Call to set the number of iteration loops during the subdecomposition of the qbit-th qubit." 2115 "Call to set the verbosity of the qgd_N_Qubit_Decomposition class." 2118 "Set the debugfile name of the N_Qubit_Decomposition class." 2121 "Call to set adaptive custom gate structure in the decomposition." 2124 "Wrapper method to reorder the qubits in the decomposition class." 2127 "Wrapper method to set the optimization tolerance of the optimization process during the decomposition." 2130 "Wrapper method to set the threshold of convergence in the optimization processes." 2133 "Wrapper method to to set the number of gate blocks to be optimized in one shot." 2136 "Call to set custom layers to the gate structure that are intended to be used in the decomposition from a binary file created from SQUANDER" 2139 "Call to append custom layers to the gate structure that are intended to be used in the decomposition from a binary file created from SQUANDER" 2142 "Call to set unitary matrix from a binary file created from SQUANDER" 2145 "Call to set unitary matrix to a numpy matrix" 2148 "Call to export unitary matrix to a binary file" 2151 "Call to get the name of SQUANDER project" 2154 "Call to set the name of SQUANDER project" 2157 "Call to get global phase" 2160 "Call to set global phase" 2163 "Call to apply global phase on Unitary matrix" 2166 "Call to add finalyzing layer (single qubit rotations on all of the qubits) to the gate structure." 2169 "Call to get Unitary Matrix" 2172 "Call to add adaptive layers to the gate structure stored by the class." 2175 "Call to add an adaptive layer to the gate structure previously imported gate structure" 2178 "Call to apply the imported gate structure on the unitary. The transformed unitary is to be decomposed in the calculations, and the imported gate structure is released." 2181 "Wrapper method to to set the optimizer method for the gate synthesis." 2184 "Wrapper method to to set the maximum number of iterations for the gate synthesis." 2187 "Method to retrieve the unitary of the circuit." 2190 "Wrapper method to to set the variant of the cost function. Input argument 0 stands for FROBENIUS_NORM, 1 for FROBENIUS_NORM_CORRECTION1, 2 for FROBENIUS_NORM_CORRECTION2, 3 for HILBERT_SCHMIDT_TEST, 4 for HILBERT_SCHMIDT_TEST_CORRECTION1, 5 for HILBERT_SCHMIDT_TEST_CORRECTION2." 2193 "Wrapper function to evaluate the cost function." 2196 "Wrapper function to evaluate the unitary function and the gradient components." 2199 "Wrapper function to evaluate the gradient components." 2202 "Wrapper function to evaluate the cost function and the gradient components." 2205 "Wrapper function to evaluate the cost function for a batch of input parameters." 2208 "Call to upload the unitary to the DFE. (Has no effect for non-DFE builds)" 2211 "Call to get the trace offset used in the cost function. In this case Tr(A) = sum_(i-offset=j) A_{ij}" 2214 "Call to set the trace offset used in the cost function. In this case Tr(A) = sum_(i-offset=j) A_{ij}" 2217 "Call to get the error of the decomposition. (i.e. the final value of the cost function)" 2220 "Wrapper function to evaluate the second Rényi entropy of a quantum circuit at a specific parameter set." 2223 "Call to get the number of qubits in the circuit" 2232 PyVarObject_HEAD_INIT(NULL, 0)
2233 "qgd_N_Qubit_Decomposition_adaptive_Wrapper.qgd_N_Qubit_Decomposition_adaptive_Wrapper",
2237 #if PY_VERSION_HEX < 0x030800b4 2240 #if PY_VERSION_HEX >= 0x030800b4 2245 #if PY_MAJOR_VERSION < 3 2248 #if PY_MAJOR_VERSION >= 3 2261 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
2262 "Object to represent a Circuit class of the QGD package.",
2289 #
if PY_VERSION_HEX >= 0x030400a1
2292 #
if PY_VERSION_HEX >= 0x030800b1
2295 #
if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
2304 PyModuleDef_HEAD_INIT,
2305 "qgd_N_Qubit_Decomposition_adaptive_Wrapper",
2306 "Python binding for QGD N_Qubit_Decomposition class",
2321 if (PyType_Ready(&qgd_N_Qubit_Decomposition_adaptive_Wrapper_Type) < 0)
2324 m = PyModule_Create(&qgd_N_Qubit_Decomposition_adaptive_Wrapper_Module);
2328 Py_INCREF(&qgd_N_Qubit_Decomposition_adaptive_Wrapper_Type);
2329 if (PyModule_AddObject(m,
"qgd_N_Qubit_Decomposition_adaptive_Wrapper", (PyObject *) &qgd_N_Qubit_Decomposition_adaptive_Wrapper_Type) < 0) {
2330 Py_DECREF(&qgd_N_Qubit_Decomposition_adaptive_Wrapper_Type);
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_List_Gates(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self)
Lists the gates decomposing the initial unitary.
Gates_block * get_flat_circuit()
Method to generate a flat circuit.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_Optimization_Problem_Combined(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args)
Wrapper function to evaluate the cost function an dthe gradient components.
N_Qubit_Decomposition_adaptive * decomp
An object to decompose the unitary.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_Start_Decomposition(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args, PyObject *kwds)
Wrapper function to call the start_decomposition method of C++ class N_Qubit_Decomposition.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_set_Cost_Function_Variant(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args, PyObject *kwds)
Wrapper function to set a variant for the cost function.
parameter_num
[set adaptive gate structure]
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_set_Convergence_Threshold(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args)
Wrapper method to set the threshold of convergence in the optimization processes. ...
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_Optimization_Problem_Batch(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args)
Wrapper function to evaluate the cost function for many input paramaters at once. ...
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_set_Debugfile(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args)
Set the debugfile name of the N_Qubit_Decomposition class.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_get_Optimized_Parameters(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self)
Extract the optimized parameters.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_add_Gate_Structure_From_Binary(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args)
Wrapper function to append custom layers to the gate structure that are intended to be used in the de...
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)
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_Optimization_Problem(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args)
Wrapper function to evaluate the cost function.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_set_Unitary(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args)
Matrix_real numpy2matrix_real(PyArrayObject *arr)
Call to create a PIC matrix_real representation of a numpy array.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_Reorder_Qubits(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args)
Wrapper method to reorder the qubits in the decomposition class.
static int qgd_N_Qubit_Decomposition_adaptive_Wrapper_init(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args, PyObject *kwds)
Method called when a python instance of the class qgd_N_Qubit_Decomposition_adaptive_Wrapper is initi...
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_get_Parameter_Num(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self)
Get the number of free parameters in the gate structure used for the decomposition.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_set_Trace_Offset(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args, PyObject *kwds)
Wrapper function to set the trace offset used in the cost function.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_set_Global_Phase(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args)
sets the global phase to the new angle given
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_set_Gate_Structure(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args)
Wrapper function to set custom gate structure for the decomposition.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_add_Adaptive_Layers(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self)
Wrapper method to add adaptive layers to the gate structure stored by the class.
Header file for a class responsible for grouping gates into subcircuits. (Subcircuits can be nested) ...
PyObject * matrix_real_to_numpy(Matrix_real &mtx)
Call to make a numpy array from an instance of matrix class.
static void qgd_N_Qubit_Decomposition_adaptive_Wrapper_dealloc(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self)
Method called when a python instance of the class qgd_N_Qubit_Decomposition_adaptive_Wrapper is destr...
A class describing a universal configuration element.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_get_Initial_Circuit(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self)
static PyModuleDef qgd_N_Qubit_Decomposition_adaptive_Wrapper_Module
Structure containing metadata about the module.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_add_Layer_To_Imported_Gate_Structure(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self)
Wrapper method to reorder the qubits in the decomposition class.
scalar * get_data() const
Call to get the pointer to the stored data.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_set_Project_Name(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args)
set project name
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_set_Max_Iterations(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args)
Set the number of maximum iterations.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_Finalize_Circuit(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args, PyObject *kwds)
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_get_Unitary(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self)
get Unitary
static PyMethodDef qgd_N_Qubit_Decomposition_adaptive_Wrapper_methods[]
Structure containing metadata about the methods of class qgd_N_Qubit_Decomposition_adaptive_Wrapper.
optimization_aglorithms
implemented optimization strategies
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_apply_Imported_Gate_Structure(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self)
Wrapper function to apply the imported gate structure on the unitary.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_set_Optimization_Tolerance(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args)
Wrapper method to set the optimization tolerance of the optimization process during the decomposition...
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_get_Project_Name(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self)
get project name
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_add_Finalyzing_Layer_To_Gate_Structure(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self)
Wrapper function to add finalyzing layer (single qubit rotations on all of the qubits) to the gate st...
int rows
The number of rows.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_Optimization_Problem_Grad(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args)
Wrapper function to evaluate the cost function an dthe gradient components.
int cols
The number of columns.
PyObject_HEAD Gates_block * gate
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_get_Num_of_Iters(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self)
Get the number of free parameters in the gate structure used for the decomposition.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_set_Gate_Structure_From_Binary(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args)
Wrapper function to set custom layers to the gate structure that are intended to be used in the decom...
Type definition of the qgd_N_Qubit_Decomposition_adaptive_Wrapper Python class of the qgd_N_Qubit_Dec...
void release_N_Qubit_Decomposition_adaptive(N_Qubit_Decomposition_adaptive *instance)
Call to deallocate an instance of N_Qubit_Decomposition_adaptive class.
Umtx
The unitary to be decomposed.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_set_Iteration_Loops(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args)
Set the number of iteration loops during the subdecomposition of the qbit-th qubit.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_Compress_Circuit(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self)
PyMODINIT_FUNC PyInit_qgd_N_Qubit_Decomposition_adaptive_Wrapper(void)
Method called when the Python module is initialized.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_Optimization_Problem_Combined_Unitary(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args)
Wrapper function to evaluate the unitary function and the unitary derivates.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_export_Unitary(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args)
export unitary to binary file
void set_owner(bool owner_in)
Call to set the current class instance to be (or not to be) the owner of the stored data array...
Structure type representing complex numbers in the SQUANDER package.
A base class to determine the decomposition of an N-qubit unitary into a sequence of CNOT and U3 gate...
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_apply_Global_Phase_Factor(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self)
applies the global phase to the Unitary matrix
dictionary config
gate systhesis #####################################
Class to store data of complex arrays and its properties.
int size() const
Call to get the number of the allocated elements.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_set_Verbose(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args)
Set the verbosity of the N_Qubit_Decomposition class.
cost_function_type
Type definition of the fifferent types of the cost function.
A class responsible for grouping two-qubit (CNOT,CZ,CH) and one-qubit gates into layers.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_set_Unitary_From_Binary(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args)
static PyMemberDef qgd_N_Qubit_Decomposition_adaptive_Wrapper_members[]
Structure containing metadata about the members of class qgd_N_Qubit_Decomposition_adaptive_Wrapper.
void set_property(std::string name_, double val_)
Call to set a double value.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_set_Optimized_Parameters(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args)
Extract the optimized parameters.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_get_Decomposition_Error(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self)
Cll to get the error of the decomposition (i.e.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_get_Second_Renyi_Entropy(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args)
Wrapper function to evaluate the second Rényi entropy of a quantum circuit at a specific parameter s...
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_get_Matrix(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args)
Retrieve the unified unitary operation of the circuit.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_get_circuit(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self)
Wrapper function to retrieve the circuit (Squander format) incorporated in the instance.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_get_gate_num(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self)
Wrapper function to get the number of decomposing gates.
Matrix numpy2matrix(PyArrayObject *arr)
Call to create a PIC matrix representation of a numpy array.
PyObject_HEAD Gates_block * circuit
Pointer to the C++ class of the base Gate_block module.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Method called when a python instance of the class qgd_N_Qubit_Decomposition_adaptive_Wrapper is alloc...
Matrix copy()
Call to create a copy of the matrix.
double real
the real part of a complex number
Header file for a class implementing the adaptive gate decomposition algorithm of arXiv:2203...
int get_qbit_num()
Call to get the number of qubits composing the unitary.
static PyTypeObject qgd_N_Qubit_Decomposition_adaptive_Wrapper_Type
A structure describing the type of the class qgd_N_Qubit_Decomposition_adaptive_Wrapper.
Type definition of the qgd_Circuit_Wrapper Python class of the qgd_Circuit_Wrapper module...
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_set_Optimizer(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args, PyObject *kwds)
Wrapper function to set custom gate structure for the decomposition.
PyObject_HEAD PyArrayObject * Umtx
pointer to the unitary to be decomposed to keep it alive
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_Upload_Umtx_to_DFE(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self)
Call to upload the unitary to the DFE.
PyObject * matrix_to_numpy(Matrix &mtx)
Call to make a numpy array from an instance of matrix class.
tuple decomposition_error
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_get_Qbit_Num(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self)
Call to retrieve the number of qubits in the circuit.
Class to store data of complex arrays and its properties.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_set_Optimization_Blocks(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args)
Wrapper method to to set the number of gate blocks to be optimized in one shot.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_get_Trace_Offset(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self)
Wrapper function to get the trace offset used in the cost function.
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_set_Max_Layer_Num(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self, PyObject *args)
Set the maximal number of layers used in the subdecomposition of the qbit-th qubit.
double imag
the imaginary part of a complex number
static PyObject * qgd_N_Qubit_Decomposition_adaptive_Wrapper_get_Global_Phase(qgd_N_Qubit_Decomposition_adaptive_Wrapper *self)
returns the angle of the global phase (the radius us always sqrt(2))
N_Qubit_Decomposition_adaptive * create_N_Qubit_Decomposition_adaptive(Matrix &Umtx, int qbit_num, int level_limit, int level_limit_min, std::vector< matrix_base< int >> topology_in, std::map< std::string, Config_Element > &config, int accelerator_num)
Creates an instance of class N_Qubit_Decomposition and return with a pointer pointing to the class in...