Sequential Quantum Gate Decomposer  v1.9.3
Powerful decomposition of general unitarias into one- and two-qubit gates gates
gates_Wrapper.cpp
Go to the documentation of this file.
1 /*
2 Created on Fri Jun 26 14:42:56 2020
3 Copyright 2020 Peter Rakyta, Ph.D.
4 
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
8 
9  http://www.apache.org/licenses/LICENSE-2.0
10 
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see http://www.gnu.org/licenses/.
19 
20 @author: Peter Rakyta, Ph.D.
21 */
22 /*
23 \file gates_Wrapper.cpp
24 \brief Python interface to expose Squander gates to Python
25 */
26 
27 #define PY_SSIZE_T_CLEAN
28 
29 
30 #include <Python.h>
31 #include "structmember.h"
32 #include "Gate.h"
33 #include "CH.h"
34 #include "CNOT.h"
35 #include "CZ.h"
36 #include "CRY.h"
37 #include "H.h"
38 #include "RX.h"
39 #include "RY.h"
40 #include "RZ.h"
41 #include "SX.h"
42 #include "SYC.h"
43 #include "U1.h"
44 #include "U2.h"
45 #include "U3.h"
46 #include "X.h"
47 #include "Y.h"
48 #include "Z.h"
49 #include "T.h"
50 #include "Tdg.h"
51 #include "R.h"
52 #include "numpy_interface.h"
53 
54 
56 
60 typedef struct {
61  PyObject_HEAD
64 } Gate_Wrapper;
65 
66 
67 
68 
69 template<typename GateT>
71  GateT* gate = new GateT( qbit_num, target_qbit );
72  return static_cast<Gate*>( gate );
73 }
74 
75 
76 template<typename GateT>
78 
79  GateT* gate = new GateT( qbit_num, target_qbit, control_qbit );
80  return static_cast<Gate*>( gate );
81 
82 }
83 
84 
85 
90 static void
92 {
93  if( self->gate != NULL ) {
94  delete( self->gate );
95  self->gate = NULL;
96  }
97 
98  Py_TYPE(self)->tp_free((PyObject *) self);
99 }
100 
101 
106 static PyObject *
107  generic_Gate_Wrapper_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
108 {
109 
110  static char *kwlist[] = {(char*)"qbit_num", NULL};
111  int qbit_num = -1;
112 
113 
114  if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwlist, &qbit_num)) {
115  std::string err( "Unable to parse arguments");
116  PyErr_SetString(PyExc_Exception, err.c_str());
117  return NULL;
118  }
119 
120 
121  Gate_Wrapper *self;
122  self = (Gate_Wrapper *) type->tp_alloc(type, 0);
123  if (self != NULL) {
124  self->gate = new Gate( qbit_num );
125  }
126 
127 
128  return (PyObject *) self;
129 }
130 
131 
132 
139 template<typename GateT>
140 static PyObject *
141  Gate_Wrapper_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
142 {
143 
144  static char *kwlist[] = {(char*)"qbit_num", (char*)"target_qbit", NULL};
145  int qbit_num = -1;
146  int target_qbit = -1;
147 
148  if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwlist, &qbit_num, &target_qbit)) {
149  std::string err( "Unable to parse arguments");
150  PyErr_SetString(PyExc_Exception, err.c_str());
151  return NULL;
152  }
153 
154 
155  Gate_Wrapper *self;
156  self = (Gate_Wrapper *) type->tp_alloc(type, 0);
157  if (self != NULL) {
158  self->gate = create_gate<GateT>( qbit_num, target_qbit );
159  }
160 
161 
162  return (PyObject *) self;
163 }
164 
165 
172 template<typename GateT>
173 static PyObject *
174  controlled_gate_Wrapper_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
175 {
176  static char *kwlist[] = {(char*)"qbit_num", (char*)"target_qbit", (char*)"control_qbit", NULL};
177  int qbit_num = -1;
178  int target_qbit = -1;
179  int control_qbit = -1;
180 
181 
182  if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iii", kwlist, &qbit_num, &target_qbit, &control_qbit)) {
183  std::string err( "Unable to parse arguments");
184  PyErr_SetString(PyExc_Exception, err.c_str());
185  return NULL;
186  }
187 
188 
189  Gate_Wrapper *self;
190  self = (Gate_Wrapper *) type->tp_alloc(type, 0);
191  if (self != NULL) {
192  self->gate = create_controlled_gate<GateT>( qbit_num, target_qbit, control_qbit );
193  }
194 
195  return (PyObject *) self;
196 
197 }
198 
199 
206 static int
207  Gate_Wrapper_init(Gate_Wrapper *self, PyObject *args, PyObject *kwds)
208 {
209 
210 
211 
212  return 0;
213 }
214 
215 
216 
217 
218 
219 
220 
225 static PyObject *
226 Gate_Wrapper_get_Matrix( Gate_Wrapper *self, PyObject *args, PyObject *kwds ) {
227 
228  static char *kwlist[] = {(char*)"parameters", NULL};
229 
230  PyArrayObject * parameters_arr = NULL;
231 
232 
233  // parsing input arguments
234  if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, &parameters_arr )) {
235  std::string err( "Unable to parse keyword arguments");
236  return NULL;
237  }
238 
239  Gate* gate = self->gate;
240 
241  Matrix gate_mtx;
242 
243  if( gate->get_parameter_num() == 0 ) {
244 
245  if( parameters_arr != NULL ) {
246  std::string err( "The gate contains no parameters to set, but parameter array was given as input");
247  return NULL;
248  }
249 
250  int parallel = 1;
251  gate_mtx = gate->get_matrix( parallel );
252 
253  }
254  else if( gate->get_parameter_num() > 0 ) {
255 
256  if( parameters_arr == NULL ) {
257  std::string err( "The gate has free parameters to set, but no parameter array was given as input");
258  return NULL;
259  }
260 
261  if ( PyArray_TYPE(parameters_arr) != NPY_DOUBLE ) {
262  PyErr_SetString(PyExc_Exception, "Parameter vector should be real typed");
263  return NULL;
264  }
265 
266  if ( PyArray_IS_C_CONTIGUOUS(parameters_arr) ) {
267  Py_INCREF(parameters_arr);
268  }
269  else {
270  parameters_arr = (PyArrayObject*)PyArray_FROM_OTF( (PyObject*)parameters_arr, NPY_DOUBLE, NPY_ARRAY_IN_ARRAY);
271  }
272 
273 
274  // get the C++ wrapper around the input data
275  Matrix_real&& parameters_mtx = numpy2matrix_real( parameters_arr );
276 
277  int parallel = 1;
278  gate_mtx = self->gate->get_matrix( parameters_mtx, parallel );
279 
280  Py_DECREF(parameters_arr);
281 
282 
283  }
284  else {
285  std::string err( "The number of parameters in a gate is set to a negative value");
286  return NULL;
287 
288  }
289 
290 
291  // convert to numpy array
292  gate_mtx.set_owner(false);
293  PyObject *gate_mtx_py = matrix_to_numpy( gate_mtx );
294 
295 
296  return gate_mtx_py;
297 
298 }
299 
300 
301 
305 static PyObject *
306 Gate_Wrapper_Wrapper_apply_to( Gate_Wrapper *self, PyObject *args, PyObject *kwds ) {
307 
308  static char *kwlist[] = {(char*)"unitary", (char*)"parameters", (char*)"parallel", NULL};
309 
310  PyArrayObject * input = NULL;
311  PyArrayObject * parameters_arr = NULL;
312  int parallel = 1;
313 
314  // parsing input arguments
315  if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|Oi", kwlist, &input, &parameters_arr, &parallel )) {
316  std::string err( "Unable to parse keyword arguments");
317  return NULL;
318  }
319 
320  // Check if input matrix is provided
321  if ( input == NULL ) {
322  PyErr_SetString(PyExc_Exception, "Input matrix was not given");
323  return NULL;
324  }
325 
326  if ( PyArray_TYPE(input) != NPY_COMPLEX128 ) {
327  PyErr_SetString(PyExc_Exception, "input matrix or state should be complex typed");
328  return NULL;
329  }
330 
331  // test C-style contiguous memory allocation of the array
332  if ( !PyArray_IS_C_CONTIGUOUS(input) ) {
333  PyErr_SetString(PyExc_Exception, "input state/matrix is not memory contiguous");
334  return NULL;
335  }
336 
337  // create QGD version of the input matrix
338  Matrix input_mtx = numpy2matrix(input);
339 
340  Gate* gate = self->gate;
341 
342  const int param_count = gate->get_parameter_num();
343 
344  try {
345  if (param_count == 0) {
346  // Non-parameterized gate
347  gate->apply_to(input_mtx, parallel);
348  }
349  else if (param_count > 0) {
350  // Parameterized gate
351  if( parameters_arr == NULL ) {
352  std::string err( "The gate has free parameters to set, but no parameter array was given as input");
353  return NULL;
354  }
355 
356  if ( PyArray_TYPE(parameters_arr) != NPY_DOUBLE ) {
357  PyErr_SetString(PyExc_TypeError, "Parameter vector should be real typed");
358  return NULL;
359  }
360 
361  // Convert parameters to C++ matrix
362  if ( PyArray_IS_C_CONTIGUOUS(parameters_arr) ) {
363  Py_INCREF(parameters_arr);
364  }
365  else {
366  parameters_arr = (PyArrayObject*)PyArray_FROM_OTF( (PyObject*)parameters_arr, NPY_DOUBLE, NPY_ARRAY_IN_ARRAY);
367  }
368 
369  Matrix_real&& parameters_mtx = numpy2matrix_real( parameters_arr );
370 
371  gate->apply_to(parameters_mtx, input_mtx, parallel);
372 
373  Py_DECREF(parameters_arr);
374  }
375  else {
376  PyErr_SetString(PyExc_ValueError, "The number of parameters in a gate is set to a negative value");
377  return NULL;
378  }
379  }
380  catch (const std::string& err) {
381  PyErr_SetString(PyExc_RuntimeError, err.c_str());
382  return NULL;
383  }
384  catch(...) {
385  PyErr_SetString(PyExc_RuntimeError, "Unknown error in gate operation");
386  return NULL;
387  }
388 
389 
390  // if numpy array was not aligned to memory boundaries, the input is reallocated on the C++ side
391  if (input_mtx.data != PyArray_DATA(input)) {
392  memcpy(PyArray_DATA(input), input_mtx.data, input_mtx.size() * sizeof(QGD_Complex16));
393  }
394 
395  return Py_BuildValue("i", 0);
396 }
397 
398 
399 
408 static PyObject *
409 Gate_Wrapper_get_Gate_Kernel( Gate_Wrapper *self, PyObject *args, PyObject *kwds) {
410 
411 
412  static char *kwlist[] = {(char*)"ThetaOver2", (char*)"Phi", (char*)"Lambda", NULL};
413 
414  double ThetaOver2;
415  double Phi;
416  double Lambda;
417 
418 
419  try {
420  self->gate->parameters_for_calc_one_qubit(ThetaOver2, Phi, Lambda);
421  }
422  catch (std::string err) {
423  PyErr_SetString(PyExc_Exception, err.c_str());
424  return NULL;
425  }
426  catch(...) {
427  std::string err( "Invalid pointer to gate class");
428  PyErr_SetString(PyExc_Exception, err.c_str());
429  return NULL;
430  }
431 
432  // parsing input arguments
433  if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ddd", kwlist, &ThetaOver2, &Phi, &Lambda )) {
434  std::string err( "Unable to parse keyword arguments");
435  return NULL;
436  }
437 
438 
439  Matrix CH_1qbit_;
440 
441  // create QGD version of the input matrix
442  Gate* gate = self->gate;
443 
444  if( gate->get_parameter_num() == 0 ) {
445  CH_1qbit_ = self->gate->calc_one_qubit_u3( );
446  }
447  else if( gate->get_parameter_num() > 0 ) {
448  CH_1qbit_ = self->gate->calc_one_qubit_u3( ThetaOver2, Phi, Lambda );
449  }
450  else {
451  std::string err( "The number of parameters in a gate is set to a negative value");
452  return NULL;
453 
454  }
455 
456 
457  PyObject *CH_1qbit = matrix_to_numpy( CH_1qbit_ );
458 
459  return CH_1qbit;
460 
461 
462 }
463 
464 
465 
470 static PyObject *
472 
473  int parameter_num;
474 
475  try {
476  parameter_num = self->gate->get_parameter_num();
477  }
478  catch (std::string err) {
479  PyErr_SetString(PyExc_Exception, err.c_str());
480  return NULL;
481  }
482  catch(...) {
483  std::string err( "Invalid pointer to gate class");
484  PyErr_SetString(PyExc_Exception, err.c_str());
485  return NULL;
486  }
487 
488 
489  return Py_BuildValue("i", parameter_num);
490 
491 }
492 
493 
494 
499 static PyObject *
501 
502  int start_index;
503 
504  try {
505  start_index = self->gate->get_parameter_start_idx();
506  }
507  catch (std::string err) {
508  PyErr_SetString(PyExc_Exception, err.c_str());
509  return NULL;
510  }
511  catch(...) {
512  std::string err( "Invalid pointer to gate class");
513  PyErr_SetString(PyExc_Exception, err.c_str());
514  return NULL;
515  }
516 
517  return Py_BuildValue("i", start_index);
518 
519 }
520 
521 
522 
523 
528 static PyObject *
530 
531  int target_qbit;
532 
533  try {
534  target_qbit = self->gate->get_target_qbit();
535  }
536  catch (std::string err) {
537  PyErr_SetString(PyExc_Exception, err.c_str());
538  return NULL;
539  }
540  catch(...) {
541  std::string err( "Invalid pointer to gate class");
542  PyErr_SetString(PyExc_Exception, err.c_str());
543  return NULL;
544  }
545 
546  return Py_BuildValue("i", target_qbit);
547 
548 }
549 
554 static PyObject *
556 
557  int control_qbit;
558 
559  try {
560  control_qbit = self->gate->get_control_qbit();
561  }
562  catch (std::string err) {
563  PyErr_SetString(PyExc_Exception, err.c_str());
564  return NULL;
565  }
566  catch(...) {
567  std::string err( "Invalid pointer to gate class");
568  PyErr_SetString(PyExc_Exception, err.c_str());
569  return NULL;
570  }
571 
572  return Py_BuildValue("i", control_qbit);
573 
574 }
575 
576 
577 
581 static PyObject *
582 Gate_Wrapper_set_Target_Qbit( Gate_Wrapper *self, PyObject *args ) {
583 
584  int target_qbit_in = -1;
585  if (!PyArg_ParseTuple(args, "|i", &target_qbit_in )) {
586  std::string err( "Unable to parse arguments");
587  return NULL;
588  }
589 
590  try{
591  self->gate->set_target_qbit(target_qbit_in);
592  }
593  catch (std::string err) {
594  PyErr_SetString(PyExc_Exception, err.c_str());
595  return NULL;
596  }
597  catch(...) {
598  std::string err( "Invalid pointer to circuit class");
599  PyErr_SetString(PyExc_Exception, err.c_str());
600  return NULL;
601  }
602 
603 
604  return Py_BuildValue("i", 0);
605 
606 }
607 
611 static PyObject *
612 Gate_Wrapper_set_Control_Qbit( Gate_Wrapper *self, PyObject *args ) {
613 
614  int control_qbit_in = -1;
615  if (!PyArg_ParseTuple(args, "|i", &control_qbit_in )) {
616  std::string err( "Unable to parse arguments");
617  return NULL;
618  }
619 
620  try{
621  self->gate->set_control_qbit(control_qbit_in);
622  }
623  catch (std::string err) {
624  PyErr_SetString(PyExc_Exception, err.c_str());
625  return NULL;
626  }
627  catch(...) {
628  std::string err( "Invalid pointer to circuit class");
629  PyErr_SetString(PyExc_Exception, err.c_str());
630  return NULL;
631  }
632 
633 
634 
635  return Py_BuildValue("i", 0);
636 
637 }
638 
639 
640 
645 static PyObject *
647 
648  PyArrayObject * parameters_arr = NULL;
649 
650 
651  // parsing input arguments
652  if (!PyArg_ParseTuple(args, "O", &parameters_arr )) {
653  PyErr_SetString(PyExc_ValueError, "Unable to parse arguments");
654  return NULL;
655  }
656 
657  if( parameters_arr == NULL ) {
658  PyErr_SetString(PyExc_ValueError, "Missing input parameter array");
659  return NULL;
660  }
661 
662  if (PyArray_TYPE(parameters_arr) != NPY_DOUBLE) {
663  PyErr_SetString(PyExc_TypeError, "Parameter array must contain double values");
664  return NULL;
665  }
666 
667  if ( PyArray_IS_C_CONTIGUOUS(parameters_arr) ) {
668  Py_INCREF(parameters_arr);
669  }
670  else {
671  parameters_arr = (PyArrayObject*)PyArray_FROM_OTF( (PyObject*)parameters_arr, NPY_DOUBLE, NPY_ARRAY_IN_ARRAY);
672  }
673 
674  // get the C++ wrapper around the data
675  Matrix_real&& parameters_mtx = numpy2matrix_real( parameters_arr );
676 
677  Matrix_real extracted_parameters;
678 
679  try {
680  extracted_parameters = self->gate->extract_parameters( parameters_mtx );
681  }
682  catch (std::string err) {
683  Py_DECREF(parameters_arr);
684  PyErr_SetString(PyExc_Exception, err.c_str());
685  return NULL;
686  }
687  catch(...) {
688  Py_DECREF(parameters_arr);
689  std::string err( "Invalid pointer to circuit class");
690  PyErr_SetString(PyExc_Exception, err.c_str());
691  return NULL;
692  }
693 
694 
695  // convert to numpy array
696  extracted_parameters.set_owner(false);
697  PyObject *extracted_parameters_py = matrix_real_to_numpy( extracted_parameters );
698 
699  // flatten the extracted array
700  long int param_num = (long int)extracted_parameters.size();
701  PyArray_Dims new_shape;
702  new_shape.ptr = &param_num;
703  new_shape.len = 1;
704 
705  PyObject *extracted_parameters_py_flatten = PyArray_Newshape( (PyArrayObject*)extracted_parameters_py, &new_shape, NPY_CORDER);
706 
707  Py_DECREF(parameters_arr);
708  return extracted_parameters_py_flatten;
709 }
710 
711 
712 
713 
718 static PyObject *
720 
721  std::string name;
722  try {
723  name = self->gate->get_name();
724  }
725  catch (std::string err) {
726  PyErr_SetString(PyExc_Exception, err.c_str());
727  return NULL;
728  }
729  catch(...) {
730  std::string err( "Invalid pointer to circuit class");
731  PyErr_SetString(PyExc_Exception, err.c_str());
732  return NULL;
733  }
734 
735  return PyUnicode_FromString(name.c_str());
736 }
737 
738 
739 
743 static PyObject *
745 
746  PyObject* gate_state = PyDict_New();
747 
748  if( gate_state == NULL ) {
749  std::string err( "Failed to create dictionary");
750  PyErr_SetString(PyExc_Exception, err.c_str());
751  return NULL;
752  }
753 
754 
755  PyObject* key = Py_BuildValue( "s", "type" );
756  PyObject* val = Py_BuildValue("i", self->gate->get_type() );
757  PyDict_SetItem(gate_state, key, val);
758 
759  key = Py_BuildValue( "s", "qbit_num" );
760  val = Py_BuildValue("i", self->gate->get_qbit_num() );
761  PyDict_SetItem(gate_state, key, val);
762 
763  key = Py_BuildValue( "s", "target_qbit" );
764  val = Py_BuildValue("i", self->gate->get_target_qbit() );
765  PyDict_SetItem(gate_state, key, val);
766 
767  key = Py_BuildValue( "s", "control_qbit" );
768  val = Py_BuildValue("i", self->gate->get_control_qbit() );
769  PyDict_SetItem(gate_state, key, val);
770 
771 
772  return gate_state;
773 
774 }
775 
776 
777 
778 
779 
783 static PyObject *
784 Gate_Wrapper_setstate( Gate_Wrapper *self, PyObject *args ) {
785 
786 
787  PyObject* gate_state = NULL;
788 
789 
790  // parsing input arguments
791  if (!PyArg_ParseTuple(args, "O", &gate_state )) {
792  PyErr_SetString(PyExc_ValueError, "Unable to parse arguments");
793  return NULL;
794  }
795 
796  if( !PyDict_Check( gate_state ) ) {
797  std::string err( "Gate state should be given by a dictionary");
798  PyErr_SetString(PyExc_Exception, err.c_str());
799  return NULL;
800  }
801 
802  PyObject* qbit_num_key = Py_BuildValue( "s", "qbit_num" );
803  if ( PyDict_Contains(gate_state, qbit_num_key) == 0 ) {
804  std::string err( "Gate state should contain the number of qubits");
805  PyErr_SetString(PyExc_Exception, err.c_str());
806 
807  Py_DECREF( qbit_num_key );
808  return NULL;
809  }
810  PyObject* qbit_num_py = PyDict_GetItem(gate_state, qbit_num_key); // borrowed reference
811  Py_DECREF( qbit_num_key );
812 
813 
814  PyObject* target_qbit_key = Py_BuildValue( "s", "target_qbit" );
815  if ( PyDict_Contains(gate_state, target_qbit_key) == 0 ) {
816  std::string err( "Gate state should contain a target qubit");
817  PyErr_SetString(PyExc_Exception, err.c_str());
818 
819  Py_DECREF( target_qbit_key );
820  return NULL;
821  }
822  PyObject* target_qbit_py = PyDict_GetItem(gate_state, target_qbit_key); // borrowed reference
823  Py_DECREF( target_qbit_key );
824 
825 
826  PyObject* control_qbit_key = Py_BuildValue( "s", "control_qbit" );
827  if ( PyDict_Contains(gate_state, control_qbit_key) == 0 ) {
828  std::string err( "Gate state should contain a control qubit (-1 for gates with no control qubits)");
829  PyErr_SetString(PyExc_Exception, err.c_str());
830 
831  Py_DECREF( control_qbit_key );
832  return NULL;
833  }
834  PyObject* control_qbit_py = PyDict_GetItem(gate_state, control_qbit_key); // borrowed reference
835  Py_DECREF( control_qbit_key );
836 
837 
838 
839 
840 
841  PyObject* type_key = Py_BuildValue( "s", "type" );
842  if ( PyDict_Contains(gate_state, type_key) == 0 ) {
843  std::string err( "Gate state should contain a type ID (see gate.h for the gate type IDs)");
844  PyErr_SetString(PyExc_Exception, err.c_str());
845 
846  Py_DECREF( type_key );
847  return NULL;
848  }
849  PyObject* type_py = PyDict_GetItem(gate_state, type_key); // borrowed reference
850  Py_DECREF( type_key );
851 
852 
853 
854  int qbit_num = (int)PyLong_AsLong( qbit_num_py );
855  int target_qbit = (int)PyLong_AsLong( target_qbit_py );
856  int control_qbit = (int)PyLong_AsLong( control_qbit_py );
857  int gate_type = (int)PyLong_AsLong( type_py );
858 
859 
860  Gate* gate = NULL;
861 
862  switch (gate_type) {
863  case CNOT_OPERATION: {
864  gate = create_controlled_gate<CNOT>( qbit_num, target_qbit, control_qbit );
865  break;
866  }
867  case CZ_OPERATION:
868  {
869  gate = create_controlled_gate<CZ>( qbit_num, target_qbit, control_qbit );
870  break;
871  }
872  case CH_OPERATION: {
873  gate = create_controlled_gate<CH>( qbit_num, target_qbit, control_qbit );
874  break;
875  }
876  case SYC_OPERATION: {
877  gate = create_controlled_gate<SYC>( qbit_num, target_qbit, control_qbit );
878  break;
879  }
880  case X_OPERATION: {
881  gate = create_gate<X>( qbit_num, target_qbit );
882  break;
883  }
884  case Y_OPERATION: {
885  gate = create_gate<Y>( qbit_num, target_qbit );
886  break;
887  }
888  case Z_OPERATION: {
889  gate = create_gate<Z>( qbit_num, target_qbit );
890  break;
891  }
892  case SX_OPERATION: {
893  gate = create_gate<SX>( qbit_num, target_qbit );
894  break;
895  }
896  case T_OPERATION: {
897  gate = create_gate<T>( qbit_num, target_qbit );
898  break;
899  }
900  case TDG_OPERATION: {
901  gate = create_gate<Tdg>( qbit_num, target_qbit );
902  break;
903  }
904  case H_OPERATION: {
905  gate = create_gate<H>( qbit_num, target_qbit );
906  break;
907  }
908  case U1_OPERATION: {
909  gate = create_gate<U1>( qbit_num, target_qbit );
910  break;
911  }
912  case U2_OPERATION: {
913  gate = create_gate<U2>( qbit_num, target_qbit );
914  break;
915  }
916  case U3_OPERATION: {
917  gate = create_gate<U3>( qbit_num, target_qbit );
918  break;
919  }
920  case R_OPERATION: {
921  gate = create_gate<R>( qbit_num, target_qbit );
922  break;
923  }
924  case RX_OPERATION: {
925  gate = create_gate<RX>( qbit_num, target_qbit );
926  break;
927  }
928  case RY_OPERATION: {
929  gate = create_gate<RY>( qbit_num, target_qbit );
930  break;
931  }
932  case CRY_OPERATION: {
933  gate = create_controlled_gate<CRY>( qbit_num, target_qbit, control_qbit );
934  break;
935  }
936  case RZ_OPERATION: {
937  gate = create_gate<RZ>( qbit_num, target_qbit );
938  break;
939  }
940  case BLOCK_OPERATION: {
941  std::string err( "Unsupported gate type: block operation");
942  PyErr_SetString(PyExc_Exception, err.c_str());
943  return NULL;
944  }
945  default:
946  std::string err( "Unsupported gate type");
947  PyErr_SetString(PyExc_Exception, err.c_str());
948  return NULL;
949  }
950 
951 
952 
953  try {
954  delete( self->gate );
955  self->gate = gate;
956  }
957  catch (std::string err) {
958  PyErr_SetString(PyExc_Exception, err.c_str());
959  return NULL;
960  }
961  catch(...) {
962  std::string err( "Invalid pointer to circuit class");
963  PyErr_SetString(PyExc_Exception, err.c_str());
964  return NULL;
965  }
966 
967 
968  return Py_None;
969 
970 }
971 
972 
973 
974 
975 
976 extern "C"
977 {
978 
982 static PyMethodDef Gate_Wrapper_methods[] = {
983  {"get_Matrix", (PyCFunction) Gate_Wrapper_get_Matrix, METH_VARARGS | METH_KEYWORDS,
984  "Method to get the matrix representation of the gate."
985  },
986  {"apply_to", (PyCFunction) Gate_Wrapper_Wrapper_apply_to, METH_VARARGS | METH_KEYWORDS,
987  "Call to apply the gate on an input state/matrix."
988  },
989  {"get_Gate_Kernel", (PyCFunction) Gate_Wrapper_get_Gate_Kernel, METH_VARARGS | METH_KEYWORDS,
990  "Call to calculate the gate matrix acting on a single qbit space."
991  },
992  {"get_Parameter_Num", (PyCFunction) Gate_Wrapper_get_Parameter_Num, METH_NOARGS,
993  "Call to get the number of free parameters in the gate."
994  },
995  {"get_Parameter_Start_Index", (PyCFunction) Gate_Wrapper_get_Parameter_Start_Index, METH_NOARGS,
996  "Call to get the starting index of the parameters in the parameter array corresponding to the circuit in which the current gate is incorporated."
997  },
998  {"get_Target_Qbit", (PyCFunction) Gate_Wrapper_get_Target_Qbit, METH_NOARGS,
999  "Call to get the target qbit."
1000  },
1001  {"get_Control_Qbit", (PyCFunction) Gate_Wrapper_get_Control_Qbit, METH_NOARGS,
1002  "Call to get the control qbit (returns with -1 if no control qbit is used in the gate)."
1003  },
1004  {"set_Target_Qbit", (PyCFunction) Gate_Wrapper_set_Target_Qbit, METH_VARARGS,
1005  "Call to set the target qbit."
1006  },
1007  {"set_Control_Qbit", (PyCFunction) Gate_Wrapper_set_Control_Qbit, METH_VARARGS,
1008  "Call to set the control qbit."
1009  },
1010  {"Extract_Parameters", (PyCFunction) Gate_Wrapper_Extract_Parameters, METH_VARARGS,
1011  "Call to extract the paramaters corresponding to the gate, from a parameter array associated to the circuit in which the gate is embedded."
1012  },
1013  {"get_Name", (PyCFunction) Gate_Wrapper_get_Name, METH_NOARGS,
1014  "Method to get the name label of the gate"
1015  },
1016  {"__getstate__", (PyCFunction) Gate_Wrapper_getstate, METH_NOARGS,
1017  "Method to extract the stored quantum gate in a human-readable data serialized and pickle-able format"
1018  },
1019  {"__setstate__", (PyCFunction) Gate_Wrapper_setstate, METH_VARARGS,
1020  "Call to set the state of quantum gate from a human-readable data serialized and pickle-able format"
1021  },
1022  {NULL} /* Sentinel */
1023 };
1024 
1025 
1029 static PyMemberDef Gate_Wrapper_members[] = {
1030  {NULL} /* Sentinel */
1031 };
1032 
1033 
1035 
1036 
1038 
1039  //PyVarObject tt = { PyVarObject_HEAD_INIT(NULL, 0) };
1040 
1041  ob_base.ob_size = 0;
1042  tp_name = "Gate";
1043  tp_basicsize = sizeof(Gate_Wrapper);
1044  tp_dealloc = (destructor) Gate_Wrapper_dealloc;
1045  tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
1046  tp_doc = "Object to represent python binding for a generic base gate of the Squander package.";
1047  tp_methods = Gate_Wrapper_methods;
1048  tp_members = Gate_Wrapper_members;
1049  tp_init = (initproc) Gate_Wrapper_init;
1050  tp_new = generic_Gate_Wrapper_new;
1051  }
1052 
1053 
1054 };
1055 
1056 
1058 
1059 
1061 
1063  tp_name = "CH";
1064  tp_doc = "Object to represent python binding for a CH gate of the Squander package.";
1065  tp_new = (newfunc) controlled_gate_Wrapper_new<CH>;
1066  tp_base = &Gate_Wrapper_Type;
1067  }
1068 };
1069 
1071 
1073  tp_name = "CNOT";
1074  tp_doc = "Object to represent python binding for a CNOT gate of the Squander package.";
1075  tp_new = (newfunc) controlled_gate_Wrapper_new<CNOT>;
1076  tp_base = &Gate_Wrapper_Type;
1077  }
1078 };
1079 
1081 
1083  tp_name = "CZ";
1084  tp_doc = "Object to represent python binding for a CZ gate of the Squander package.";
1085  tp_new = (newfunc) controlled_gate_Wrapper_new<CZ>;
1086  tp_base = &Gate_Wrapper_Type;
1087  }
1088 };
1089 
1091 
1093  tp_name = "CRY";
1094  tp_doc = "Object to represent python binding for a CRY gate of the Squander package.";
1095  tp_new = (newfunc) controlled_gate_Wrapper_new<CRY>;
1096  tp_base = &Gate_Wrapper_Type;
1097  }
1098 };
1099 
1101 
1103  tp_name = "H";
1104  tp_doc = "Object to represent python binding for a H gate of the Squander package.";
1105  tp_new = (newfunc) Gate_Wrapper_new<H>;
1106  tp_base = &Gate_Wrapper_Type;
1107  }
1108 };
1109 
1111 
1113  tp_name = "RX";
1114  tp_doc = "Object to represent python binding for a RX gate of the Squander package.";
1115  tp_new = (newfunc) Gate_Wrapper_new<RX>;
1116  tp_base = &Gate_Wrapper_Type;
1117  }
1118 };
1119 
1121 
1123  tp_name = "RY";
1124  tp_doc = "Object to represent python binding for a RY gate of the Squander package.";
1125  tp_new = (newfunc) Gate_Wrapper_new<RY>;
1126  tp_base = &Gate_Wrapper_Type;
1127  }
1128 };
1129 
1131 
1133  tp_name = "RZ";
1134  tp_doc = "Object to represent python binding for a RZ gate of the Squander package.";
1135  tp_new = (newfunc) Gate_Wrapper_new<RZ>;
1136  tp_base = &Gate_Wrapper_Type;
1137  }
1138 };
1139 
1141 
1143  tp_name = "SX";
1144  tp_doc = "Object to represent python binding for a SX gate of the Squander package.";
1145  tp_new = (newfunc) Gate_Wrapper_new<SX>;
1146  tp_base = &Gate_Wrapper_Type;
1147  }
1148 };
1149 
1151 
1153  tp_name = "SYC";
1154  tp_doc = "Object to represent python binding for a SYC gate of the Squander package.";
1155  tp_new = (newfunc) controlled_gate_Wrapper_new<SYC>;
1156  tp_base = &Gate_Wrapper_Type;
1157  }
1158 };
1159 
1161 
1163  tp_name = "U1";
1164  tp_doc = "Object to represent python binding for a U1 gate of the Squander package.";
1165  tp_new = (newfunc) Gate_Wrapper_new<U1>;
1166  tp_base = &Gate_Wrapper_Type;
1167  }
1168 };
1169 
1171 
1173  tp_name = "U2";
1174  tp_doc = "Object to represent python binding for a U2 gate of the Squander package.";
1175  tp_new = (newfunc) Gate_Wrapper_new<U2>;
1176  tp_base = &Gate_Wrapper_Type;
1177  }
1178 };
1179 
1181 
1183  tp_name = "U3";
1184  tp_doc = "Object to represent python binding for a U3 gate of the Squander package.";
1185  tp_new = (newfunc) Gate_Wrapper_new<U3>;
1186  tp_base = &Gate_Wrapper_Type;
1187  }
1188 };
1189 
1191 
1193  tp_name = "X";
1194  tp_doc = "Object to represent python binding for a X gate of the Squander package.";
1195  tp_new = (newfunc) Gate_Wrapper_new<X>;
1196  tp_base = &Gate_Wrapper_Type;
1197  }
1198 };
1199 
1201 
1203  tp_name = "Y";
1204  tp_doc = "Object to represent python binding for a Y gate of the Squander package.";
1205  tp_new = (newfunc) Gate_Wrapper_new<Y>;
1206  tp_base = &Gate_Wrapper_Type;
1207  }
1208 };
1209 
1211 
1213  tp_name = "Z";
1214  tp_doc = "Object to represent python binding for a Z gate of the Squander package.";
1215  tp_new = (newfunc) Gate_Wrapper_new<Z>;
1216  tp_base = &Gate_Wrapper_Type;
1217  }
1218 };
1219 
1220 
1222 
1224  tp_name = "T";
1225  tp_doc = "Object to represent python binding for a T gate of the Squander package.";
1226  tp_new = (newfunc) Gate_Wrapper_new<T>;
1227  tp_base = &Gate_Wrapper_Type;
1228  }
1229 };
1230 
1231 
1233 
1235  tp_name = "Tdg";
1236  tp_doc = "Object to represent python binding for a T gate of the Squander package.";
1237  tp_new = (newfunc) Gate_Wrapper_new<Tdg>;
1238  tp_base = &Gate_Wrapper_Type;
1239  }
1240 };
1241 
1242 
1244 
1246  tp_name = "R";
1247  tp_doc = "Object to represent python binding for a R gate of the Squander package.";
1248  tp_new = (newfunc) Gate_Wrapper_new<R>;
1249  tp_base = &Gate_Wrapper_Type;
1250  }
1251 };
1252 
1253 
1273 
1274 
1275 
1276 
1278 
1279 
1280 
1281 
1285 static PyModuleDef gates_Wrapper_Module = {
1286  PyModuleDef_HEAD_INIT,
1287  "gates_Wrapper",
1288  "Python binding for gates implemented in Squander C++",
1289  -1,
1290 };
1291 
1292 
1296 PyMODINIT_FUNC
1298 {
1299 
1300  // initialize Numpy API
1301  import_array();
1302 
1303 
1304  PyObject * m= PyModule_Create(& gates_Wrapper_Module);
1305  if (m == NULL)
1306  return NULL;
1307 
1308 
1309  if (PyType_Ready(&Gate_Wrapper_Type) < 0 ||
1310  PyType_Ready(&CH_Wrapper_Type_ins) < 0 ||
1311  PyType_Ready(&CNOT_Wrapper_Type_ins) < 0 ||
1312  PyType_Ready(&CZ_Wrapper_Type_ins) < 0 ||
1313  PyType_Ready(&CRY_Wrapper_Type_ins) < 0 ||
1314  PyType_Ready(&H_Wrapper_Type_ins) < 0 ||
1315  PyType_Ready(&RX_Wrapper_Type_ins) < 0 ||
1316  PyType_Ready(&RY_Wrapper_Type_ins) < 0 ||
1317  PyType_Ready(&RZ_Wrapper_Type_ins) < 0 ||
1318  PyType_Ready(&SX_Wrapper_Type_ins) < 0 ||
1319  PyType_Ready(&SYC_Wrapper_Type_ins) < 0 ||
1320  PyType_Ready(&U1_Wrapper_Type_ins) < 0 ||
1321  PyType_Ready(&U2_Wrapper_Type_ins) < 0 ||
1322  PyType_Ready(&U3_Wrapper_Type_ins) < 0 ||
1323  PyType_Ready(&X_Wrapper_Type_ins) < 0 ||
1324  PyType_Ready(&Y_Wrapper_Type_ins) < 0 ||
1325  PyType_Ready(&Z_Wrapper_Type_ins) < 0 ||
1326  PyType_Ready(&T_Wrapper_Type_ins) < 0 ||
1327  PyType_Ready(&Tdg_Wrapper_Type_ins) < 0 ||
1328  PyType_Ready(&R_Wrapper_Type_ins) < 0 ) {
1329 
1330  Py_DECREF(m);
1331  return NULL;
1332  }
1333 
1334 
1335  Py_INCREF(&Gate_Wrapper_Type);
1336  if (PyModule_AddObject(m, "Gate", (PyObject *) & Gate_Wrapper_Type) < 0) {
1337  Py_DECREF(& Gate_Wrapper_Type);
1338  Py_DECREF(m);
1339  return NULL;
1340  }
1341 
1342 
1343  Py_INCREF(&CH_Wrapper_Type_ins);
1344  if (PyModule_AddObject(m, "CH", (PyObject *) & CH_Wrapper_Type_ins) < 0) {
1345  Py_DECREF(& CH_Wrapper_Type_ins);
1346  Py_DECREF(m);
1347  return NULL;
1348  }
1349 
1350 
1351  Py_INCREF(&CNOT_Wrapper_Type_ins);
1352  if (PyModule_AddObject(m, "CNOT", (PyObject *) & CNOT_Wrapper_Type_ins) < 0) {
1353  Py_DECREF(& CNOT_Wrapper_Type_ins);
1354  Py_DECREF(m);
1355  return NULL;
1356  }
1357 
1358 
1359  Py_INCREF(&CZ_Wrapper_Type_ins);
1360  if (PyModule_AddObject(m, "CZ", (PyObject *) & CZ_Wrapper_Type_ins) < 0) {
1361  Py_DECREF(& CZ_Wrapper_Type_ins);
1362  Py_DECREF(m);
1363  return NULL;
1364  }
1365 
1366  Py_INCREF(&CRY_Wrapper_Type_ins);
1367  if (PyModule_AddObject(m, "CRY", (PyObject *) & CRY_Wrapper_Type_ins) < 0) {
1368  Py_DECREF(& CRY_Wrapper_Type_ins);
1369  Py_DECREF(m);
1370  return NULL;
1371  }
1372 
1373  Py_INCREF(&H_Wrapper_Type_ins);
1374  if (PyModule_AddObject(m, "H", (PyObject *) & H_Wrapper_Type_ins) < 0) {
1375  Py_DECREF(& H_Wrapper_Type_ins);
1376  Py_DECREF(m);
1377  return NULL;
1378  }
1379 
1380  Py_INCREF(&RX_Wrapper_Type_ins);
1381  if (PyModule_AddObject(m, "RX", (PyObject *) & RX_Wrapper_Type_ins) < 0) {
1382  Py_DECREF(& RX_Wrapper_Type_ins);
1383  Py_DECREF(m);
1384  return NULL;
1385  }
1386 
1387  Py_INCREF(&RY_Wrapper_Type_ins);
1388  if (PyModule_AddObject(m, "RY", (PyObject *) & RY_Wrapper_Type_ins) < 0) {
1389  Py_DECREF(& RY_Wrapper_Type_ins);
1390  Py_DECREF(m);
1391  return NULL;
1392  }
1393 
1394  Py_INCREF(&RZ_Wrapper_Type_ins);
1395  if (PyModule_AddObject(m, "RZ", (PyObject *) & RZ_Wrapper_Type_ins) < 0) {
1396  Py_DECREF(& RZ_Wrapper_Type_ins);
1397  Py_DECREF(m);
1398  return NULL;
1399  }
1400 
1401  Py_INCREF(&SX_Wrapper_Type_ins);
1402  if (PyModule_AddObject(m, "SX", (PyObject *) & SX_Wrapper_Type_ins) < 0) {
1403  Py_DECREF(& SX_Wrapper_Type_ins);
1404  Py_DECREF(m);
1405  return NULL;
1406  }
1407 
1408  Py_INCREF(&SYC_Wrapper_Type_ins);
1409  if (PyModule_AddObject(m, "SYC", (PyObject *) & SYC_Wrapper_Type_ins) < 0) {
1410  Py_DECREF(& SYC_Wrapper_Type_ins);
1411  Py_DECREF(m);
1412  return NULL;
1413  }
1414 
1415  Py_INCREF(&U1_Wrapper_Type_ins);
1416  if (PyModule_AddObject(m, "U1", (PyObject *) & U1_Wrapper_Type_ins) < 0) {
1417  Py_DECREF(& U1_Wrapper_Type_ins);
1418  Py_DECREF(m);
1419  return NULL;
1420  }
1421 
1422  Py_INCREF(&U2_Wrapper_Type_ins);
1423  if (PyModule_AddObject(m, "U2", (PyObject *) & U2_Wrapper_Type_ins) < 0) {
1424  Py_DECREF(& U2_Wrapper_Type_ins);
1425  Py_DECREF(m);
1426  return NULL;
1427  }
1428 
1429  Py_INCREF(&U3_Wrapper_Type_ins);
1430  if (PyModule_AddObject(m, "U3", (PyObject *) & U3_Wrapper_Type_ins) < 0) {
1431  Py_DECREF(& U3_Wrapper_Type_ins);
1432  Py_DECREF(m);
1433  return NULL;
1434  }
1435 
1436  Py_INCREF(&X_Wrapper_Type_ins);
1437  if (PyModule_AddObject(m, "X", (PyObject *) & X_Wrapper_Type_ins) < 0) {
1438  Py_DECREF(& X_Wrapper_Type_ins);
1439  Py_DECREF(m);
1440  return NULL;
1441  }
1442 
1443  Py_INCREF(&Y_Wrapper_Type_ins);
1444  if (PyModule_AddObject(m, "Y", (PyObject *) & Y_Wrapper_Type_ins) < 0) {
1445  Py_DECREF(& Y_Wrapper_Type_ins);
1446  Py_DECREF(m);
1447  return NULL;
1448  }
1449 
1450  Py_INCREF(&Z_Wrapper_Type_ins);
1451  if (PyModule_AddObject(m, "Z", (PyObject *) & Z_Wrapper_Type_ins) < 0) {
1452  Py_DECREF(& Z_Wrapper_Type_ins);
1453  Py_DECREF(m);
1454  return NULL;
1455  }
1456 
1457 
1458  Py_INCREF(&T_Wrapper_Type_ins);
1459  if (PyModule_AddObject(m, "T", (PyObject *) & T_Wrapper_Type_ins) < 0) {
1460  Py_DECREF(& T_Wrapper_Type_ins);
1461  Py_DECREF(m);
1462  return NULL;
1463  }
1464 
1465 
1466  Py_INCREF(&Tdg_Wrapper_Type_ins);
1467  if (PyModule_AddObject(m, "Tdg", (PyObject *) & Tdg_Wrapper_Type_ins) < 0) {
1468  Py_DECREF(& Tdg_Wrapper_Type_ins);
1469  Py_DECREF(m);
1470  return NULL;
1471  }
1472 
1473 
1474  Py_INCREF(&R_Wrapper_Type_ins);
1475  if (PyModule_AddObject(m, "R", (PyObject *) & R_Wrapper_Type_ins) < 0) {
1476  Py_DECREF(&R_Wrapper_Type_ins);
1477  Py_DECREF(m);
1478  return NULL;
1479  }
1480 
1481  return m;
1482 }
1483 
1484 
1485 
1486 }
static SYC_Wrapper_Type SYC_Wrapper_Type_ins
static PyObject * Gate_Wrapper_set_Control_Qbit(Gate_Wrapper *self, PyObject *args)
Call to set the target qbit.
Header file for a class representing the T gate.
static PyObject * Gate_Wrapper_getstate(Gate_Wrapper *self)
Method to extract the stored quantum gate in a human-readable data serialized and pickle-able format...
Gate * create_controlled_gate(int qbit_num, int target_qbit, int control_qbit)
parameter_num
[set adaptive gate structure]
Header file for a class for the representation of general gate operations.
Header file for a class representing a rotation gate around the X axis.
virtual Matrix get_matrix()
Call to retrieve the operation matrix.
Definition: Gate.cpp:129
PyMODINIT_FUNC PyInit_gates_Wrapper(void)
Method called when the Python module is initialized.
static PyObject * generic_Gate_Wrapper_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Method called when a python instance of the class qgd_CH_Wrapper is allocated.
Header file for a class representing the X gate.
Header file for a class representing the Y gate.
static RZ_Wrapper_Type RZ_Wrapper_Type_ins
static PyObject * Gate_Wrapper_get_Matrix(Gate_Wrapper *self, PyObject *args, PyObject *kwds)
Call te extract t he matric representation of the gate.
static PyObject * Gate_Wrapper_Extract_Parameters(Gate_Wrapper *self, PyObject *args)
Call to extract the paramaters corresponding to the gate, from a parameter array associated to the ci...
Header file for a class representing a controlled rotation gate around the Y axis.
PyObject_HEAD Gate * gate
Pointer to the C++ class of the CH gate.
static PyModuleDef gates_Wrapper_Module
Structure containing metadata about the module.
static Tdg_Wrapper_Type Tdg_Wrapper_Type_ins
static Z_Wrapper_Type Z_Wrapper_Type_ins
Matrix_real numpy2matrix_real(PyArrayObject *arr)
Call to create a PIC matrix_real representation of a numpy array.
static U2_Wrapper_Type U2_Wrapper_Type_ins
Header file for a class representing the SX axis.
scalar * data
pointer to the stored data
Definition: matrix_base.hpp:48
static PyObject * Gate_Wrapper_get_Gate_Kernel(Gate_Wrapper *self, PyObject *args, PyObject *kwds)
Calculate the matrix of a U3 gate gate corresponding to the given parameters acting on a single qbit ...
Header file for a class representing a CH operation.
static PyObject * Gate_Wrapper_get_Parameter_Num(Gate_Wrapper *self)
Call to get the number of free parameters in the gate.
static CNOT_Wrapper_Type CNOT_Wrapper_Type_ins
PyObject * matrix_real_to_numpy(Matrix_real &mtx)
Call to make a numpy array from an instance of matrix class.
Header file for a class representing the Tdg gate.
static T_Wrapper_Type T_Wrapper_Type_ins
name
Definition: setup.py:33
static PyObject * Gate_Wrapper_get_Parameter_Start_Index(Gate_Wrapper *self)
Call to get the starting index of the parameters in the parameter array corresponding to the circuit ...
static PyObject * controlled_gate_Wrapper_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Method called when a python instance of a controlled gate class is initialized.
static void Gate_Wrapper_dealloc(Gate_Wrapper *self)
Method called when a python instance of the class Gate_Wrapper is destroyed.
static RX_Wrapper_Type RX_Wrapper_Type_ins
Header file for a class representing a CNOT operation.
static PyObject * Gate_Wrapper_get_Target_Qbit(Gate_Wrapper *self)
Call to get the target qbit.
static CRY_Wrapper_Type CRY_Wrapper_Type_ins
static PyObject * Gate_Wrapper_set_Target_Qbit(Gate_Wrapper *self, PyObject *args)
Call to set the target qbit.
static U3_Wrapper_Type U3_Wrapper_Type_ins
Header file for a class representing a rotation gate around the Z axis.
static PyObject * Gate_Wrapper_setstate(Gate_Wrapper *self, PyObject *args)
Call to set the state of quantum gate from a human-readable data serialized and pickle-able format...
Header file for a class representing the Hadamard gate.
static CH_Wrapper_Type CH_Wrapper_Type_ins
static U1_Wrapper_Type U1_Wrapper_Type_ins
static int Gate_Wrapper_init(Gate_Wrapper *self, PyObject *args, PyObject *kwds)
Method called when a python instance of a non-controlled gate class is initialized.
static R_Wrapper_Type R_Wrapper_Type_ins
static Gate_Wrapper_Type_tmp Gate_Wrapper_Type
Header file for a class representing a CZ operation.
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.
Definition: QGDTypes.h:38
static SX_Wrapper_Type SX_Wrapper_Type_ins
static H_Wrapper_Type H_Wrapper_Type_ins
static RY_Wrapper_Type RY_Wrapper_Type_ins
static PyObject * Gate_Wrapper_Wrapper_apply_to(Gate_Wrapper *self, PyObject *args, PyObject *kwds)
Call to apply the gate operation on an input state or matrix.
Class to store data of complex arrays and its properties.
Definition: matrix.h:38
Header file for a class representing a U2 gate.
int size() const
Call to get the number of the allocated elements.
static PyObject * Gate_Wrapper_get_Name(Gate_Wrapper *self)
Extract the optimized parameters.
int get_parameter_num()
Call to get the number of free parameters.
Definition: Gate.cpp:486
static PyObject * Gate_Wrapper_get_Control_Qbit(Gate_Wrapper *self)
Call to get the control qbit (returns with -1 if no control qbit is used in the gate) ...
Header file for a class representing a U3 gate.
static X_Wrapper_Type X_Wrapper_Type_ins
Gate * create_gate(int qbit_num, int target_qbit)
Type definition of the Gate_Wrapper Python class of the gates module.
Header file for a class representing a rotation gate around the X axis.
Base class for the representation of general gate operations.
Definition: Gate.h:73
Header file for a class representing a rotation gate around the Y axis.
static PyMethodDef Gate_Wrapper_methods[]
Structure containing metadata about the methods of class qgd_U3.
static Y_Wrapper_Type Y_Wrapper_Type_ins
Matrix numpy2matrix(PyArrayObject *arr)
Call to create a PIC matrix representation of a numpy array.
static PyMemberDef Gate_Wrapper_members[]
Structure containing metadata about the members of class qgd_CH_Wrapper.
Header file for a class representing the Z gate.
gate_type
Type definition of operation types (also generalized for decomposition classes derived from the class...
Definition: Gate.h:34
virtual void apply_to(Matrix &input, int parallel)
Call to apply the gate on the input array/matrix.
Definition: Gate.cpp:237
PyObject * matrix_to_numpy(Matrix &mtx)
Call to make a numpy array from an instance of matrix class.
Header file for a class representing a U1 gate.
Class to store data of complex arrays and its properties.
Definition: matrix_real.h:39
static PyObject * Gate_Wrapper_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Method called when a python instance of a non-controlled gate class is initialized.
static CZ_Wrapper_Type CZ_Wrapper_Type_ins
Header file for a class representing a Sycamore gate.