Autograd Variational Quantum Circuits' API ****************************************************************************** VQNet is based on the construction of automatic differential operators and some commonly used quantum logic gates, quantum circuits and measurement methods. Automatic differentiation can be used to calculate gradients instead of the quantum circuit parameter-shift method. We can use VQC operators to form complex neural networks like other `Modules`. The virtual machine `QMachine` needs to be defined in `Module`, and the `states` in the machine need to be reset_states based on the input batchsize. Please see the following example for details. .. code-block:: from pyvqnet.nn import Module,Linear,ModuleList from pyvqnet.qnn.vqc.qcircuit import VQC_HardwareEfficientAnsatz,RZZ,RZ from pyvqnet.qnn.vqc import Probability,QMachine from pyvqnet import tensor class QM(Module): def __init__(self, name=""): super().__init__(name) self.linearx = Linear(4,2) self.ansatz = VQC_HardwareEfficientAnsatz(4, ["rx", "RY", "rz"], entangle_gate="cnot", entangle_rules="linear", depth=2) #VQC based RZ on 0 bits self.encode1 = RZ(wires=0) #VQC based RZ on 1 bit self.encode2 = RZ(wires=1) #VQC-based probability measurement on 0, 2 bits self.measure = Probability(wires=[0,2]) #Quantum device QMachine, uses 4 bits. self.device = QMachine(4) def forward(self, x, *args, **kwargs): #States must be reset to the same batchsize as the input. self.device.reset_states(x.shape[0]) y = self.linearx(x) #Encode the input to the RZ gate. Note that the input must be of shape [batchsize,1] self.encode1(params = y[:, [0]],q_machine = self.device,) #Encode the input to the RZ gate. Note that the input must be of shape [batchsize,1] self.encode2(params = y[:, [1]],q_machine = self.device,) self.ansatz(q_machine =self.device) return self.measure(q_machine =self.device) bz=3 inputx = tensor.arange(1.0,bz*4+1).reshape([bz,4]) inputx.requires_grad= True #Define like other Modules qlayer = QM() #Prequel y = qlayer(inputx) #reversepass y.backward() print(y) Simulator ======================================= QMachine ------------------------------- .. py:class:: pyvqnet.qnn.vqc.QMachine(num_wires, dtype=pyvqnet.kcomplex64) A simulator class for variable quantum computing, including statevectors whose states attribute is a quantum circuit. :param num_wires: number of qubits。 :param dtype: the data type of the calculated data, the default is pyvqnet.kcomplex64, and the corresponding parameter precision is pyvqnet.kfloat32 :return: Output QMachine。 Example:: from pyvqnet.qnn.vqc import QMachine qm = QMachine(4) print(qm.states) # [[[[[1.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]] # [[[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]]]] .. py:method:: reset_states(batchsize) Reinitialize the initial state in the simulator and broadcast it to (batchsize,[2]**num_qubits) dimensions to adapt to batch data training. :param batchsize: batch processing size. Quantum Gates and Quantum Gates's Operation ============================================= i ------------------------------- .. py:function:: pyvqnet.qnn.vqc.i(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates I to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import i,QMachine qm = QMachine(4) i(q_machine=qm, wires=1) print(qm.states) # [[[[[1.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]] # [[[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]]]] I --------------------------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.I(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define an I logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64, or pyvqnet.kcomplex128, corresponding to float input or double input parameters respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import I,QMachine device = QMachine(4) layer = I(wires=0) batchsize=1 device.reset_states(1) layer(q_machine = device) print(device.states) hadamard --------------------------------------------------------------- .. py:function:: pyvqnet.qnn.vqc.hadamard(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates hadamard to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import hadamard,QMachine qm = QMachine(4) hadamard(q_machine=qm, wires=1) print(qm.states) # [[[[[0.7071068+0.j 0. +0.j] # [0. +0.j 0. +0.j]] # # [[0.7071068+0.j 0. +0.j] # [0. +0.j 0. +0.j]]] # # # [[[0. +0.j 0. +0.j] # [0. +0.j 0. +0.j]] # # [[0. +0.j 0. +0.j] # [0. +0.j 0. +0.j]]]]] Hadamard --------------------------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.Hadamard(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define a Hadamard logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64, or pyvqnet.kcomplex128, corresponding to float input or double input parameters respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import Hadamard,QMachine device = QMachine(4) layer = Hadamard(wires=0) batchsize=1 device.reset_states(1) layer(q_machine = device) print(device.states) t ---------------- .. py:function:: pyvqnet.qnn.vqc.t(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates t to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import t,QMachine qm = QMachine(4) t(q_machine=qm, wires=1) print(qm.states) # [[[[[1.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]] # # # [[[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]]]] T --------------------------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.T(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define a T logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64, or pyvqnet.kcomplex128, corresponding to float input or double input parameters respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import T,QMachine device = QMachine(4) layer = T(wires=0) batchsize=1 device.reset_states(1) layer(q_machine = device) print(device.states) s ------ .. py:function:: pyvqnet.qnn.vqc.s(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates s to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import s,QMachine qm = QMachine(4) s(q_machine=qm, wires=1) print(qm.states) # [[[[[1.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]] # # # [[[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]]]] S -------------------------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.S(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define an S logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64, or pyvqnet.kcomplex128, corresponding to float input or double input parameters respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import S,QMachine device = QMachine(4) layer = S(wires=0) batchsize=1 device.reset_states(1) layer(q_machine = device) print(device.states) paulix --------------- .. py:function:: pyvqnet.qnn.vqc.paulix(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates paulix to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import paulix,QMachine qm = QMachine(4) paulix(q_machine=qm, wires=1) print(qm.states) # [[[[[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[1.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]] # # # [[[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]]]] PauliX --------------------------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.PauliX(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define a PauliX logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64, or pyvqnet.kcomplex128, corresponding to float input or double input parameters respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import PauliX,QMachine device = QMachine(4) layer = PauliX(wires=0) batchsize=1 device.reset_states(1) layer(q_machine = device) print(device.states) pauliy ---------------- .. py:function:: pyvqnet.qnn.vqc.pauliy(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates pauliy to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import pauliy,QMachine qm = QMachine(4) pauliy(q_machine=qm, wires=1) print(qm.states) # [[[[[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+1.j 0.+0.j] # [0.+0.j 0.+0.j]]] # # # [[[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]]]] PauliY --------------------------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.PauliY(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define a PauliY logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64, or pyvqnet.kcomplex128, corresponding to float input or double input parameters respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import PauliY,QMachine device = QMachine(4) layer = PauliY(wires=0) batchsize=1 device.reset_states(1) layer(q_machine = device) print(device.states) pauliz ----------------- .. py:function:: pyvqnet.qnn.vqc.pauliz(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates pauliz to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import pauliz,QMachine qm = QMachine(4) pauliz(q_machine=qm, wires=1) print(qm.states) # [[[[[1.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]] # # # [[[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]]]] PauliZ --------------------------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.PauliZ(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define a PauliZ logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64, or pyvqnet.kcomplex128, corresponding to float input or double input parameters respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import PauliZ,QMachine device = QMachine(4) layer = PauliZ(wires=0) batchsize=1 device.reset_states(1) layer(q_machine = device) print(device.states) x1 -------- .. py:function:: pyvqnet.qnn.vqc.x1(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates x1 to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import x1,QMachine qm = QMachine(4) x1(q_machine=qm, wires=1) print(qm.states) # [[[[[0.7071068+0.j 0. +0.j ] # [0. +0.j 0. +0.j ]] # # [[0. -0.7071068j 0. +0.j ] # [0. +0.j 0. +0.j ]]] # # # [[[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]] # # [[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]]]]] X1 --------------------------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.X1(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define an X1 logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64, or pyvqnet.kcomplex128, corresponding to float input or double input parameters respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import X1,QMachine device = QMachine(4) layer = X1(wires=0) batchsize=1 device.reset_states(1) layer(q_machine = device) print(device.states) y1 ----------------- .. py:function:: pyvqnet.qnn.vqc.y1(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates y1 to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import y1,QMachine qm = QMachine(4) y1(q_machine=qm, wires=1) print(qm.states) # [[[[[0.7071068+0.j 0. +0.j] # [0. +0.j 0. +0.j]] # # [[0.7071068+0.j 0. +0.j] # [0. +0.j 0. +0.j]]] # # # [[[0. +0.j 0. +0.j] # [0. +0.j 0. +0.j]] # # [[0. +0.j 0. +0.j] # [0. +0.j 0. +0.j]]]]] Y1 --------------------------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.Y1(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define an Y1 logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64, or pyvqnet.kcomplex128, corresponding to float input or double input parameters respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import Y1,QMachine device = QMachine(4) layer = Y1(wires=0) batchsize=1 device.reset_states(1) layer(q_machine = device) print(device.states) z1 --------------------------- .. py:function:: pyvqnet.qnn.vqc.z1(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates z1 to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import z1,QMachine qm = QMachine(4) z1(q_machine=qm, wires=1) print(qm.states) # [[[[[0.7071068-0.7071068j 0. +0.j ] # [0. +0.j 0. +0.j ]] # # [[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]]] # # # [[[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]] # # [[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]]]]] Z1 --------------------------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.Z1(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define an Z1 logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64, or pyvqnet.kcomplex128, corresponding to float input or double input parameters respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import Z1,QMachine device = QMachine(4) layer = Z1(wires=0) batchsize=1 device.reset_states(1) layer(q_machine = device) print(device.states) rx ---- .. py:function:: pyvqnet.qnn.vqc.rx(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates rx to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import rx,QMachine from pyvqnet.tensor import QTensor qm = QMachine(4) rx(q_machine=qm, wires=1,params=QTensor([0.5])) print(qm.states) # [[[[[0.9689124+0.j 0. +0.j ] # [0. +0.j 0. +0.j ]] # # [[0. -0.247404j 0. +0.j ] # [0. +0.j 0. +0.j ]]] # # # [[[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]] # # [[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]]]]] RX --------------------------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.RX(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define an RX logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64, or pyvqnet.kcomplex128, corresponding to float input or double input parameters respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import RX,QMachine device = QMachine(4) layer = RX(has_params= True, trainable= True, wires=0) batchsize = 2 device.reset_states(batchsize) layer(q_machine = device) print(device.states) ry ------------ .. py:function:: pyvqnet.qnn.vqc.ry(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates ry to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import ry,QMachine from pyvqnet.tensor import QTensor qm = QMachine(4) ry(q_machine=qm, wires=1,params=QTensor([0.5])) print(qm.states) # [[[[[0.9689124+0.j 0. +0.j] # [0. +0.j 0. +0.j]] # # [[0.247404 +0.j 0. +0.j] # [0. +0.j 0. +0.j]]] # # # [[[0. +0.j 0. +0.j] # [0. +0.j 0. +0.j]] # # [[0. +0.j 0. +0.j] # [0. +0.j 0. +0.j]]]]] RY --------------------------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.RY(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define an RY logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64, or pyvqnet.kcomplex128, corresponding to float input or double input parameters respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import RY,QMachine device = QMachine(4) layer = RY(has_params= True, trainable= True, wires=0) batchsize = 2 device.reset_states(batchsize) layer(q_machine = device) print(device.states) rz ----- .. py:function:: pyvqnet.qnn.vqc.rz(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates rz to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import rz,QMachine from pyvqnet.tensor import QTensor qm = QMachine(4) rz(q_machine=qm, wires=1,params=QTensor([0.5])) print(qm.states) # [[[[[0.9689124-0.247404j 0. +0.j ] # [0. +0.j 0. +0.j ]] # # [[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]]] # # # [[[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]] # # [[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]]]]] RZ --------------------------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.RZ(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define an RZ logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64, or pyvqnet.kcomplex128, corresponding to float input or double input parameters respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import RZ,QMachine device = QMachine(4) layer = RZ(has_params= True, trainable= True, wires=0) batchsize = 2 device.reset_states(batchsize) layer(q_machine = device) print(device.states) crx ------------- .. py:function:: pyvqnet.qnn.vqc.crx(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates crx to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import QMachine import pyvqnet.qnn.vqc as vqc from pyvqnet.tensor import QTensor qm = QMachine(4) vqc.crx(q_machine=qm,wires=[0,2], params=QTensor([0.5])) print(qm.states) # [[[[[1.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]] # # # [[[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]]]] CRX --------------------------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.CRX(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define a CRX logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64, or pyvqnet.kcomplex128, corresponding to float input or double input parameters respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import CRX,QMachine device = QMachine(4) layer = CRX(has_params= True, trainable= True, wires=[0,2]) batchsize = 2 device.reset_states(batchsize) layer(q_machine = device) print(device.states) cry ----------------- .. py:function:: pyvqnet.qnn.vqc.cry(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates cry to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import QMachine import pyvqnet.qnn.vqc as vqc from pyvqnet.tensor import QTensor qm = QMachine(4) vqc.cry(q_machine=qm,wires=[0,2], params=QTensor([0.5])) print(qm.states) # [[[[[1.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]] # # # [[[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]]]] CRY --------------------------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.CRY(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define a CRY logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64, or pyvqnet.kcomplex128, corresponding to float input or double input parameters respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import CRY,QMachine device = QMachine(4) layer = CRY(has_params= True, trainable= True, wires=[0,2]) batchsize = 2 device.reset_states(batchsize) layer(q_machine = device) print(device.states) crz ------------ .. py:function:: pyvqnet.qnn.vqc.crz(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates crz to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import QMachine import pyvqnet.qnn.vqc as vqc from pyvqnet.tensor import QTensor qm = QMachine(4) vqc.crz(q_machine=qm,wires=[0,2], params=QTensor([0.5])) print(qm.states) # [[[[[1.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]] # # # [[[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]]]] CRZ --------------------------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.CRZ(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define a CRZ logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64, or pyvqnet.kcomplex128, corresponding to float input or double input parameters respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import CRZ,QMachine device = QMachine(4) layer = CRZ(has_params= True, trainable= True, wires=[0,2]) batchsize = 2 device.reset_states(batchsize) layer(q_machine = device) print(device.states) u1 ------------------------------- .. py:function:: pyvqnet.qnn.vqc.u1(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates u1 to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import u1,QMachine from pyvqnet.tensor import QTensor qm = QMachine(4) u1(q_machine=qm, wires=1,params=QTensor([24.0])) print(qm.states) # [[[[1.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]] # # # [[[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]]]] U1 -------------------------------------- .. py:class:: pyvqnet.qnn.vqc.U1(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define a U1 logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64, or pyvqnet.kcomplex128, corresponding to float input or double input parameters respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import U1,QMachine device = QMachine(4) layer = U1(has_params= True, trainable= True, wires=0) batchsize = 2 device.reset_states(batchsize) layer(q_machine = device) print(device.states) u2 ------------------ .. py:function:: pyvqnet.qnn.vqc.u2(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates u2 to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import u2,QMachine from pyvqnet.tensor import QTensor qm = QMachine(4) u2(q_machine=qm, wires=1,params=QTensor([[24.0,-3]])) print(qm.states) # [[[[[0.7071068+0.j 0. +0.j ] # [0. +0.j 0. +0.j ]] # # [[0.2999398-0.6403406j 0. +0.j ] # [0. +0.j 0. +0.j ]]] # # # [[[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]] # # [[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]]]]] U2 ----------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.U2(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define a U2 logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64, or pyvqnet.kcomplex128, corresponding to float input or double input parameters respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import U2,QMachine device = QMachine(4) layer = U2(has_params= True, trainable= True, wires=0) batchsize = 2 device.reset_states(batchsize) layer(q_machine = device) print(device.states) u3 ------ .. py:function:: pyvqnet.qnn.vqc.u3(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates u3 to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import u3,QMachine from pyvqnet.tensor import QTensor qm = QMachine(4) u3(q_machine=qm, wires=1,params=QTensor([[24.0,-3,1]])) print(qm.states) # [[[[[0.843854 +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]] # # [[0.5312032+0.0757212j 0. +0.j ] # [0. +0.j 0. +0.j ]]] # # # [[[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]] # # [[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]]]]] U3 ----------------------------------------- .. py:class:: pyvqnet.qnn.vqc.U3(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define a U3 logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64, or pyvqnet.kcomplex128, corresponding to float input or double input parameters respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import U3,QMachine device = QMachine(4) layer = U3(has_params= True, trainable= True, wires=0) batchsize = 2 device.reset_states(batchsize) layer(q_machine = device) print(device.states) cy --------------------------------------------------------------- .. py:function:: pyvqnet.qnn.vqc.cy(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates cy to statevectors in ``q_machine``. :param q_machine: Quantum virtual machine device. :param wires: Qubit index. :param params: Parameter matrix, default is None. :param use_dagger: Whether to use conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import cy,QMachine qm = QMachine(4) cy(q_machine=qm,wires=(1,0)) print(qm.states) # [[[[[1.+0.j,0.+0.j], # [0.+0.j,0.+0.j]], # [[0.+0.j,0.+0.j], # [0.+0.j,0.+0.j]]], # [[[0.+0.j,0.+0.j], # [0.+0.j,0.+0.j]], # [[0.+0.j,0.+0.j], # [0.+0.j,0.+0.j]]]]] CY --------------------------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.CY(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define a CY logic category. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it comes with parameters to be trained. If this layer uses external input data to construct a logic gate matrix, set it to False. If the parameters to be trained need to be initialized from this layer, it will be True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64, or pyvqnet.kcomplex128, corresponding to float input or double input parameters respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import CY,QMachine device = QMachine(4) layer = CY(wires=[0,1]) batchsize = 2 device.reset_states(batchsize) layer(q_machine = device) print(device.states) cnot ------------------- .. py:function:: pyvqnet.qnn.vqc.cnot(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates cnot to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import cnot,QMachine qm = QMachine(4) cnot(q_machine=qm,wires=[1,0]) print(qm.states) # [[[[[1.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]] # # # [[[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]]]] CNOT ------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.CNOT(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define a CNOT logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64 or pyvqnet.kcomplex128, corresponding to float input or double input parameter respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import CNOT,QMachine device = QMachine(4) layer = CNOT(wires=[0,1]) batchsize = 2 device.reset_states(batchsize) layer(q_machine = device) print(device.states) cr ------------------- .. py:function:: pyvqnet.qnn.vqc.cr(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates cr to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import cr,QMachine from pyvqnet.tensor import QTensor qm = QMachine(4) cr(q_machine=qm,wires=[1,0],params=QTensor([0.5])) print(qm.states) # [[[[[1.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]] # # # [[[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]]]] CR --------------------------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.CR(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define a CR logic gate. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64 or pyvqnet.kcomplex128, corresponding to float input or double input parameter respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import CR,QMachine device = QMachine(4) layer = CR(has_params= True, trainable= True, wires=[0,2]) batchsize = 2 device.reset_states(batchsize) layer(q_machine = device) print(device.states) iswap --------------- .. py:function:: pyvqnet.qnn.vqc.iswap(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates iswap to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import iswap,QMachine from pyvqnet.tensor import QTensor qm = QMachine(4) iswap(q_machine=qm,wires=[1,0],params=QTensor([0.5])) print(qm.states) # [[[[[1.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]] # # # [[[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]]]] swap ------------------- .. py:function:: pyvqnet.qnn.vqc.swap(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates swap to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import swap,QMachine qm = QMachine(4) swap(q_machine=qm,wires=[1,0]) print(qm.states) # [[[[[1.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]] # # # [[[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]]]] SWAP ---------------------------------------- .. py:class:: pyvqnet.qnn.vqc.SWAP(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define a SWAP logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64, or pyvqnet.kcomplex128, corresponding to float input or double input parameters respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import SWAP,QMachine device = QMachine(4) layer = SWAP(wires=[0,1]) batchsize = 2 device.reset_states(batchsize) layer(q_machine = device) print(device.states) cswap --------------------------------------------------------------- .. py:function:: pyvqnet.qnn.vqc.cswap(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates cswap to statevectors in ``q_machine``. :param q_machine: Quantum virtual machine device. :param wires: Qubit index. :param params: Parameter matrix, default is None. :param use_dagger: Whether to use conjugate transpose, the default is False. :return: Output QTensor. Example:: from pyvqnet.qnn.vqc import cswap,QMachine qm = QMachine(4) cswap(q_machine=qm,wires=[1,0,3],) print(qm.states) # [[[[[1.+0.j,0.+0.j], # [0.+0.j,0.+0.j]], # [[0.+0.j,0.+0.j], # [0.+0.j,0.+0.j]]], # [[[0.+0.j,0.+0.j], # [0.+0.j,0.+0.j]], # [[0.+0.j,0.+0.j], # [0.+0.j,0.+0.j]]]]] CSWAP ------------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.CSWAP(has_params: bool = False, trainable: bool = False, init_params=None, wires=None, dtype=pyvqnet.kcomplex64, use_dagger=False) Define a SWAP logic gate class. .. math:: CSWAP = \begin{bmatrix} 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \end{bmatrix}. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it comes with parameters to be trained. If this layer uses external input data to construct a logic gate matrix, set it to False. If the parameters to be trained need to be initialized from this layer, it will be True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64, or pyvqnet.kcomplex128, corresponding to float input or double input parameters respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import CSWAP,QMachine device = QMachine(4) layer = CSWAP(wires=[0,1,2]) batchsize = 2 device.reset_states(batchsize) layer(q_machine = device) print(device.states) # [[[[[1.+0.j,0.+0.j], # [0.+0.j,0.+0.j]], # [[0.+0.j,0.+0.j], # [0.+0.j,0.+0.j]]], # [[[0.+0.j,0.+0.j], # [0.+0.j,0.+0.j]], # [[0.+0.j,0.+0.j], # [0.+0.j,0.+0.j]]]], # [[[[1.+0.j,0.+0.j], # [0.+0.j,0.+0.j]], # [[0.+0.j,0.+0.j], # [0.+0.j,0.+0.j]]], # [[[0.+0.j,0.+0.j], # [0.+0.j,0.+0.j]], # [[0.+0.j,0.+0.j], # [0.+0.j,0.+0.j]]]]] cz ----------- .. py:function:: pyvqnet.qnn.vqc.cz(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates cz to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import cz,QMachine qm = QMachine(4) cz(q_machine=qm,wires=[1,0]) print(qm.states) # [[[[[1.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]] # # # [[[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]]]] CZ -------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.CZ(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define a CZ logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64 or pyvqnet.kcomplex128, corresponding to float input or double input parameter respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import CZ,QMachine device = QMachine(4) layer = CZ(wires=[0,1]) batchsize = 2 device.reset_states(batchsize) layer(q_machine = device) print(device.states) rxx ---------------- .. py:function:: pyvqnet.qnn.vqc.rxx(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates rxx to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import rxx,QMachine from pyvqnet.tensor import QTensor qm = QMachine(4) rxx(q_machine=qm,wires=[1,0],params=QTensor([0.2])) print(qm.states) # [[[[[0.9950042+0.j 0. +0.j ] # [0. +0.j 0. +0.j ]] # # [[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]]] # # # [[[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]] # # [[0. -0.0998334j 0. +0.j ] # [0. +0.j 0. +0.j ]]]]] RXX ------------------------------------------ .. py:class:: pyvqnet.qnn.vqc.RXX(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define an RXX logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64 or pyvqnet.kcomplex128, corresponding to float input or double input parameter respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import RXX,QMachine device = QMachine(4) layer = RXX(has_params= True, trainable= True, wires=[0,2]) batchsize = 2 device.reset_states(batchsize) layer(q_machine = device) print(device.states) ryy --------------- .. py:function:: pyvqnet.qnn.vqc.ryy(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates ryy to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import ryy,QMachine from pyvqnet.tensor import QTensor qm = QMachine(4) ryy(q_machine=qm,wires=[1,0],params=QTensor([0.2])) print(qm.states) # [[[[[0.9950042+0.j 0. +0.j ] # [0. +0.j 0. +0.j ]] # # [[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]]] # # # [[[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]] # # [[0. +0.0998334j 0. +0.j ] # [0. +0.j 0. +0.j ]]]]] RYY ------------------------------------------ .. py:class:: pyvqnet.qnn.vqc.RYY(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define an RYY logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64 or pyvqnet.kcomplex128, corresponding to float input or double input parameter respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import RYY,QMachine device = QMachine(4) layer = RYY(has_params= True, trainable= True, wires=[0,2]) batchsize = 2 device.reset_states(batchsize) layer(q_machine = device) print(device.states) rzz --------------- .. py:function:: pyvqnet.qnn.vqc.rzz(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates rzz to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import rzz,QMachine from pyvqnet.tensor import QTensor qm = QMachine(4) rzz(q_machine=qm,wires=[1,0],params=QTensor([0.2])) print(qm.states) # [[[[[0.9950042-0.0998334j 0. +0.j ] # [0. +0.j 0. +0.j ]] # # [[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]]] # # # [[[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]] # # [[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]]]]] RZZ ------------------------------------------ .. py:class:: pyvqnet.qnn.vqc.RZZ(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define an RZZ logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64 or pyvqnet.kcomplex128, corresponding to float input or double input parameter respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import RZZ,QMachine device = QMachine(4) layer = RZZ(has_params= True, trainable= True, wires=[0,2]) batchsize = 2 device.reset_states(batchsize) layer(q_machine = device) print(device.states) rzx ------------- .. py:function:: pyvqnet.qnn.vqc.rzx(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates rzx to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import rzx,QMachine from pyvqnet.tensor import QTensor qm = QMachine(4) rzx(q_machine=qm,wires=[1,0],params=QTensor([0.2])) print(qm.states) # [[[[[0.9950042+0.j 0. +0.j ] # [0. +0.j 0. +0.j ]] # # [[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]]] # # # [[[0. -0.0998334j 0. +0.j ] # [0. +0.j 0. +0.j ]] # # [[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]]]]] RZX ------------------------------------------ .. py:class:: pyvqnet.qnn.vqc.RZX(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define an RZX logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64 or pyvqnet.kcomplex128, corresponding to float input or double input parameter respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import RZX,QMachine device = QMachine(4) layer = RZX(has_params= True, trainable= True, wires=[0,2]) batchsize = 2 device.reset_states(batchsize) layer(q_machine = device) print(device.states) toffoli -------------------------- .. py:function:: pyvqnet.qnn.vqc.toffoli(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates toffoli to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. :return: Output QTensor. Example:: from pyvqnet.qnn.vqc import toffoli,QMachine qm = QMachine(4) toffoli(q_machine=qm,wires=[0,1,2]) print(qm.states) # [[[[[1.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]] # # # [[[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]]]] Toffoli ----------------------------------- .. py:class:: pyvqnet.qnn.vqc.Toffoli(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define a Toffoli logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64 or pyvqnet.kcomplex128, corresponding to float input or double input parameter respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import Toffoli,QMachine device = QMachine(4) layer = Toffoli( wires=[0,2,1]) batchsize = 2 device.reset_states(batchsize) layer(q_machine = device) print(device.states) isingxx ---------------------- .. py:function:: pyvqnet.qnn.vqc.isingxx(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates isingxx to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. :return: Output QTensor. Example:: from pyvqnet.qnn.vqc import QMachine import pyvqnet.qnn.vqc as vqc from pyvqnet.tensor import QTensor qm = QMachine(4) vqc.isingxx(q_machine=qm,wires=[0,1], params = QTensor([0.5])) print(qm.states) # [[[[[0.9689124+0.j 0. +0.j ] # [0. +0.j 0. +0.j ]] # # [[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]]] # # # [[[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]] # # [[0. -0.247404j 0. +0.j ] # [0. +0.j 0. +0.j ]]]]] IsingXX --------------------------------------- .. py:class:: pyvqnet.qnn.vqc.IsingXX(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define an IsingXX logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64 or pyvqnet.kcomplex128, corresponding to float input or double input parameter respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import IsingXX,QMachine device = QMachine(4) layer = IsingXX(has_params= True, trainable= True, wires=[0,2]) batchsize = 2 device.reset_states(batchsize) layer(q_machine = device) print(device.states) isingyy ------------------- .. py:function:: pyvqnet.qnn.vqc.isingyy(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates isingyy to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. :return: Output QTensor. Example:: from pyvqnet.qnn.vqc import QMachine import pyvqnet.qnn.vqc as vqc from pyvqnet.tensor import QTensor qm = QMachine(4) vqc.isingyy(q_machine=qm,wires=[0,1], params = QTensor([0.5])) print(qm.states) # [[[[[0.9689124+0.j 0. +0.j ] # [0. +0.j 0. +0.j ]] # # [[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]]] # # # [[[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]] # # [[0. +0.247404j 0. +0.j ] # [0. +0.j 0. +0.j ]]]]] IsingYY --------------------------------------- .. py:class:: pyvqnet.qnn.vqc.IsingYY(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define an IsingYY logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64 or pyvqnet.kcomplex128, corresponding to float input or double input parameter respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import IsingYY,QMachine device = QMachine(4) layer = IsingYY(has_params= True, trainable= True, wires=[0,2]) batchsize = 2 device.reset_states(batchsize) layer(q_machine = device) print(device.states) isingzz --------------------- .. py:function:: pyvqnet.qnn.vqc.isingzz(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates isingzz to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. :return: Output QTensor. Example:: from pyvqnet.qnn.vqc import QMachine import pyvqnet.qnn.vqc as vqc from pyvqnet.tensor import QTensor qm = QMachine(4) vqc.isingzz(q_machine=qm,wires=[0,1], params = QTensor([0.5])) print(qm.states) # [[[[[0.9689124-0.247404j 0. +0.j ] # [0. +0.j 0. +0.j ]] # # [[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]]] # # # [[[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]] # # [[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]]]]] IsingZZ --------------------------------------- .. py:class:: pyvqnet.qnn.vqc.IsingZZ(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define an IsingZZ logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64 or pyvqnet.kcomplex128, corresponding to float input or double input parameter respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import IsingZZ,QMachine device = QMachine(4) layer = IsingZZ(has_params= True, trainable= True, wires=[0,2]) batchsize = 2 device.reset_states(batchsize) layer(q_machine = device) print(device.states) isingxy --------------------- .. py:function:: pyvqnet.qnn.vqc.isingxy(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates isingxy to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. :return: Output QTensor. Example:: from pyvqnet.qnn.vqc import QMachine import pyvqnet.qnn.vqc as vqc from pyvqnet.tensor import QTensor qm = QMachine(4) vqc.isingxy(q_machine=qm,wires=[0,1], params = QTensor([0.5])) print(qm.states) # [[[[[1.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]] # # # [[[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]]]] IsingXY --------------------------------------- .. py:class:: pyvqnet.qnn.vqc.IsingXY(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define an IsingXY logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64 or pyvqnet.kcomplex128, corresponding to float input or double input parameter respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import IsingXY,QMachine device = QMachine(4) layer = IsingXY(has_params= True, trainable= True, wires=[0,2]) batchsize = 2 device.reset_states(batchsize) layer(q_machine = device) print(device.states) phaseshift --------------- .. py:function:: pyvqnet.qnn.vqc.phaseshift(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates phaseshift to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. :return: Output QTensor. Example:: from pyvqnet.qnn.vqc import QMachine import pyvqnet.qnn.vqc as vqc from pyvqnet.tensor import QTensor qm = QMachine(4) vqc.phaseshift(q_machine=qm,wires=[0], params = QTensor([0.5])) print(qm.states) # [[[[[1.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]] # # # [[[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]]]] PhaseShift ----------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.PhaseShift(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define a PhaseShift logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64 or pyvqnet.kcomplex128, corresponding to float input or double input parameter respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import PhaseShift,QMachine device = QMachine(4) layer = PhaseShift(has_params= True, trainable= True, wires=1) batchsize = 2 device.reset_states(batchsize) layer(q_machine = device) print(device.states) multirz -------------------- .. py:function:: pyvqnet.qnn.vqc.multirz(q_machine, wires, params=None, use_dagger=False) Acting quantum logic gates on state vectors in q_machine multirz. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. :return: Output QTensor. Example:: from pyvqnet.qnn.vqc import QMachine import pyvqnet.qnn.vqc as vqc from pyvqnet.tensor import QTensor qm = QMachine(4) vqc.multirz(q_machine=qm,wires=[0, 1], params = QTensor([0.5])) print(qm.states) # [[[[[0.9689124-0.247404j 0. +0.j ] # [0. +0.j 0. +0.j ]] # # [[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]]] # # # [[[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]] # # [[0. +0.j 0. +0.j ] # [0. +0.j 0. +0.j ]]]]] MultiRZ ------------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.MultiRZ(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define a MultiRZ logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64 or pyvqnet.kcomplex128, corresponding to float input or double input parameter respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import MultiRZ,QMachine device = QMachine(4) layer = MultiRZ(has_params= True, trainable= True, wires=[0,2]) batchsize = 2 device.reset_states(batchsize) layer(q_machine = device) print(device.states) sdg -------------- .. py:function:: pyvqnet.qnn.vqc.sdg(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates sdg to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import QMachine import pyvqnet.qnn.vqc as vqc from pyvqnet.tensor import QTensor qm = QMachine(4) vqc.sdg(q_machine=qm,wires=[0]) print(qm.states) # [[[[[1.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]] # # # [[[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]]]] SDG ---------------------------------------- .. py:class:: pyvqnet.qnn.vqc.SDG(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define an SDG logic category. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64 or pyvqnet.kcomplex128, corresponding to float input or double input parameter respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import SDG,QMachine device = QMachine(4) layer = SDG(wires=0) batchsize=1 device.reset_states(1) layer(q_machine = device) print(device.states) tdg ------------------ .. py:function:: pyvqnet.qnn.vqc.tdg(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates tdg to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import QMachine import pyvqnet.qnn.vqc as vqc from pyvqnet.tensor import QTensor qm = QMachine(4) vqc.tdg(q_machine=qm,wires=[0]) print(qm.states) # [[[[[1.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]] # # # [[[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]]]] TDG --------------------------------- .. py:class:: pyvqnet.qnn.vqc.TDG(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define a TDG logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64 or pyvqnet.kcomplex128, corresponding to float input or double input parameter respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import TDG,QMachine device = QMachine(4) layer = TDG(wires=0) batchsize=1 device.reset_states(1) layer(q_machine = device) print(device.states) controlledphaseshift ----------------------------- .. py:function:: pyvqnet.qnn.vqc.controlledphaseshift(q_machine, wires, params=None, use_dagger=False) Apply quantum logic gates controlledphaseshift to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import QMachine import pyvqnet.qnn.vqc as vqc from pyvqnet.tensor import QTensor qm = QMachine(4) for i in range(4): vqc.hadamard(q_machine=qm, wires=i) vqc.controlledphaseshift(q_machine=qm,params=QTensor([0.5]),wires=[0,1]) print(qm.states) # [[[[[0.25 +0.j 0.25 +0.j ] # [0.25 +0.j 0.25 +0.j ]] # # [[0.25 +0.j 0.25 +0.j ] # [0.25 +0.j 0.25 +0.j ]]] # # # [[[0.25 +0.j 0.25 +0.j ] # [0.25 +0.j 0.25 +0.j ]] # # [[0.2193956+0.1198564j 0.2193956+0.1198564j] # [0.2193956+0.1198564j 0.2193956+0.1198564j]]]]] ControlledPhaseShift ---------------------------------------- .. py:class:: pyvqnet.qnn.vqc.ControlledPhaseShift(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define a ControlledPhaseShift logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64 or pyvqnet.kcomplex128, corresponding to float input or double input parameter respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import ControlledPhaseShift,QMachine device = QMachine(4) layer = ControlledPhaseShift(has_params= True, trainable= True, wires=[0,2]) batchsize = 2 device.reset_states(batchsize) layer(q_machine = device) print(device.states) multicnot --------------------------------- .. py:function:: pyvqnet.qnn.vqc.multicnot(q_machine, wires, params=None, use_dagger=False) Acting quantum logic gates on state vectors in q_machine multicnot. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import QMachine import pyvqnet.qnn.vqc as vqc from pyvqnet.tensor import QTensor qm = QMachine(4) vqc.multicnot(q_machine=qm, wires=[0, 1]) print(qm.states) # [[[[[1.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]] # # # [[[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]]]] MultiCnot ------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.MultiCnot(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define a MultiCnot logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64 or pyvqnet.kcomplex128, corresponding to float input or double input parameter respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import MultiCnot,QMachine device = QMachine(4) layer = MultiCnot(wires=[0,2]) batchsize = 2 device.reset_states(batchsize) layer(q_machine = device) print(device.states) multixcnot ---------------- .. py:function:: pyvqnet.qnn.vqc.multixcnot(q_machine, wires, params=None, use_dagger=False) Acting quantum logic gates on state vectors in q_machine multixcnot. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import QMachine import pyvqnet.qnn.vqc as vqc from pyvqnet.tensor import QTensor qm = QMachine(4) vqc.multixcnot(q_machine=qm, wires=[0, 1]) print(qm.states) # [[[[[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[1.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]] # # # [[[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]]]] MultiXcnot --------------------------------------- .. py:class:: pyvqnet.qnn.vqc.MultiXcnot(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False) Define a MultiXcnot logic gate class. :param has_params: Whether there are parameters, such as RX, RY and other gates need to be set to True, those without parameters need to be set to False, the default is False. :param trainable: Whether it contains parameters to be trained. If the layer uses external input data to construct a logic gate matrix, set it to False. If it contains parameters to be trained, it is True. The default is False. :param init_params: Initialization parameters, used to encode classic data QTensor, default is None,If it is a parameter-containing logic gate with p parameters, the input data dimension needs to be [1,p] or [p]. :param wires: Bit index of wire action, default is None. :param dtype: The data precision of the internal matrix of the logic gate can be set to pyvqnet.kcomplex64 or pyvqnet.kcomplex128, corresponding to float input or double input parameter respectively. :param use_dagger: Whether to use the transposed conjugate version of this gate, the default is False. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import MultiXcnot,QMachine device = QMachine(4) layer = MultiXcnot(wires=[0,2]) batchsize = 2 device.reset_states(batchsize) layer(q_machine = device) print(device.states) multicontrolledx --------------------------------------------------------------- .. py:function:: pyvqnet.qnn.vqc.multicontrolledx(q_machine, wires, params=None, use_dagger=False,control_values=None) Apply quantum logic gates multicontrolledx to statevectors in ``q_machine``. :param q_machine: quantum virtual machine device. :param wires: qubit index. :param params: parameter matrix, default is None. :param use_dagger: whether to conjugate transpose, default is False. :param control_values: control value, default is None, control when the bit is 1. Example:: from pyvqnet.qnn.vqc import QMachine import pyvqnet.qnn.vqc as vqc from pyvqnet.tensor import QTensor qm = QMachine(4) for i in range(4): vqc.hadamard(q_machine=qm, wires=i) vqc.phaseshift(q_machine=qm,wires=[0], params = QTensor([0.5])) vqc.phaseshift(q_machine=qm,wires=[1], params = QTensor([2])) vqc.phaseshift(q_machine=qm,wires=[3], params = QTensor([3])) vqc.multicontrolledx(qm, wires=[0, 1, 3, 2]) print(qm.states) # [[[[[ 0.25 +0.j ,-0.2474981+0.03528j ], # [ 0.25 +0.j ,-0.2474981+0.03528j ]], # [[-0.1040367+0.2273243j, 0.0709155-0.239731j ], # [-0.1040367+0.2273243j, 0.0709155-0.239731j ]]], # [[[ 0.2193956+0.1198564j,-0.2341141-0.0876958j], # [ 0.2193956+0.1198564j,-0.2341141-0.0876958j]], # [[-0.2002859+0.149618j , 0.1771674-0.176385j ], # [-0.2002859+0.149618j , 0.1771674-0.176385j ]]]]] MultiControlledX --------------------------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.MultiControlledX(has_params: bool = False,trainable: bool = False,init_params=None,wires=None,dtype=pyvqnet.kcomplex64,use_dagger=False,control_values=None) Define a MultiControlledX logic gate class. :param has_params: Whether it has parameters, such as RX, RY and other gates need to be set to True, and those without parameters need to be set to False, the default is False. :param trainable: Whether it has parameters to be trained. If the layer uses external input data to build the logic gate matrix, set to False. If the parameters to be trained need to be initialized from this layer, it is True, the default is False. :param init_params: Initialization parameters used to encode classic data QTensor, the default is None. :param wires: Bit index of the wire action, the default is None. :param dtype: The data precision of the internal matrix of the logic gate, which can be set to pyvqnet.kcomplex64, or pyvqnet.kcomplex128, corresponding to float input or double input respectively. :param use_dagger: Whether to use the transposed conjugate version of the gate, the default is False. :param control_values: control value, default is None, control when the bit is 1. :return: A Module that can be used to train the model. Example:: from pyvqnet.qnn.vqc import QMachine import pyvqnet.qnn.vqc as vqc from pyvqnet.tensor import QTensor,kcomplex64 qm = QMachine(4,dtype=kcomplex64) qm.reset_states(2) for i in range(4): vqc.hadamard(q_machine=qm, wires=i) vqc.isingzz(q_machine=qm, params=QTensor([0.25]), wires=[1,0]) vqc.double_excitation(q_machine=qm, params=QTensor([0.55]), wires=[0,1,2,3]) mcx = vqc.MultiControlledX( init_params=None, wires=[2,3,0,1], dtype=kcomplex64, use_dagger=False,control_values=[1,0,0]) y = mcx(q_machine = qm) print(qm.states) """ [[[[[0.2480494-0.0311687j,0.2480494-0.0311687j], [0.2480494+0.0311687j,0.1713719-0.0215338j]], [[0.2480494+0.0311687j,0.2480494+0.0311687j], [0.2480494-0.0311687j,0.2480494+0.0311687j]]], [[[0.2480494+0.0311687j,0.2480494+0.0311687j], [0.2480494+0.0311687j,0.2480494+0.0311687j]], [[0.306086 -0.0384613j,0.2480494-0.0311687j], [0.2480494-0.0311687j,0.2480494-0.0311687j]]]], [[[[0.2480494-0.0311687j,0.2480494-0.0311687j], [0.2480494+0.0311687j,0.1713719-0.0215338j]], [[0.2480494+0.0311687j,0.2480494+0.0311687j], [0.2480494-0.0311687j,0.2480494+0.0311687j]]], [[[0.2480494+0.0311687j,0.2480494+0.0311687j], [0.2480494+0.0311687j,0.2480494+0.0311687j]], [[0.306086 -0.0384613j,0.2480494-0.0311687j], [0.2480494-0.0311687j,0.2480494-0.0311687j]]]]] """ single_excitation ----------------------------- .. py:function:: pyvqnet.qnn.vqc.single_excitation(q_machine, wires, params=None, use_dagger=False) Acting quantum logic gates on state vectors in q_machine single_excitation. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import QMachine import pyvqnet.qnn.vqc as vqc from pyvqnet.tensor import QTensor qm = QMachine(4) vqc.single_excitation(q_machine=qm, wires=[0, 1],params=QTensor([0.5])) print(qm.states) # [[[[[1.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]] # # # [[[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]]]]] double_excitation -------------------------- .. py:function:: pyvqnet.qnn.vqc.double_excitation(q_machine, wires, params=None, use_dagger=False) Acting quantum logic gates on state vectors in q_machine double_excitation. :param q_machine: quantum virtual machine device. :param wires: qubit idx. :param params: parameter matrix, defaults to None,For a logic gate operation function with p parameters, the dimension of the input parameter needs to be [1,p], or [p]. :param use_dagger: whether to conjugate transpose, the default is False. Example:: from pyvqnet.qnn.vqc import QMachine import pyvqnet.qnn.vqc as vqc from pyvqnet.tensor import QTensor qm = QMachine(4) for i in range(4): vqc.hadamard(q_machine=qm, wires=i) vqc.isingzz(q_machine=qm, params=QTensor([0.55]), wires=[1,0]) vqc.double_excitation(q_machine=qm, params=QTensor([0.55]), wires=[0,1,2,3]) print(qm.states) # [[[[[0.2406063-0.0678867j 0.2406063-0.0678867j] # [0.2406063-0.0678867j 0.1662296-0.0469015j]] # # [[0.2406063+0.0678867j 0.2406063+0.0678867j] # [0.2406063+0.0678867j 0.2406063+0.0678867j]]] # # # [[[0.2406063+0.0678867j 0.2406063+0.0678867j] # [0.2406063+0.0678867j 0.2406063+0.0678867j]] # # [[0.2969014-0.0837703j 0.2406063-0.0678867j] # [0.2406063-0.0678867j 0.2406063-0.0678867j]]]]] VQC_BasisEmbedding -------------------------- .. py:function:: pyvqnet.qnn.vqc.VQC_BasisEmbedding(basis_state,q_machine) Encode binary features ``basis_state`` into the ground state of n qubits in ``q_machine``. For example, for ``basis_state=([0, 1, 1])``, the ground state of the quantum system is :math:`|011 \rangle`. :param basis_state: binary input of size ``(n)``. :param q_machine: quantum virtual machine device。 Example:: from pyvqnet.qnn.vqc import VQC_BasisEmbedding,QMachine qm = QMachine(3) VQC_BasisEmbedding(basis_state=[1,1,0],q_machine=qm) print(qm.states) # [[[[0.+0.j 0.+0.j] # [0.+0.j 0.+0.j]] # # [[0.+0.j 0.+0.j] # [1.+0.j 0.+0.j]]]] VQC_AngleEmbedding -------------------------- .. py:function:: pyvqnet.qnn.vqc.VQC_AngleEmbedding(input_feat, wires, q_machine: QMachine, rotation: str = "X") Encodes the :math:`N` feature into the rotation angle of the :math:`n` qubit, where :math:`N \leq n` in ``q_machine`` . Rotation can be selected as: 'X' , 'Y' , 'Z', such as the parameter definition of ``rotation`` is: * ``rotation='X'`` Use feature as angle for RX rotation. * ``rotation='Y'`` Use feature as angle for RY rotation. * ``rotation='Z'`` Use feature as angle for RZ rotation. ``wires`` denote the idx of rotation gates on the qubits. :param input_feat: array representing the parameters. :param wires: qubit idx. :param q_machine: Quantum virtual machine device. :param rotation: Rotation gate, default is "X". Example:: from pyvqnet.qnn.vqc import VQC_AngleEmbedding, QMachine from pyvqnet.tensor import QTensor qm = QMachine(2) VQC_AngleEmbedding(QTensor([2.2, 1]), [0, 1], q_machine=qm, rotation='X') print(qm.states) # [[[ 0.398068 +0.j 0. -0.2174655j] # [ 0. -0.7821081j -0.4272676+0.j ]]] VQC_AngleEmbedding(QTensor([2.2, 1]), [0, 1], q_machine=qm, rotation='Y') print(qm.states) # [[[-0.0240995+0.6589843j 0.4207355+0.2476033j] # [ 0.4042482-0.2184162j 0. -0.3401631j]]] VQC_AngleEmbedding(QTensor([2.2, 1]), [0, 1], q_machine=qm, rotation='Z') print(qm.states) # [[[0.659407 +0.0048471j 0.4870554-0.0332093j] # [0.4569675+0.047989j 0.340018 +0.0099326j]]] VQC_AmplitudeEmbedding -------------------------- .. py:function:: pyvqnet.qnn.vqc.VQC_AmplitudeEmbeddingCircuit(input_feature, q_machine) Encode a :math:`2^n` feature into an amplitude vector of :math:`n` qubits in ``q_machine`` . :param input_feature: A numpy array representing the parameters. :param q_machine: Quantum virtual machine device. Example:: from pyvqnet.qnn.vqc import VQC_AmplitudeEmbedding, QMachine from pyvqnet.tensor import QTensor qm = QMachine(3) VQC_AmplitudeEmbedding(QTensor([3.2,-2,-2,0.3,12,0.1,2,-1]), q_machine=qm) print(qm.states) # [[[[ 0.2473717+0.j -0.1546073+0.j] # [-0.1546073+0.j 0.0231911+0.j]] # # [[ 0.9276441+0.j 0.0077304+0.j] # [ 0.1546073+0.j -0.0773037+0.j]]]] VQC_IQPEmbedding -------------------------- .. py:function:: pyvqnet.qnn.vqc.VQC_IQPEmbedding(input_feat, q_machine: QMachine, rep: int = 1) Apply diagonal gates using IQP lines encode :math:`n` features into :math:`n` qubits of ``q_machine`` .. The encoding was proposed by `Havlicek et al. (2018) `_. By specifying ``rep``, basic IQP lines can be repeated. :param input_feat: A numpy array representing the parameters. :param q_machine: Quantum virtual machine device. :param rep: The number of times to repeat the quantum circuit block, the default number is 1. Example:: from pyvqnet.qnn.vqc import VQC_IQPEmbedding, QMachine from pyvqnet.tensor import QTensor qm = QMachine(3) VQC_IQPEmbedding(QTensor([3.2,-2,-2]), q_machine=qm) print(qm.states) # [[[[ 0.0309356-0.3521973j 0.3256442+0.1376801j] # [ 0.3256442+0.1376801j 0.2983474+0.1897071j]] # # [[ 0.0309356+0.3521973j -0.3170519-0.1564546j] # [-0.3170519-0.1564546j -0.2310978-0.2675701j]]]] VQC_RotCircuit -------------------------- .. py:function:: pyvqnet.qnn.vqc.VQC_RotCircuit(q_machine, wire, params) Apply Arbitrary single-qubit rotations in statevectors of ``q_machine`` . .. math:: R(\phi,\theta,\omega) = RZ(\omega)RY(\theta)RZ(\phi)= \begin{bmatrix} e^{-i(\phi+\omega)/2}\cos(\theta/2) & -e^{i(\phi-\omega)/2}\sin(\theta/2) \\ e^{-i(\phi-\omega)/2}\sin(\theta/2) & e^{i(\phi+\omega)/2}\cos(\theta/2) \end{bmatrix}. :param q_machine: Quantum virtual machine device. :param wire: Qubit idx。 :param params: Parameters :math:`[\phi, \theta, \omega]`. :return: Output QTensor. Example:: from pyvqnet.qnn.vqc import VQC_RotCircuit, QMachine from pyvqnet.tensor import QTensor qm = QMachine(3) VQC_RotCircuit(q_machine=qm, wire=[1],params=QTensor([2.0,1.5,2.1])) print(qm.states) # [[[[-0.3373617-0.6492732j 0. +0.j ] # [ 0.6807868-0.0340677j 0. +0.j ]] # # [[ 0. +0.j 0. +0.j ] # [ 0. +0.j 0. +0.j ]]]] VQC_CRotCircuit -------------------------- .. py:function:: pyvqnet.qnn.vqc.VQC_CRotCircuit(para,control_qubits,rot_wire,q_machine) Controlled Rot circuit. .. math:: CR(\phi, \theta, \omega) = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0\\ 0 & 0 & e^{-i(\phi+\omega)/2}\cos(\theta/2) & -e^{i(\phi-\omega)/2}\sin(\theta/2)\\ 0 & 0 & e^{-i(\phi-\omega)/2}\sin(\theta/2) & e^{i(\phi+\omega)/2}\cos(\theta/2) \end{bmatrix}. :param para: numpy array representing the parameters. :param control_qubits: Idx of control bits. :param rot_wire: Idx of rot bits. :param q_machine: Quantum virtual machine device. :return: Output QTensor. Example:: from pyvqnet.tensor import QTensor from pyvqnet.qnn.vqc.qcircuit import VQC_CRotCircuit from pyvqnet.qnn.vqc import QMachine, MeasureAll p = QTensor([2, 3, 4.0]) qm = QMachine(2) VQC_CRotCircuit(p, 0, 1, qm) m = MeasureAll(obs={"Z0": 1}) exp = m(q_machine=qm) print(exp) # [[0.9999999]] VQC_Controlled_Hadamard -------------------------- .. py:function:: pyvqnet.qnn.vqc.VQC_Controlled_Hadamard(wires, q_machine) Apply Controlled Hadamard operation in ``q_machine`` . .. math:: CH = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & \frac{1}{\sqrt{2}} & \frac{1}{\sqrt{2}} \\ 0 & 0 & \frac{1}{\sqrt{2}} & -\frac{1}{\sqrt{2}} \end{bmatrix}. :param wires: Qubit idx, the first is the control bit, and the list length is 2. :param q_machine: Quantum virtual machine device. Examples:: from pyvqnet.tensor import QTensor from pyvqnet.qnn.vqc.qcircuit import VQC_Controlled_Hadamard from pyvqnet.qnn.vqc import QMachine, MeasureAll p = QTensor([0.2, 3, 4.0]) qm = QMachine(3) VQC_Controlled_Hadamard([1, 0], qm) m = MeasureAll(obs={"Z0": 1}) exp = m(q_machine=qm) print(exp) # [[1.]] VQC_CCZ -------------------------- .. py:function:: pyvqnet.qnn.vqc.VQC_CCZ(wires, q_machine) Apply Controlled-controlled-Z logic in ``q_machine`` . .. math:: CCZ = \begin{pmatrix} 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\ 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\ 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0\\ 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0\\ 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0\\ 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0\\ 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0\\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 \end{pmatrix} :param wires: List of qubit subscripts, the first bit is the control bit. The list length is 3. :param q_machine: Quantum virtual machine device. :return: pyqpanda QCircuit Example:: from pyvqnet.tensor import QTensor from pyvqnet.qnn.vqc.qcircuit import VQC_CCZ from pyvqnet.qnn.vqc import QMachine, MeasureAll p = QTensor([0.2, 3, 4.0]) qm = QMachine(3) VQC_CCZ([1, 0, 2], qm) m = MeasureAll(obs={"Z0": 1}) exp = m(q_machine=qm) print(exp) # [[0.9999999]] VQC_FermionicSingleExcitation ----------------------------------------- .. py:function:: pyvqnet.qnn.vqc.VQC_FermionicSingleExcitation(weight, wires, q_machine) A coupled cluster single-excitation operator for exponentiating the tensor product of a Pauli matrix. The matrix form is given by: .. math:: \hat{U}_{pr}(\theta) = \mathrm{exp} \{ \theta_{pr} (\hat{c}_p^\dagger \hat{c}_r -\mathrm{H.c.}) \}, :param weight: The parameter on qubit p has only one element. :param wires: Denotes a subset of qubit indices in the interval [r, p]. Minimum length must be 2. The first index value is interpreted as r and the last index value as p. The intermediate index is acted on by the CNOT gate to calculate the parity of the qubit set. :param q_machine: Quantum virtual machine device. :return: pyqpanda QCircuit Examples:: from pyvqnet.tensor import QTensor from pyvqnet.qnn.vqc.qcircuit import VQC_FermionicSingleExcitation from pyvqnet.qnn.vqc import QMachine, MeasureAll qm = QMachine(3) p0 = QTensor([0.5]) VQC_FermionicSingleExcitation(p0, [1, 0, 2], qm) m = MeasureAll(obs={"Z0": 1}) exp = m(q_machine=qm) print(exp) # [[0.9999998]] VQC_FermionicDoubleExcitation ----------------------------------------- .. py:function:: pyvqnet.qnn.vqc.VQC_FermionicDoubleExcitation(weight, wires1, wires2, q_machine) The coupled clustering dual excitation operator that exponentiates the tensor product of the Pauli matrix, the matrix form is given by: .. math:: \hat{U}_{pqrs}(\theta) = \mathrm{exp} \{ \theta (\hat{c}_p^\dagger \hat{c}_q^\dagger \hat{c}_r \hat{c}_s - \mathrm{H.c.}) \}, where :math:`\hat{c}` and :math:`\hat{c}^\dagger` are the fermion annihilation and Create operators and indices :math:`r, s` and :math:`p, q` in the occupied and are empty molecular orbitals, respectively. Use the `Jordan-Wigner transformation `_ The fermion operator defined above can be written as According to the Pauli matrix (for more details, see `arXiv:1805.04340 `_) .. math:: \hat{U}_{pqrs}(\theta) = \mathrm{exp} \Big\{ \frac{i\theta}{8} \bigotimes_{b=s+1}^{r-1} \hat{Z}_b \bigotimes_{a=q+1}^{p-1} \hat{Z}_a (\hat{X}_s \hat{X}_r \hat{Y}_q \hat{X}_p + \hat{Y}_s \hat{X}_r \hat{Y}_q \hat{Y}_p +\\ \hat{X}_s \hat{Y}_r \hat{Y}_q \hat{Y}_p + \hat{X}_s \hat{X}_r \hat{X}_q \hat{Y}_p - \mathrm{H.c.} ) \Big\} :param weight: Variable parameter. :param wires1: The index list of qubits representing the subset of qubits occupied in the interval [s, r]. The first index is interpreted as s, the last as r. CNOT gates operate on intermediate indices to compute the parity of a set of qubits. :param wires2: The index list of qubits representing the subset of qubits occupied in the interval [q, p]. The first index is interpreted as q, the last as p. CNOT gates operate on intermediate indices to compute the parity of a set of qubits. :param q_machine: Quantum virtual machine device. :return: pyqpanda QCircuit Examples:: from pyvqnet.tensor import QTensor from pyvqnet.qnn.vqc.qcircuit import VQC_FermionicDoubleExcitation from pyvqnet.qnn.vqc import QMachine, MeasureAll qm = QMachine(5) p0 = QTensor([0.5]) VQC_FermionicDoubleExcitation(p0, [0, 1], [2, 3], qm) m = MeasureAll(obs={"Z0": 1}) exp = m(q_machine=qm) print(exp) # [[0.9999998]] VQC_UCCSD ----------------------------------------- .. py:function:: pyvqnet.qnn.vqc.VQC_UCCSD(weights, wires, s_wires, d_wires, init_state, q_machine) Realize the unitary coupled cluster single-excitation and double-excitation design (UCCSD). UCCSD is the proposed VQE design, commonly used to run quantum chemistry simulations. Within the first-order Trotter approximation, the UCCSD unitary function is given by: .. math:: \hat{U}(\vec{\theta}) = \prod_{p > r} \mathrm{exp} \Big\{\theta_{pr} (\hat{c}_p^\dagger \hat{c}_r-\mathrm{H.c.}) \Big\} \prod_{p > q > r > s} \mathrm{exp} \Big\{\theta_{pqrs} (\hat{c}_p^\dagger \hat{c}_q^\dagger \hat{c}_r \hat{c}_s-\mathrm{H.c.}) \Big\} where :math:`\hat{c}` and :math:`\hat{c}^\dagger` are the fermion annihilation and Create operators and indices :math:`r, s` and :math:`p, q` in the occupied and are empty molecular orbitals, respectively. (For more details see `arXiv:1805.04340 `_): :param weights: A ``(len(s_wires)+ len(d_wires))`` tensor containing the parameters :math:`\theta_{pr}` and :math:`\theta_{pqrs}` input Z rotation ``FermionicSingleExcitation`` and ``FermionicDoubleExcitation``. :param wires: Qubit indexing of template effects :param s_wires: A sequence of lists ``[r,...,p]`` containing qubit indices produced by a single excitation :math:`\vert r, p \rangle = \hat{c}_p^\dagger \hat{c}_r \vert \mathrm{HF} \rangle`, where :math:`\vert \mathrm{HF} \rangle` represents the Hartree-Fock reference state. :param d_wires: sequence of lists, each list containing two lists specify indices ``[s, ...,r]`` and ``[q,...,p]`` Define double excitation: math:`\vert s, r, q, p \rangle = \hat{c}_p^\dagger \hat{c}_q^\dagger \hat{c}_r\hat{c}_s \ vert \mathrm{HF} \rangle`. :param init_state: length ``len(wires)`` occupation-number vector representation high frequency state. ``init_state`` is the qubit initialization state. :param q_machine: Quantum virtual machine device. Examples:: from pyvqnet.qnn.vqc import VQC_UCCSD, QMachine, MeasureAll from pyvqnet.tensor import QTensor p0 = QTensor([2, 0.5, -0.2, 0.3, -2, 1, 3, 0]) s_wires = [[0, 1, 2], [0, 1, 2, 3, 4], [1, 2, 3], [1, 2, 3, 4, 5]] d_wires = [[[0, 1], [2, 3]], [[0, 1], [2, 3, 4, 5]], [[0, 1], [3, 4]], [[0, 1], [4, 5]]] qm = QMachine(6) VQC_UCCSD(p0, range(6), s_wires, d_wires, QTensor([1.0, 1, 0, 0, 0, 0]), qm) m = MeasureAll(obs={"Z1": 1}) exp = m(q_machine=qm) print(exp) # [[0.963802]] VQC_ZFeatureMap ----------------------------------------- .. py:function:: pyvqnet.qnn.vqc.VQC_ZFeatureMap(input_feat, q_machine: QMachine, data_map_func=None, rep: int = 2) First-order bubblegum Z-evolution circuit. For 3 quantum bits and 2 repetitions, the circuit is represented as: .. parsed-literal:: ┌───┐┌──────────────┐┌───┐┌──────────────┐ ┤ H ├┤ U1(2.0*x[0]) ├┤ H ├┤ U1(2.0*x[0]) ├ ├───┤├──────────────┤├───┤├──────────────┤ ┤ H ├┤ U1(2.0*x[1]) ├┤ H ├┤ U1(2.0*x[1]) ├ ├───┤├──────────────┤├───┤├──────────────┤ ┤ H ├┤ U1(2.0*x[2]) ├┤ H ├┤ U1(2.0*x[2]) ├ └───┘└──────────────┘└───┘└──────────────┘ The Pauli string is fixed to ``Z``. Thus, the first order expansion will be a circuit without entanglement gates. :param input_feat: An array representing the input parameters. :param q_machine: Quantum machine. :param data_map_func: Parameter mapping matrix, design as ``data_map = lambda x: x``. :param rep: Number of module repetitions. Example:: from pyvqnet.qnn.vqc import VQC_ZFeatureMap, QMachine, hadamard from pyvqnet.tensor import QTensor qm = QMachine(3) for i in range(3): hadamard(q_machine=qm, wires=[i]) VQC_ZFeatureMap(input_feat=QTensor([[0.1,0.2,0.3]]),q_machine = qm) print(qm.states) # [[[[0.3535534+0.j 0.2918002+0.1996312j] # [0.3256442+0.1376801j 0.1910257+0.2975049j]] # # [[0.3465058+0.0702402j 0.246323 +0.2536236j] # [0.2918002+0.1996312j 0.1281128+0.3295255j]]]] VQC_ZZFeatureMap ----------------------------------------- .. py:function:: pyvqnet.qnn.vqc.VQC_ZZFeatureMap(input_feat, q_machine: QMachine, data_map_func=None, entanglement: Union[str, List[List[int]],Callable[[int], List[int]]] = "full",rep: int = 2) Second-order Pauli-Z evolution circuits. For 3 quantum bits, 1 repetition and linear entanglement, the circuit is represented as: .. parsed-literal:: ┌───┐┌─────────────────┐ ┤ H ├┤ U1(2.0*φ(x[0])) ├──■────────────────────────────■──────────────────────────────────── ├───┤├─────────────────┤┌─┴─┐┌──────────────────────┐┌─┴─┐ ┤ H ├┤ U1(2.0*φ(x[1])) ├┤ X ├┤ U1(2.0*φ(x[0],x[1])) ├┤ X ├──■────────────────────────────■── ├───┤├─────────────────┤└───┘└──────────────────────┘└───┘┌─┴─┐┌──────────────────────┐┌─┴─┐ ┤ H ├┤ U1(2.0*φ(x[2])) ├──────────────────────────────────┤ X ├┤ U1(2.0*φ(x[1],x[2])) ├┤ X ├ └───┘└─────────────────┘ └───┘└──────────────────────┘└───┘ where ``φ`` is the classical nonlinear function that defaults to ``φ(x) = x`` if and ``φ(x,y) = (pi - x)(pi - y)``, design as: .. code-block:: def data_map_func(x): coeff = x if x.shape[-1] == 1 else ft.reduce(lambda x, y: (np.pi - x) * (np.pi - y), x) return coeff :param input_feat: An array representing the input parameters. :param q_machine: Quantum machine. :param data_map_func: Parameter mapping matrix. :param entanglement: specified entanglement structure. :param rep: Number of module repetitions. Example:: from pyvqnet.qnn.vqc import VQC_ZZFeatureMap, QMachine from pyvqnet.tensor import QTensor qm = QMachine(3) VQC_ZZFeatureMap(q_machine=qm, input_feat=QTensor([[0.1,0.2,0.3]])) print(qm.states) # [[[[-0.4234843-0.0480578j -0.144067 +0.1220178j] # [-0.0800646+0.0484439j -0.5512857-0.2947832j]] # # [[ 0.0084012-0.0050071j -0.2593993-0.2717131j] # [-0.1961917-0.3470543j 0.2786197+0.0732045j]]]] VQC_AllSinglesDoubles ----------------------------------------- .. py:function:: pyvqnet.qnn.vqc.VQC_AllSinglesDoubles(weights, q_machine: QMachine, hf_state, wires, singles=None, doubles=None) Apply all ``SingleExcitation`` and ``DoubleExcitation`` operations on the ``q_machine`` to the initial Hartree-Fock state, preparing the molecular association state. :param weights: QTensor of size ``(len(singles) + len(doubles),)`` containing angles that enter vqc.qCircuit.single_excitation and vqc.qCircuit.double_excitation operations sequentially :param q_machine: Quantum machine. :param hf_state: Represents the length of the Hartree-Fock state ``len(wires)`` Occupancy count vector, ``hf_state`` is used to initialize the wires. :param wires: Qubits action on. :param singles: Sequence of lists with the two quantum bit indices on which the single_exitation operation acts. :param doubles: Sequence of lists with the two quantum bit indices on which the double_exitation operation acts. For example, the quantum circuit for the case of two electrons and six quantum bits is shown below: .. image:: ./images/all_singles_doubles.png :width: 600 px :align: center | Example:: from pyvqnet.qnn.vqc import VQC_AllSinglesDoubles, QMachine from pyvqnet.tensor import QTensor qubits = 4 qm = QMachine(qubits) VQC_AllSinglesDoubles(q_machine=qm, weights=QTensor([0.55, 0.11, 0.53]), hf_state = QTensor([1,1,0,0]), singles=[[0, 2], [1, 3]], doubles=[[0, 1, 2, 3]], wires=[0,1,2,3]) print(qm.states) # [ 0. +0.j 0. +0.j 0. +0.j -0.23728043+0.j # 0. +0.j 0. +0.j -0.27552837+0.j 0. +0.j # 0. +0.j -0.12207296+0.j 0. +0.j 0. +0.j # 0.9235152 +0.j 0. +0.j 0. +0.j 0. +0.j] VQC_BasisRotation ----------------------------------------- .. py:function:: pyvqnet.qnn.vqc.VQC_BasisRotation(q_machine: QMachine, wires, unitary_matrix: QTensor, check=False) Implement a circuit that provides a whole that can be used to perform precise monolithic base rotations. :class:`~.vqc.qCircuit.VQC_BasisRotation` Performs the following you-transform determined by single-particle fermions given in `arXiv:1711.04789 `_\ :math:`U(u)` .. math:: U(u) = \exp{\left( \sum_{pq} \left[\log u \right]_{pq} (a_p^\dagger a_q - a_q^\dagger a_p) \right)}. :math:`U(u)` by using the scheme given in the paper `Optica, 3, 1460 (2016) `_\. The decomposition of the input You matrix is efficiently implemented by a series of :class:`~vqc.qCircuit.phaseshift` and :class:`~vqc.qCircuit.single_exitation` gates. :param q_machine: Quantum machine. :param wires: Qubits action on. :param unitary_matrix: Specify the matrix of the base transformation. :param check: Tests if `unitary_matrix` is a You matrix. Example:: from pyvqnet.qnn.vqc import VQC_BasisRotation, QMachine, hadamard, isingzz from pyvqnet.tensor import QTensor import numpy as np V = np.array([[0.73678+0.27511j, -0.5095 +0.10704j, -0.06847+0.32515j], [0.73678+0.27511j, -0.5095 +0.10704j, -0.06847+0.32515j], [-0.21271+0.34938j, -0.38853+0.36497j, 0.61467-0.41317j]]) eigen_vals, eigen_vecs = np.linalg.eigh(V) umat = eigen_vecs.T wires = range(len(umat)) qm = QMachine(len(umat)) for i in range(len(umat)): hadamard(q_machine=qm, wires=i) isingzz(q_machine=qm, params=QTensor([0.55]), wires=[0,2]) VQC_BasisRotation(q_machine=qm, wires=wires,unitary_matrix=QTensor(umat,dtype=qm.state.dtype)) print(qm.states) # [[[[ 0.3402686-0.0960063j 0.4140436-0.3069579j] # [ 0.1206574+0.1982292j 0.5662895-0.0949503j]] # # [[-0.1715559-0.1614315j 0.1624039-0.0598041j] # [ 0.0608986-0.1078906j -0.305845 +0.1773662j]]]] VQC_QuantumPoolingCircuit ----------------------------------------- .. py:function:: pyvqnet.qnn.vqc.VQC_QuantumPoolingCircuit(ignored_wires, sinks_wires, params, q_machine) A quantum circuit that downsamples data. To reduce the number of qubits in a circuit, pairs of qubits are first created in the system. After initially pairing all qubits, a generalized 2-qubit unitary is applied to each pair of qubits. And after applying the two-qubit unitary, one qubit in each pair of qubits is ignored in the rest of the neural network. :param sources_wires: The source qubit index that will be ignored. :param sinks_wires: The target qubit index to keep. :param params: Input parameters. :param q_machine: Quantum virtual machine device. :return: pyqpanda QCircuit Examples:: from pyvqnet.qnn.vqc import VQC_QuantumPoolingCircuit, QMachine, MeasureAll import pyqpanda as pq from pyvqnet import tensor machine = pq.CPUQVM() machine.init_qvm() qlists = machine.qAlloc_many(4) p = tensor.full([6], 0.35) qm = QMachine(4) VQC_QuantumPoolingCircuit(q_machine=qm, ignored_wires=[0, 1], sinks_wires=[2, 3], params=p) m = MeasureAll(obs={"Z1": 1}) exp = m(q_machine=qm) print(exp) vqc_qft_add_to_register ------------------------------------- .. py:function:: pyvqnet.qnn.vqc.vqc_qft_add_to_register(q_machine, m, k) Encode an unsigned integer `m` into a qubit and then add `k` to it. .. math:: \text{Sum(k)}\vert m \rangle = \vert m + k \rangle. This unitary operation is implemented as follows: (1). Convert the state from the computational basis to the Fourier basis by applying the QFT to the :math:`\vert m \rangle` state. (2). Use the :math:`R_Z` gate to rotate the :math:`j` qubit by the angle :math:`\frac{2k\pi}{2^{j}}`, resulting in the new phase :math:`\frac{2(m + k)\pi}{2^{j}}`. (3). Apply the inverse QFT back to the computational basis and obtain :math:`m+k`. :param q_machine: The quantum machine to simulate. :param m: The classical integer to embed into the register. :param k: The classical integer to add to the register. :retrun: Return the binary representation of the target sum. .. note:: Please note that the number of bits used by ``q_machine`` needs to be sufficient to encode the binary value of the resulting sum using the X basis state. Example:: import numpy as np from pyvqnet.qnn.vqc import QMachine,Samples, vqc_qft_add_to_register dev = QMachine(4) vqc_qft_add_to_register(dev,3, 7) ma = Samples() y = ma(q_machine=dev) print(y) #[[1,0,1,0]] vqc_qft_add_two_register ------------------------------------- .. py:function:: vqc_qft_add_two_register(q_machine, m, k, wires_m, wires_k, wires_solution) Add the unsigned integers encoded in the two qubits. .. math:: \text{Sum}_2\vert m \rangle \vert k \rangle \vert 0 \rangle = \vert m \rangle \vert k \rangle \vert m+k \rangle In this case, we can understand the third register (initially at :math:`0`) as a counter that will count the number of units :math:`m` and :math:`k` add up to. Binary factorization will make this easy. If we have :math:`\vert m \rangle = \vert \overline{q_0q_1q_2} \rangle`, then if :math:`q_2 = 1`, then we must add :math:`1` to the counter, otherwise add nothing. In general, if the :math:`i`-th qubit is in the :math:`\vert 1 \rangle` state, we should add :math:`2^{n-i-1}` units, otherwise add 0. :param q_machine: The quantum machine to simulate. :param m: The classical integer embedded in the register as lhs. :param k: The classical integer embedded in the register as rhs. :param wires_m: The index of the qubit to encode m. :param wires_k: The index of the qubit to encode k. :param wires_solution: The index of the qubit to encode the solution. :retrun: Return the binary representation of the target sum. .. note:: The number of bits used in ``wires_m`` needs to be enough to encode the binary value of `m` using the X basis state. ``wires_k`` uses enough bits to encode the binary value of `k` using the X basis state. ``wires_solution`` uses enough bits to encode the binary value of the result using the X basis state. Example:: import numpy as np from pyvqnet.qnn.vqc import QMachine,Samples, vqc_qft_add_two_register wires_m = [0, 1, 2] # qubits needed to encode m wires_k = [3, 4, 5] # qubits needed to encode k wires_solution = [6, 7, 8, 9, 10] # qubits needed to encode the solution wires_m = [0, 1, 2] # qubits needed to encode m wires_k = [3, 4, 5] # qubits needed to encode k wires_solution = [6, 7, 8, 9] # qubits needed to encode the solution dev = QMachine(len(wires_m) + len(wires_k) + len(wires_solution)) vqc_qft_add_two_register(dev,3, 7, wires_m, wires_k, wires_solution) ma = Samples(wires=wires_solution) y = ma(q_machine=dev) print(y) vqc_qft_mul ------------------------------------- .. py:function:: vqc_qft_mul(q_machine, m, k, wires_m, wires_k, wires_solution) Add the values ​​encoded in two qubits. .. math:: \text{Mul}\vert m \rangle \vert k \rangle \vert 0 \rangle = \vert m \rangle \vert k \rangle \vert m\cdot k \rangle :param q_machine: The quantum machine to simulate. :param m: The classical integer embedded in a register as the left-hand side. :param k: The classical integer embedded in a register as the right-hand side. :param wires_m: The qubit index to encode m. :param wires_k: The qubit index to encode k. :param wires_solution: The qubit index to encode the solution. :retrun: Return the binary representation of the target product. .. note:: ``wires_m`` needs to use enough bits to encode the binary value of `m` using the X basis state. ``wires_k`` uses enough bits to encode the binary value of `k` using the X basis state. ``wires_solution`` uses enough bits to encode the binary value of the result using the X basis state. Example:: import numpy as np from pyvqnet.qnn.vqc import QMachine,Samples, vqc_qft_mul wires_m = [0, 1, 2] # qubits needed to encode m wires_k = [3, 4, 5] # qubits needed to encode k wires_solution = [6, 7, 8, 9, 10] # qubits needed to encode the solution dev = QMachine(len(wires_m) + len(wires_k) + len(wires_solution)) vqc_qft_mul(dev,3, 7, wires_m, wires_k, wires_solution) ma = Samples(wires=wires_solution) y = ma(q_machine=dev) print(y) #[[1,0,1,0,1]] VQC_FABLE -------------------- .. py:class:: pyvqnet.qnn.vqc.VQC_FABLE(wires) Constructs a VQC-based QCircuit using a fast approximate block coding method. For matrices of certain structures [`arXiv:2205.00081 `_], the FABLE method can simplify the block coding circuit without losing accuracy. :param wires: The qlist index to which the operator acts. :return: Returns an instance of the VQC-based FABLE class. Examples:: from pyvqnet.qnn.vqc import VQC_FABLE from pyvqnet.qnn.vqc import QMachine from pyvqnet.dtype import float_dtype_to_complex_dtype import numpy as np from pyvqnet import QTensor A = QTensor(np.array([[0.1, 0.2 ], [0.3, 0.4 ]]) ) qf = VQC_FABLE(list(range(3))) qm = QMachine(3,dtype=float_dtype_to_complex_dtype(A.dtype)) qm.reset_states(1) z1 = qf(qm,A,0.001) """ [[[[0.05 +0.j,0.15 +0.j], [0.05 +0.j,0.15 +0.j]], [[0.4974937+0.j,0.4769696+0.j], [0.4974937+0.j,0.4769696+0.j]]]] """ VQC_LCU -------------------- .. py:class:: pyvqnet.qnn.vqc.VQC_LCU(wires) Build a VQC-based QCircuit using Linear Combination Unit (LCU), `Hamiltonian Simulation via Qubitization `_. Input dtype can be kfloat32, kfloat64, kcomplex64, kcomplex128 Input should be Hermitian. :param wires: qlist index on which operator to act, may require auxiliary qubits. :param check_hermitian: Check if input is Hermitian, default: True. Examples:: from pyvqnet.qnn.vqc import VQC_LCU from pyvqnet.qnn.vqc import QMachine from pyvqnet.dtype import float_dtype_to_complex_dtype,kfloat64 from pyvqnet import QTensor A = QTensor([[0.25,0,0,0.75],[0,-0.25,0.75,0],[0,0.75,0.25,0],[0.75,0,0,-0.25]],device=1001,dtype=kfloat64) qf = VQC_LCU(list(range(3))) qm = QMachine(3,dtype=float_dtype_to_complex_dtype(A.dtype)) qm.reset_states(2) z1 = qf(qm,A) print(z1) """ [[[[ 0.25 +0.j, 0. +0.j], [ 0. +0.j, 0.75 +0.j]], [[-0.4330127+0.j, 0. +0.j], [ 0. +0.j, 0.4330127+0.j]]], [[[ 0.25 +0.j, 0. +0.j], [ 0. +0.j, 0.75 +0.j]], [[-0.4330127+0.j, 0. +0.j], [ 0. +0.j, 0.4330127+0.j]]]] """ VQC_QSVT -------------------- .. py:class:: pyvqnet.qnn.vqc.VQC_QSVT(A, angles, wires) Implements the `quantum singular value transformation `__ (QSVT) circuit. :param A: The general :math:`(n \times m)` matrix to encode. :param angles: The list of angles to shift to get the desired polynomial. :param wires: The qubit indices that A acts on. Example:: from pyvqnet import DEV_GPU from pyvqnet.qnn.vqc import QMachine,VQC_QSVT from pyvqnet.dtype import float_dtype_to_complex_dtype,kfloat64 import numpy as np from pyvqnet import QTensor A = QTensor([[0.1, 0.2], [0.3, 0.4]]) angles = QTensor([0.1, 0.2, 0.3]) qm = QMachine(4,dtype=float_dtype_to_complex_dtype(A.dtype)) qm.reset_states(1) qf = VQC_QSVT(A,angles,wires=[2,1,3]) z1 = qf(qm) print(z1) """ [[[[[ 0.9645935+0.2352667j,-0.0216623+0.0512362j], [-0.0062613+0.0308878j,-0.0199871+0.0985996j]], [[ 0. +0.j , 0. +0.j ], [ 0. +0.j , 0. +0.j ]]], [[[ 0. +0.j , 0. +0.j ], [ 0. +0.j , 0. +0.j ]], [[ 0. +0.j , 0. +0.j ], [ 0. +0.j , 0. +0.j ]]]]] """ Quantum Measurements ============================================= VQC_Purity ---------------------- .. py:function:: pyvqnet.qnn.vqc.VQC_Purity(state, qubits_idx, num_wires) Calculate the purity on a particular qubit ``qubits_idx`` from the state vector ``state``. .. math:: \gamma = \text{Tr}(\rho^2) where :math:`\rho` is a density matrix. The purity of a normalized quantum state satisfies :math:`\frac{1}{d} \leq \gamma \leq 1` , where :math:`d` is the dimension of the Hilbert space. The purity of the pure state is 1. :param state: Quantum state obtained from pyqpanda get_qstate() :param qubits_idx: Qubit index for which to calculate purity :param num_wires: Qubit idx :return: purity Example:: from pyvqnet.qnn.vqc import VQC_Purity, rx, ry, cnot, QMachine from pyvqnet.tensor import kfloat64, QTensor x = QTensor([[0.7, 0.4], [1.7, 2.4]], requires_grad=True) qm = QMachine(3) qm.reset_states(2) rx(q_machine=qm, wires=0, params=x[:, [0]]) ry(q_machine=qm, wires=1, params=x[:, [1]]) ry(q_machine=qm, wires=2, params=x[:, [1]]) cnot(q_machine=qm, wires=[0, 1]) cnot(q_machine=qm, wires=[2, 1]) y = VQC_Purity(qm.states, [0, 1], num_wires=3) y.backward() print(y) # [0.9356751 0.875957] VQC_VarMeasure ------------------------------------- .. py:function:: pyvqnet.qnn.vqc.VQC_VarMeasure(q_machine, obs) Return the measurement variance of the provided observable ``obs`` in statevectors in ``q_machine`` . :param q_machine: Quantum state obtained from pyqpanda get_qstate() :param obs: observables :return: variance value Example:: from pyvqnet.tensor import QTensor from pyvqnet.qnn.vqc import VQC_VarMeasure, rx, cnot, hadamard, QMachine,PauliY x = QTensor([[0.5]], requires_grad=True) qm = QMachine(3) rx(q_machine=qm, wires=0, params=x) var_result = VQC_VarMeasure(q_machine= qm, obs=PauliY(wires=0)) var_result.backward() print(var_result) # [[0.7701511]] VQC_DensityMatrixFromQstate ------------------------------------- .. py:function:: pyvqnet.qnn.vqc.VQC_DensityMatrixFromQstate(state, indices) Computes the density matrix of quantum states ``state`` over a specific set of qubits ``indices`` . :param state: A 1D list of state vectors. The size of this list should be ``(2**N,)`` For the number of qubits ``N``, qstate should start from 000 -> 111. :param indices: A list of qubit indices in the considered subsystem. :return: A density matrix of size "(b, 2**len(indices), 2**len(indices))". Example:: from pyvqnet.qnn.vqc import VQC_DensityMatrixFromQstate,rx,ry,cnot,QMachine from pyvqnet.tensor import kfloat64, QTensor x = QTensor([[0.7,0.4],[1.7,2.4]],requires_grad=True) qm = QMachine(3) qm.reset_states(2) rx(q_machine=qm,wires=0,params=x[:,[0]]) ry(q_machine=qm,wires=1,params=x[:,[1]]) ry(q_machine=qm,wires=2,params=x[:,[1]]) cnot(q_machine=qm,wires=[0,1]) cnot(q_machine=qm,wires=[2, 1]) y = VQC_DensityMatrixFromQstate(qm.states,[0,1]) print(y) # [[[0.8155131+0.j 0.1718155+0.j 0. +0.0627175j # 0. +0.2976855j] # [0.1718155+0.j 0.0669081+0.j 0. +0.0244234j # 0. +0.0627175j] # [0. -0.0627175j 0. -0.0244234j 0.0089152+0.j # 0.0228937+0.j ] # [0. -0.2976855j 0. -0.0627175j 0.0228937+0.j # 0.1086637+0.j ]] # # [[0.3362115+0.j 0.1471083+0.j 0. +0.1674582j # 0. +0.3827205j] # [0.1471083+0.j 0.0993662+0.j 0. +0.1131119j # 0. +0.1674582j] # [0. -0.1674582j 0. -0.1131119j 0.1287589+0.j # 0.1906232+0.j ] # [0. -0.3827205j 0. -0.1674582j 0.1906232+0.j # 0.4356633+0.j ]]] Probability -------------------- .. py:class:: pyvqnet.qnn.vqc.Probability(wires, name="") Calculating the probability measurements of quantum circuits on specific bits :param wires: Measure qubit idx. :param name: name of module .. py:method:: forward(q_machine) Perform probability measurement calculations :param q_machine: quantum state vector simulator :return: probability measurement results .. note:: The probability measurement results calculated using this class are generally [b, len(wires)], where b is the batch number b of q_machine.reset_states(b). Example:: from pyvqnet.qnn.vqc import Probability,rx,ry,cnot,QMachine,rz from pyvqnet.tensor import kfloat64, QTensor x = QTensor([[0.56, 0.1],[0.56, 0.1]],requires_grad=True) qm = QMachine(4) qm.reset_states(2) rz(q_machine=qm,wires=0,params=x[:,[0]]) rz(q_machine=qm,wires=1,params=x[:,[0]]) cnot(q_machine=qm,wires=[0,1]) ry(q_machine=qm,wires=2,params=x[:,[1]]) cnot(q_machine=qm,wires=[0,2]) rz(q_machine=qm,wires=3,params=x[:,[1]]) ma = Probability(wires=1) y =ma(q_machine=qm) # [[1.0000002 0. ] # [1.0000002 0. ]] MeasureAll -------------------- .. py:class:: pyvqnet.qnn.vqc.MeasureAll(obs,name="") Calculate the measurement results of the quantum circuit. Support input observables ``obs`` as a dictionary consisting of observables `observables`, wires `wires`, coefficients `coefficient` key-value pairs, or a list of key-value pair dictionaries. For example: {\'wires\': [0, 1], \'observables\': [\'x\', \'i\'],\'coefficient\':[0.23,-3.5]} or: {\'X0\': 0.23} or: [{\'wires\': [0, 2, 3],\'observables\': [\'X\', \'Y\', \'Z\'],\'coefficient\': [1, 0.5, 0.4]}, {\'wires\': [0, 1, 2],\'observables\': [\'X\', \'Y\', \'Z\'],\'coefficient\': [1, 0.5, 0.4]}] :param obs: observable。 :param name: name of module :return: a Module .. py:method:: forward(q_machine) Perform measurement operation :param q_machine: quantum state vector simulator :return: measurement result, QTensor. .. note:: If ``obs`` is a list, the measurement result calculated using this class is generally [b, obs list length], where b is the batch number b of q_machine.reset_states(b). If ``obs`` is a dictionary, the measurement result calculated using this class is generally [b,1], where b is the batch number b of q_machine.reset_states(b). Example:: from pyvqnet.qnn.vqc import MeasureAll,rx,ry,cnot,QMachine,rz from pyvqnet.tensor import kfloat64, QTensor x = QTensor([[0.56, 0.1],[0.56, 0.1]],requires_grad=True) qm = QMachine(4) qm.reset_states(2) rz(q_machine=qm,wires=0,params=x[:,[0]]) rz(q_machine=qm,wires=1,params=x[:,[0]]) cnot(q_machine=qm,wires=[0,1]) ry(q_machine=qm,wires=2,params=x[:,[1]]) cnot(q_machine=qm,wires=[0,2]) rz(q_machine=qm,wires=3,params=x[:,[1]]) obs_list = [{ 'wires': [0, 2, 3], 'observables': ['X', 'Y', 'Z'], 'coefficient': [1, 0.5, 0.4] }, { 'wires': [0, 1, 2], 'observables': ['X', 'Y', 'Z'], 'coefficient': [1, 0.5, 0.4] }] ma = MeasureAll(obs=obs_list) y =ma(q_machine=qm) print(y) # [[0.4000001 0.3980018] # [0.4000001 0.3980018]] Samples ---------------------------- .. py:class:: pyvqnet.qnn.vqc.Samples(wires=None, obs=None, shots = 1,name="") Get the observation ``obs`` result with ``shots`` on the specified wires ``wires``. .. py:method:: forward(q_machine) Perform sampling operations. :param q_machine: The quantum state vector simulator in effect :return: Measurement results, QTensor. .. note:: The measurement results calculated using this class are generally [b, shots, len(wires)], where b is the batch number b of q_machine.reset_states(b). :param wires: Sample qubit index. Default value: None, use all bits of the simulator at runtime. :param obs: This value can only be None. :param shots: Number of sample repetitions, default value: 1. :param name: Name of this module, default value: "". :return: A measurement method class Example:: from pyvqnet.qnn.vqc import Samples,rx,ry,cnot,QMachine,rz from pyvqnet.tensor import kfloat64, QTensor x = QTensor([[0.56, 0.1],[0.56, 0.1]],requires_grad=True) qm = QMachine(4) qm.reset_states(2) rz(q_machine=qm,wires=0,params=x[:,[0]]) rx(q_machine=qm,wires=1,params=x[:,[0]]) cnot(q_machine=qm,wires=[0,1]) cnot(q_machine=qm,wires=[0,2]) ry(q_machine=qm,wires=3,params=x[:,[1]]) ma = Samples(wires=[0,1,2],shots=3) y = ma(q_machine=qm) print(y) """ [[[0,0,0], [0,1,0], [0,0,0]], [[0,1,0], [0,0,0], [0,1,0]]] """ SparseHamiltonian --------------------------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.SparseHamiltonian(obs, name="") Computes the sparse Hamiltonian of an observation ``obs`` , for example {"observables":H,"wires":[0,2,3]}. :param obs: Sparse Hamiltonian, use the `tensor.dense_to_csr()` function to obtain the sparse format of the dense function. :param name: The name of the module, default: "". :return: a Module. .. py:method:: forward(q_machine) Perform sparse Hamiltonian measurement. :param q_machine: quantum state vector simulator :return: measurement result, QTensor. .. note:: The measurement result calculated using this class is generally [b,1], where b is the batch number b of q_machine.reset_states(b). Example:: import pyvqnet pyvqnet.utils.set_random_seed(42) from pyvqnet import tensor from pyvqnet.nn import Module from pyvqnet.qnn.vqc import QMachine,CRX,PauliX,paulix,crx,SparseHamiltonian H = tensor.QTensor( [[ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, -1.+0.j,], [ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j,], [ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j,], [ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, -1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,], [ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, -1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,], [ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,], [ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,], [ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, -1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,], [ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, -1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,], [ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,], [ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,], [ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, -1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,], [ 0.+0.j, 0.+0.j, 0.+0.j, -1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,], [ 0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,], [ 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,], [-1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,]],dtype=pyvqnet.kcomplex64) cpu_csr = tensor.dense_to_csr(H) class QModel(Module): def __init__(self, num_wires, dtype,grad_mode=""): super(QModel, self).__init__() self._num_wires = num_wires self._dtype = dtype self.qm = QMachine(num_wires) self.measure = SparseHamiltonian(obs = {"observables":cpu_csr, "wires":[2, 1, 3, 5]}) def forward(self, x, *args, **kwargs): self.qm.reset_states(x.shape[0]) paulix(q_machine=self.qm, wires= 0) paulix(q_machine=self.qm, wires = 2) crx(q_machine=self.qm,wires=[0, 1],params=tensor.full((x.shape[0],1),0.1,dtype=pyvqnet.kcomplex64)) crx(q_machine=self.qm,wires=[2, 3],params=tensor.full((x.shape[0],1),0.2,dtype=pyvqnet.kcomplex64)) crx(q_machine=self.qm,wires=[1, 2],params=tensor.full((x.shape[0],1),0.3,dtype=pyvqnet.kcomplex64)) crx(q_machine=self.qm,wires=[2, 4],params=tensor.full((x.shape[0],1),0.3,dtype=pyvqnet.kcomplex64)) crx(q_machine=self.qm,wires=[5, 3],params=tensor.full((x.shape[0],1),0.3,dtype=pyvqnet.kcomplex64)) rlt = self.measure(q_machine=self.qm) return rlt model = QModel(6,pyvqnet.kcomplex64) y = model(tensor.ones([1,1])) print(y) #[0.] HermitianExpval --------------------------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.HermitianExpval(obs, name="") Compute the expectation of a Hermitian observable ``obs`` of a quantum circuit. :param obs: Hermitian quantity. :param name: The name of the module, default: "". :return: A HermitianExpval instance. .. py:method:: forward(q_machine) Perform Hermitian measurement. :param q_machine: quantum state vector simulator :return: measurement result, QTensor. .. note:: The measurement result calculated using this class is generally [b,1], where b is the batch number b of q_machine.reset_states(b). Example:: from pyvqnet.qnn.vqc import qcircuit from pyvqnet.qnn.vqc import QMachine, RX, RY, CNOT, PauliX, qmatrix, PauliZ, VQC_RotCircuit,HermitianExpval from pyvqnet.tensor import QTensor, tensor import pyvqnet from pyvqnet.nn import Parameter import numpy as np bsz = 3 H = np.array([[8, 4, 0, -6], [4, 0, 4, 0], [0, 4, 8, 0], [-6, 0, 0, 0]]) class QModel(pyvqnet.nn.Module): def __init__(self, num_wires, dtype): super(QModel, self).__init__() self.rot_param = Parameter((3, )) self.rot_param.copy_value_from(tensor.QTensor([-0.5, 1, 2.3])) self._num_wires = num_wires self._dtype = dtype self.qm = QMachine(num_wires, dtype=dtype) self.rx_layer1 = VQC_RotCircuit self.ry_layer2 = RY(has_params=True, trainable=True, wires=0, init_params=tensor.QTensor([-0.5])) self.xlayer = PauliX(wires=0) self.cnot = CNOT(wires=[0, 1]) self.measure = HermitianExpval(obs = {'wires':(1,0),'observables':tensor.to_tensor(H)}) def forward(self, x, *args, **kwargs): self.qm.reset_states(x.shape[0]) qcircuit.rx(q_machine=self.qm, wires=0, params=x[:, [1]]) qcircuit.ry(q_machine=self.qm, wires=1, params=x[:, [0]]) self.xlayer(q_machine=self.qm) self.rx_layer1(params=self.rot_param, wire=1, q_machine=self.qm) self.ry_layer2(q_machine=self.qm) self.cnot(q_machine=self.qm) rlt = self.measure(q_machine = self.qm) return rlt input_x = tensor.arange(1, bsz * 2 + 1, dtype=pyvqnet.kfloat32).reshape([bsz, 2]) input_x.requires_grad = True qunatum_model = QModel(num_wires=2, dtype=pyvqnet.kcomplex64) batch_y = qunatum_model(input_x) batch_y.backward() print(batch_y) # [[5.3798223], # [7.1294155], # [0.7028297]] Commonly used quantum variation circuit templates ===================================================== VQC_HardwareEfficientAnsatz ----------------------------------------- .. py:class:: pyvqnet.qnn.vqc.VQC_HardwareEfficientAnsatz(n_qubits,single_rot_gate_list,entangle_gate="CNOT",entangle_rules='linear',depth=1) The implementation of Hardware Efficient Ansatz introduced in the paper:`Hardware-efficient Variational Quantum Eigensolver for Small Molecules `__. :param n_qubits: number of qubits. :param single_rot_gate_list: A single-qubit turnstile list consists of one or more turnstiles that act on each qubit. Rx, Ry, Rz are currently supported. :param entangle_gate: Nonparametric entanglement gates. Support CNOT, CZ. Default: CNOT. :param entangle_rules: How to use entanglement gates in circuits. ``linear`` means that the entanglement gate will act on every adjacent qubit. ``all`` means that the entanglement gate will act on any two qbuits. Default: ``linear``. :param depth: Ansatz depth, default: 1. :return: A VQC_HardwareEfficientAnsatz instance. Example:: from pyvqnet.nn import Module,Linear,ModuleList from pyvqnet.qnn.vqc.qcircuit import VQC_HardwareEfficientAnsatz,RZZ,RZ from pyvqnet.qnn.vqc import Probability,QMachine from pyvqnet import tensor class QM(Module): def __init__(self, name=""): super().__init__(name) self.linearx = Linear(4,2) self.ansatz = VQC_HardwareEfficientAnsatz(4, ["rx", "RY", "rz"], entangle_gate="cnot", entangle_rules="linear", depth=2) self.encode1 = RZ(wires=0) self.encode2 = RZ(wires=1) self.measure = Probability(wires=[0,2]) self.device = QMachine(4) def forward(self, x, *args, **kwargs): self.device.reset_states(x.shape[0]) y = self.linearx(x) self.encode1(params = y[:, [0]],q_machine = self.device,) self.encode2(params = y[:, [1]],q_machine = self.device,) self.ansatz(q_machine =self.device) return self.measure(q_machine =self.device) bz =3 inputx = tensor.arange(1.0,bz*4+1).reshape([bz,4]) inputx.requires_grad= True qlayer = QM() y = qlayer(inputx) y.backward() print(y) # [[0.3075959 0.2315064 0.2491432 0.2117545] # [0.3075958 0.2315062 0.2491433 0.2117546] # [0.3075958 0.2315062 0.2491432 0.2117545]] VQC_BasicEntanglerTemplate ------------------------------- .. py:class:: pyvqnet.qnn.vqc.VQC_BasicEntanglerTemplate(num_layer=1, num_qubits=1, rotation="RX", initial=None, dtype=None) A layer consisting of a single-parameter single-qubit rotation on each qubit, followed by a closed chain or ring combination of multiple CNOT gates. A CNOT gate ring connects each qubit to its neighbors, with the last qubit considered to be a neighbor of the first qubit. :param num_layer: The number of qubit circuit layers. :param num_qubits: The number of qubits, defaults to 1. :param rotation: With single-parameter single-qubit gates, ``RX`` is used as the default. :return: A VQC_BasicEntanglerTemplate instance. Example:: from pyvqnet.nn import Module, Linear, ModuleList from pyvqnet.qnn.vqc.qcircuit import VQC_BasicEntanglerTemplate, RZZ, RZ from pyvqnet.qnn.vqc import Probability, QMachine from pyvqnet import tensor class QM(Module): def __init__(self, name=""): super().__init__(name) self.ansatz = VQC_BasicEntanglerTemplate(2, 4, "rz", initial=tensor.ones([1, 1])) self.measure = Probability(wires=[0, 2]) self.device = QMachine(4) def forward(self,x, *args, **kwargs): self.ansatz(q_machine=self.device) return self.measure(q_machine=self.device) bz = 1 inputx = tensor.arange(1.0, bz * 4 + 1).reshape([bz, 4]) qlayer = QM() y = qlayer(inputx) y.backward() print(y) # [[1.0000002 0. 0. 0. ]] VQC_StronglyEntanglingTemplate ------------------------------------ .. py:class:: pyvqnet.qnn.vqc.VQC_StronglyEntanglingTemplate(weights=None, num_qubits=1, ranges=None) A layer consisting of a single qubit rotation and an entangler, see `circuit-centric classifier design `__. The parameter ``weights`` contains the weights for each layer. Thus it follows that the number of layers :math:`L` is equal to the first dimension of ``weights``. It consists of 2-qubit CNOT gates acting on :math: `M` qubits, :math:`i = 1,...,M`. The second qubit label for each gate is given by the formula :math:`(i+r)\mod M`, where :math:`r` is a hyperparameter called ``range``, and :math: `0 < r < M`. :param weights: Weight tensor of shape ``(L, M, 3)``, default: None, use a random tensor of shape ``(1,1,3)``. :param num_qubits: The number of qubits, default: 1. :param ranges: Sequence of hyperparameters that determine the ranges of each subsequent layer; default: None, use :math:`r=l \ mod M` as the value of ranges. :return: A VQC_StronglyEntanglingTemplate instance. Example:: from pyvqnet.nn import Module from pyvqnet.qnn.vqc.qcircuit import VQC_StronglyEntanglingTemplate from pyvqnet.qnn.vqc import Probability, QMachine from pyvqnet import tensor class QM(Module): def __init__(self, name=""): super().__init__(name) self.ansatz = VQC_StronglyEntanglingTemplate(2, 4, None, initial=tensor.ones([1, 1])) self.measure = Probability(wires=[0, 1]) self.device = QMachine(4) def forward(self,x, *args, **kwargs): self.ansatz(q_machine=self.device) return self.measure(q_machine=self.device) bz = 1 inputx = tensor.arange(1.0, bz * 4 + 1).reshape([bz, 4]) qlayer = QM() y = qlayer(inputx) y.backward() print(y) # [[0.3745951 0.154298 0.059156 0.4119509]] VQC_QuantumEmbedding -------------------------- .. py:class:: pyvqnet.qnn.VQC_QuantumEmbedding(qubits, machine, num_repetitions_input, depth_input, num_unitary_layers, num_repetitions) Use RZ,RY,RZ to create variational quantum circuits that encode classical data into quantum states. Reference `Quantum embeddings for machine learning `_. After the class is initialized, its member function ``compute_circuit`` is a running function, which can be input as a parameter. The ``QuantumLayerV2`` class constitutes a layer of the quantum machine learning model. :param qubits: Qubits requested using pyqpanda. :param machine: Quantum virtual machine requested by pyqpanda. :param num_repetitions_input: Number of repetitions to encode input in submodules. :param depth_input: The feature dimension of the input data. :param num_unitary_layers: The number of repetitions of the variable quantum gates in each submodule. :param num_repetitions: The number of repetitions for the submodule. :return: A VQC_QuantumEmbedding instance. Example:: from pyvqnet.nn import Module from pyvqnet.qnn.vqc.qcircuit import VQC_QuantumEmbedding from pyvqnet.qnn.vqc import QMachine,MeasureAll from pyvqnet import tensor import pyvqnet depth_input = 2 num_repetitions = 2 num_repetitions_input = 2 num_unitary_layers = 2 nq = depth_input * num_repetitions_input bz = 12 class QM(Module): def __init__(self, name=""): super().__init__(name) self.ansatz = VQC_QuantumEmbedding(num_repetitions_input, depth_input, num_unitary_layers, num_repetitions, pyvqnet.kfloat64, initial=tensor.full([1],12.0)) self.measure = MeasureAll(obs={f"Z{nq-1}":1}) self.device = QMachine(nq,dtype=pyvqnet.kcomplex128) def forward(self, x, *args, **kwargs): self.device.reset_states(x.shape[0]) self.ansatz(x,q_machine=self.device) return self.measure(q_machine=self.device) inputx = tensor.arange(1.0, bz * depth_input + 1, dtype=pyvqnet.kfloat64).reshape([bz, depth_input]) qlayer = QM() y = qlayer(inputx) y.backward() print(y) # [[-0.2539548] # [-0.1604787] # [ 0.1492931] # [-0.1711956] # [-0.1577133] # [ 0.1396999] # [ 0.016864 ] # [-0.0893069] # [ 0.1897014] # [ 0.0941301] # [ 0.0550722] # [ 0.2408579]] Other functions ===================== HybirdVQCQpandaQVMLayer ----------------------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.HybirdVQCQpandaQVMLayer(vqc_module: Module,qcloud_token: str,para_num: int,num_qubits: int,num_cubits: int,pauli_str_dict: Union[List[Dict], Dict, None] = None,shots: int = 1000,initializer: Callable = None,dtype: Union[int, None] = None,name: str = "",submit_kwargs: Dict = {},query_kwargs: Dict = {}) Hybrid vqc and qpanda QVM layer. This layer converts quantum circuit computations defined by the user `forward` function into QPanda circuits, which can be run forward on a QPanda local VM or cloud service, and simulates circuit parameter gradients on the local CPU, reducing the time complexity of using the parameter drift method. :param vqc_module: vqc_module with forward(), qmachine set up correctly. :param qcloud_token: `str` - Type of quantum machine or cloud token for execution. :param para_num: `int` - Number of parameters; parameters are one-dimensional. :param num_qubits: `int` - Number of qubits in the quantum circuit. :param num_cubits: `int` - Number of classical bits used for measurements in the quantum circuit. :param pauli_str_dict: `dict|list` - Dictionary or list of dictionaries representing Pauli operators in the quantum circuit. Default is None. :param shots: `int` - Number of measurement shots. Default is 1000. :param initializer: Initializer for parameter values. Default is None. :param dtype: Data type of the parameter. Default is None, i.e. use the default data type. :param name: Module name. Default is the empty string. :param submit_kwargs: Additional keyword parameters for submitting quantum circuits, default value: {"chip_id":pyqpanda.real_chip_type.origin_72,"is_amend":True,"is_mapping":True,"is_optimization":True,"default_task_group_size":200,"test_qcloud_fake":True}. :param query_kwargs: Additional keyword parameters for querying quantum results, default value:{"timeout":2,"print_query_info":True,"sub_circuits_split_size":1}。 :return: The module that can calculate quantum circuits. .. note:: pauli_str_dict cannot be None and should be the same as obs in the vqc_module measurement function. vqc_module should have attributes of type QMachine, and QMachine should set save_ir=True. Example:: from pyvqnet.qnn.vqc import * import pyvqnet from pyvqnet.nn import Module,Linear class Hybird(Module): def __init__(self): self.cl1 = Linear(3,3) self.ql = QModel(num_wires=6, dtype=pyvqnet.kcomplex64) self.cl2 = Linear(1,2) def forward(self,x): x = self.cl1(x) x = self.ql(x) x = self.cl2(x) return x class QModel(Module): def __init__(self, num_wires, dtype,grad_mode=""): super(QModel, self).__init__() self._num_wires = num_wires self._dtype = dtype self.qm = QMachine(num_wires, dtype=dtype,grad_mode=grad_mode,save_ir=True) self.rx_layer = RX(has_params=True, trainable=False, wires=0) self.ry_layer = RY(has_params=True, trainable=False, wires=1) self.rz_layer = RZ(has_params=True, trainable=False, wires=1) self.u1 = U1(has_params=True,trainable=True,wires=[2]) self.u2 = U2(has_params=True,trainable=True,wires=[3]) self.u3 = U3(has_params=True,trainable=True,wires=[1]) self.i = I(wires=[3]) self.s = S(wires=[3]) self.x1 = X1(wires=[3]) self.y1 = Y1(wires=[3]) self.z1 = Z1(wires=[3]) self.x = PauliX(wires=[3]) self.y = PauliY(wires=[3]) self.z = PauliZ(wires=[3]) self.swap = SWAP(wires=[2,3]) self.cz = CZ(wires=[2,3]) self.cr = CR(has_params=True,trainable=True,wires=[2,3]) self.rxx = RXX(has_params=True,trainable=True,wires=[2,3]) self.rzz = RYY(has_params=True,trainable=True,wires=[2,3]) self.ryy = RZZ(has_params=True,trainable=True,wires=[2,3]) self.rzx = RZX(has_params=True,trainable=False, wires=[2,3]) self.toffoli = Toffoli(wires=[2,3,4],use_dagger=True) #self.rz_layer2 = RZ(has_params=True, trainable=True, wires=1) self.h =Hadamard(wires=[1]) self.iSWAP = iSWAP(True,True,wires=[0,2]) self.tlayer = T(wires=1) self.cnot = CNOT(wires=[0, 1]) self.measure = MeasureAll(obs={'Z0':2,'Y3':3} ) def forward(self, x, *args, **kwargs): self.qm.reset_states(x.shape[0]) self.i(q_machine=self.qm) self.s(q_machine=self.qm) self.swap(q_machine=self.qm) self.cz(q_machine=self.qm) self.x(q_machine=self.qm) self.x1(q_machine=self.qm) self.y(q_machine=self.qm) self.y1(q_machine=self.qm) self.z(q_machine=self.qm) self.z1(q_machine=self.qm) self.ryy(q_machine=self.qm) self.rxx(q_machine=self.qm) self.rzz(q_machine=self.qm) self.rzx(q_machine=self.qm,params = x[:,[1]]) self.cr(q_machine=self.qm) self.u1(q_machine=self.qm) self.u2(q_machine=self.qm) self.u3(q_machine=self.qm) self.rx_layer(params = x[:,[0]], q_machine=self.qm) self.cnot(q_machine=self.qm) self.h(q_machine=self.qm) self.iSWAP(q_machine=self.qm) self.ry_layer(params = x[:,[1]], q_machine=self.qm) self.tlayer(q_machine=self.qm) self.rz_layer(params = x[:,[2]], q_machine=self.qm) self.toffoli(q_machine=self.qm) rlt = self.measure(q_machine=self.qm) return rlt input_x = tensor.QTensor([[0.1, 0.2, 0.3]]) input_x = tensor.broadcast_to(input_x,[2,3]) input_x.requires_grad = True qunatum_model = QModel(num_wires=6, dtype=pyvqnet.kcomplex64) l = HybirdVQCQpandaQVMLayer(qunatum_model, "3047DE8A59764BEDAC9C3282093B16AF1", 5, 6, 6, pauli_str_dict={'Z0':2,'Y3':3}, shots = 1000, initializer=None, dtype=None, name="", submit_kwargs={"test_qcloud_fake":True}, query_kwargs={}) y = l(input_x) print(y) y.backward() print(input_x.grad) QuantumLayerAdjoint ----------------------------------------- .. py:class:: pyvqnet.qnn.vqc.QuantumLayerAdjoint(general_module: pyvqnet.nn.Module, q_machine: QMachine,name="") An automatically differentiated QuantumLayer layer that uses adjoint matrix method for gradient calculation, refer to `Efficient calculation of gradients in classical simulations of variational quantum algorithms `_. :param general_module: A `pyvqnet.nn.Module` instance built using only the `pyvqnet.qnn.vqc` lower quantum circuit interface. :param q_machine: comes from the QMachine defined in general_module. :param name: The name of this layer, the default is "". .. note:: QMachine for general_module should set grad_method = "adjoint". Currently, the following parametric logic gates are supported: `RX`, `RY`, `RZ`, `PhaseShift`, `RXX`, `RYY`, `RZZ`, `RZX`, `U1`, `U2`, `U3` and other variational circuits without parametric logic gates. Example:: from pyvqnet import tensor from pyvqnet.qnn.vqc import QuantumLayerAdjoint, QMachine, RX, RY, CNOT, PauliX, qmatrix, PauliZ, T, MeasureAll, RZ, VQC_RotCircuit, VQC_HardwareEfficientAnsatz import pyvqnet from pyvqnet.utils import set_random_seed set_random_seed(42) class QModel(pyvqnet.nn.Module): def __init__(self, num_wires, dtype, grad_mode=""): super(QModel, self).__init__() self._num_wires = num_wires self._dtype = dtype self.qm = QMachine(num_wires, dtype=dtype, grad_mode=grad_mode) self.rx_layer = RX(has_params=True, trainable=False, wires=0) self.ry_layer = RY(has_params=True, trainable=False, wires=1) self.rz_layer = RZ(has_params=True, trainable=False, wires=1) self.rz_layer2 = RZ(has_params=True, trainable=True, wires=1) self.rot = VQC_HardwareEfficientAnsatz(6, ["rx", "RY", "rz"], entangle_gate="cnot", entangle_rules="linear", depth=5) self.tlayer = T(wires=1) self.cnot = CNOT(wires=[0, 1]) self.measure = MeasureAll(obs = { 'wires': [1], 'observables': ['x'], 'coefficient': [1] }) def forward(self, x, *args, **kwargs): self.qm.reset_states(x.shape[0]) self.rx_layer(params=x[:, [0]], q_machine=self.qm) self.cnot(q_machine=self.qm) self.ry_layer(params=x[:, [1]], q_machine=self.qm) self.tlayer(q_machine=self.qm) self.rz_layer(params=x[:, [2]], q_machine=self.qm) self.rz_layer2(q_machine=self.qm) self.rot(q_machine=self.qm) rlt = self.measure(q_machine=self.qm) return rlt input_x = tensor.QTensor([[0.1, 0.2, 0.3]]) input_x = tensor.broadcast_to(input_x, [4, 3]) input_x.requires_grad = True qunatum_model = QModel(num_wires=6, dtype=pyvqnet.kcomplex64, grad_mode="adjoint") adjoint_model = QuantumLayerAdjoint(qunatum_model, qunatum_model.qm) batch_y = adjoint_model(input_x) batch_y.backward() print(batch_y) # [[-0.0778451], # [-0.0778451], # [-0.0778451], # [-0.0778451]] QuantumLayerES --------------------------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.QuantumLayerES(general_module: nn.Module, q_machine: QMachine, name="", sigma = np.pi / 24) Automatically Differentiable QuantumLayer Layer for Gradient Calculation According to Evolutionary Strategies, refer to `Learning to learn with an evolutionary strategy Learning to learn with an evolutionary strategy `_ . :param general_module: An instance of `pyvqnet.nn.QModule` built using only the quantum line interface under `pyvqnet.qnn.vqc`. :param q_machine: The QMachine from the general_module definition. :param name: The name of the layer, defaults to "". :param sigma: The sampling variance of the multivariate sigma distribution. .. note:: The QMachine for general_module should have grad_method = "ES". Variable division lines consisting of the following parametric logic gates `RX`, `RY`, `RZ`, `PhaseShift`, `RXX`, `RYY`, `RZZ`, `RZX`, `U1`, `U2`, `U3`, and other non-parametric logic gates are supported at present. Example:: from pyvqnet import tensor from pyvqnet.qnn.vqc import QuantumLayerES, QMachine, RX, RY, CNOT, T, MeasureAll, RZ, VQC_HardwareEfficientAnsatz import pyvqnet class QModel(pyvqnet.nn.Module): def __init__(self, num_wires, dtype, grad_mode=""): super(QModel, self).__init__() self._num_wires = num_wires self._dtype = dtype self.qm = QMachine(num_wires, dtype=dtype, grad_mode=grad_mode) self.rx_layer = RX(has_params=True, trainable=False, wires=0) self.ry_layer = RY(has_params=True, trainable=False, wires=1) self.rz_layer = RZ(has_params=True, trainable=False, wires=1) self.rz_layer2 = RZ(has_params=True, trainable=True, wires=1) self.rot = VQC_HardwareEfficientAnsatz(6, ["rx", "RY", "rz"], entangle_gate="cnot", entangle_rules="linear", depth=5) self.tlayer = T(wires=1) self.cnot = CNOT(wires=[0, 1]) self.measure = MeasureAll(obs = { 'wires': [1], 'observables': ['x'], 'coefficient': [1] }) def forward(self, x, *args, **kwargs): self.qm.reset_states(x.shape[0]) self.rx_layer(params=x[:, [0]], q_machine=self.qm) self.cnot(q_machine=self.qm) self.ry_layer(params=x[:, [1]], q_machine=self.qm) self.tlayer(q_machine=self.qm) self.rz_layer(params=x[:, [2]], q_machine=self.qm) self.rz_layer2(q_machine=self.qm) self.rot(q_machine=self.qm) rlt = self.measure(q_machine=self.qm) return rlt input_x = tensor.QTensor([[0.1, 0.2, 0.3]]) input_x = tensor.broadcast_to(input_x, [40, 3]) input_x.requires_grad = True qunatum_model = QModel(num_wires=6, dtype=pyvqnet.kcomplex64, grad_mode="ES") ES_model = QuantumLayerES(qunatum_model, qunatum_model.qm) batch_y = ES_model(input_x) batch_y.backward() print(batch_y) # [[-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365], # [-0.1664365]] vqc_to_originir_list ------------------------------------- .. py:function:: pyvqnet.qnn.vqc.vqc_to_originir_list(vqc_model: pyvqnet.nn.Module) Convert VQNet vqc module to `originIR `_ . vqc_model should run the forward function before this function to get the input data. If the input data is batch data. For each input it will return multiple IR strings. :param vqc_model: VQNet vqc module, which should be run forward first. :return: originIR string or originIR string list. Example:: import pyvqnet import pyvqnet.tensor as tensor from pyvqnet.qnn.vqc import * from pyvqnet.nn import Module from pyvqnet.utils import set_random_seed set_random_seed(42) class QModel(Module): def __init__(self, num_wires, dtype,grad_mode=""): super(QModel, self).__init__() self._num_wires = num_wires self._dtype = dtype self.qm = QMachine(num_wires, dtype=dtype,grad_mode=grad_mode,save_ir=True) self.rx_layer = RX(has_params=True, trainable=False, wires=0) self.ry_layer = RY(has_params=True, trainable=False, wires=1) self.rz_layer = RZ(has_params=True, trainable=False, wires=1) self.u1 = U1(has_params=True,trainable=True,wires=[2]) self.u2 = U2(has_params=True,trainable=True,wires=[3]) self.u3 = U3(has_params=True,trainable=True,wires=[1]) self.i = I(wires=[3]) self.s = S(wires=[3]) self.x1 = X1(wires=[3]) self.y1 = Y1(wires=[3]) self.z1 = Z1(wires=[3]) self.x = PauliX(wires=[3]) self.y = PauliY(wires=[3]) self.z = PauliZ(wires=[3]) self.swap = SWAP(wires=[2,3]) self.cz = CZ(wires=[2,3]) self.cr = CR(has_params=True,trainable=True,wires=[2,3]) self.rxx = RXX(has_params=True,trainable=True,wires=[2,3]) self.rzz = RYY(has_params=True,trainable=True,wires=[2,3]) self.ryy = RZZ(has_params=True,trainable=True,wires=[2,3]) self.rzx = RZX(has_params=True,trainable=False, wires=[2,3]) self.toffoli = Toffoli(wires=[2,3,4],use_dagger=True) #self.rz_layer2 = RZ(has_params=True, trainable=True, wires=1) self.h =Hadamard(wires=[1]) self.rot = VQC_HardwareEfficientAnsatz(6, ["rx", "RY", "rz"], entangle_gate="cnot", entangle_rules="linear", depth=5) self.iSWAP = iSWAP(True,True,wires=[0,2]) self.tlayer = T(wires=1) self.cnot = CNOT(wires=[0, 1]) self.measure = MeasureAll(obs = { 'wires': [1], 'observables': ['x'], 'coefficient': [1] }) def forward(self, x, *args, **kwargs): self.qm.reset_states(x.shape[0]) self.i(q_machine=self.qm) self.s(q_machine=self.qm) self.swap(q_machine=self.qm) self.cz(q_machine=self.qm) self.x(q_machine=self.qm) self.x1(q_machine=self.qm) self.y(q_machine=self.qm) self.y1(q_machine=self.qm) self.z(q_machine=self.qm) self.z1(q_machine=self.qm) self.ryy(q_machine=self.qm) self.rxx(q_machine=self.qm) self.rzz(q_machine=self.qm) self.rzx(q_machine=self.qm,params = x[:,[1]]) self.cr(q_machine=self.qm) self.u1(q_machine=self.qm) self.u2(q_machine=self.qm) self.u3(q_machine=self.qm) self.rx_layer(params = x[:,[0]], q_machine=self.qm) self.cnot(q_machine=self.qm) self.h(q_machine=self.qm) self.iSWAP(q_machine=self.qm) self.ry_layer(params = x[:,[1]], q_machine=self.qm) self.tlayer(q_machine=self.qm) self.rz_layer(params = x[:,[2]], q_machine=self.qm) self.toffoli(q_machine=self.qm) rlt = self.measure(q_machine=self.qm) return rlt input_x = tensor.QTensor([[0.1, 0.2, 0.3]]) input_x = tensor.broadcast_to(input_x,[2,3]) input_x.requires_grad = True qunatum_model = QModel(num_wires=6, dtype=pyvqnet.kcomplex64) batch_y = qunatum_model(input_x) batch_y.backward() ll = vqc_to_originir_list(qunatum_model) from pyqpanda import CPUQVM,convert_originir_str_to_qprog,convert_qprog_to_originir for l in ll : print(l) machine = CPUQVM() machine.init_qvm() prog, qv, cv = convert_originir_str_to_qprog(l, machine) print(machine.prob_run_dict(prog,qv)) # QINIT 6 # CREG 6 # I q[3] # S q[3] # SWAP q[2],q[3] # CZ q[2],q[3] # X q[3] # X1 q[3] # Y q[3] # Y1 q[3] # Z q[3] # Z1 q[3] # RZZ q[2],q[3],(4.484121322631836) # RXX q[2],q[3],(5.302337169647217) # RYY q[2],q[3],(3.470323085784912) # RZX q[2],q[3],(0.20000000298023224) # CR q[2],q[3],(5.467088222503662) # U1 q[2],(6.254805088043213) # U2 q[3],(1.261604905128479,0.9901542067527771) # U3 q[1],(5.290454387664795,6.182775020599365,1.1797741651535034) # RX q[0],(0.10000000149011612) # CNOT q[0],q[1] # H q[1] # ISWAPTHETA q[0],q[2],(0.6857681274414062) # RY q[1],(0.20000000298023224) # T q[1] # RZ q[1],(0.30000001192092896) # DAGGER # TOFFOLI q[2],q[3],q[4] # ENDDAGGER # {'000000': 0.006448949346548678, '000001': 0.004089870964118778, '000010': 0.1660891289303212, '000011': 0.08520414851665635, '000100': 0.0048503036661063, '000101': 8.679196482917438e-05, '000110': 0.14379026566368325, '000111': 0.0005079553597106437, '001000': 0.0023774056959510325, '001001': 0.008241263544544148, '001010': 0.06122877075562884, '001011': 0.1984226195587807, '001100': 0.0, '001101': 0.0, '001110': 0.0, '001111': 0.0, '010000': 0.0, '010001': 0.0, '010010': 0.0, '010011': 0.0, '010100': 0.0, '010101': 0.0, '010110': 0.0, '010111': 0.0, '011000': 0.0, '011001': 0.0, '011010': 0.0, '011011': 0.0, '011100': 0.011362100696548312, '011101': 0.00019143557058348747, '011110': 0.3059886012103368, '011111': 0.0011203885556518832, '100000': 0.0, '100001': 0.0, '100010': 0.0, '100011': 0.0, '100100': 0.0, '100101': 0.0, '100110': 0.0, '100111': 0.0, '101000': 0.0, '101001': 0.0, '101010': 0.0, '101011': 0.0, '101100': 0.0, '101101': 0.0, '101110': 0.0, '101111': 0.0, '110000': 0.0, '110001': 0.0, '110010': 0.0, '110011': 0.0, '110100': 0.0, '110101': 0.0, '110110': 0.0, '110111': 0.0, '111000': 0.0, '111001': 0.0, '111010': 0.0, '111011': 0.0, '111100': 0.0, '111101': 0.0, '111110': 0.0, '111111': 0.0} # QINIT 6 # CREG 6 # I q[3] # S q[3] # SWAP q[2],q[3] # CZ q[2],q[3] # X q[3] # X1 q[3] # Y q[3] # Y1 q[3] # Z q[3] # Z1 q[3] # RZZ q[2],q[3],(4.484121322631836) # RXX q[2],q[3],(5.302337169647217) # RYY q[2],q[3],(3.470323085784912) # RZX q[2],q[3],(0.20000000298023224) # CR q[2],q[3],(5.467088222503662) # U1 q[2],(6.254805088043213) # U2 q[3],(1.261604905128479,0.9901542067527771) # U3 q[1],(5.290454387664795,6.182775020599365,1.1797741651535034) # RX q[0],(0.10000000149011612) # CNOT q[0],q[1] # H q[1] # ISWAPTHETA q[0],q[2],(0.6857681274414062) # RY q[1],(0.20000000298023224) # T q[1] # RZ q[1],(0.30000001192092896) # DAGGER # TOFFOLI q[2],q[3],q[4] # ENDDAGGER # {'000000': 0.006448949346548678, '000001': 0.004089870964118778, '000010': 0.1660891289303212, '000011': 0.08520414851665635, '000100': 0.0048503036661063, '000101': 8.679196482917438e-05, '000110': 0.14379026566368325, '000111': 0.0005079553597106437, '001000': 0.0023774056959510325, '001001': 0.008241263544544148, '001010': 0.06122877075562884, '001011': 0.1984226195587807, '001100': 0.0, '001101': 0.0, '001110': 0.0, '001111': 0.0, '010000': 0.0, '010001': 0.0, '010010': 0.0, '010011': 0.0, '010100': 0.0, '010101': 0.0, '010110': 0.0, '010111': 0.0, '011000': 0.0, '011001': 0.0, '011010': 0.0, '011011': 0.0, '011100': 0.011362100696548312, '011101': 0.00019143557058348747, '011110': 0.3059886012103368, '011111': 0.0011203885556518832, '100000': 0.0, '100001': 0.0, '100010': 0.0, '100011': 0.0, '100100': 0.0, '100101': 0.0, '100110': 0.0, '100111': 0.0, '101000': 0.0, '101001': 0.0, '101010': 0.0, '101011': 0.0, '101100': 0.0, '101101': 0.0, '101110': 0.0, '101111': 0.0, '110000': 0.0, '110001': 0.0, '110010': 0.0, '110011': 0.0, '110100': 0.0, '110101': 0.0, '110110': 0.0, '110111': 0.0, '111000': 0.0, '111001': 0.0, '111010': 0.0, '111011': 0.0, '111100': 0.0, '111101': 0.0, '111110': 0.0, '111111': 0.0} originir_to_vqc ------------------------------------------ .. py:function:: pyvqnet.qnn.vqc.originir_to_vqc(originir, tmp="code_tmp.py", verbose=False) Parse originIR into vqc model code. The code creates a variational quantum circuit `pyvqnet.nn.Module` without `Measure`, and returns the state vector form of the quantum state, such as [b,2,...,2]. This function will generate a code file defining the corresponding VQNet model in "./origin_ir_gen_code/" + tmp + ".py". :param originir: Original IR. :param tmp: code file name, default ``code_tmp.py``. :param verbose: If display generated code, default = False :return: Generate runnable code. Example:: from pyvqnet.qnn.vqc import originir_to_vqc ss = "QINIT 3\nCREG 3\nH q[1]" Z = originir_to_vqc(ss,verbose=True) exec(Z) m =Exported_Model() print(m(2)) # from pyvqnet.nn import Module # from pyvqnet.tensor import QTensor # from pyvqnet.qnn.vqc import * # class Exported_Model(Module): # def __init__(self, name=""): # super().__init__(name) # self.q_machine = QMachine(num_wires=3) # self.H_0 = Hadamard(wires=1, use_dagger = False) # def forward(self, x, *args, **kwargs): # x = self.H_0(q_machine=self.q_machine) # return self.q_machine.states # [[[[0.7071068+0.j 0. +0.j] # [0.7071068+0.j 0. +0.j]] # [[0. +0.j 0. +0.j] # [0. +0.j 0. +0.j]]]] model_summary ----------------------------------------------- .. py:function:: pyvqnet.model_summary(vqc_module) Print information about classical layer and quantum gate operators registered in vqc_module. :param vqc_module: vqc module :return: summary string Example:: from pyvqnet.qnn.vqc import QMachine, RX, RY, CNOT, PauliX, qmatrix, PauliZ,MeasureAll from pyvqnet.tensor import QTensor, tensor,kcomplex64 import pyvqnet from pyvqnet.nn import LSTM,Linear from pyvqnet import model_summary class QModel(pyvqnet.nn.Module): def __init__(self, num_wires, dtype): super(QModel, self).__init__() self._num_wires = num_wires self._dtype = dtype self.qm = QMachine(num_wires, dtype=dtype) self.rx_layer1 = RX(has_params=True, trainable=True, wires=1, init_params=tensor.QTensor([0.5])) self.ry_layer2 = RY(has_params=True, trainable=True, wires=0, init_params=tensor.QTensor([-0.5])) self.xlayer = PauliX(wires=0) self.cnot = CNOT(wires=[0, 1]) self.measure = MeasureAll(obs = PauliZ) self.linear = Linear(24,2) self.lstm =LSTM(23,5) def forward(self, x, *args, **kwargs): return super().forward(x, *args, **kwargs) Z = QModel(4,kcomplex64) print(model_summary(Z)) # ###################QModel Summary####################### # classic layers: {'Linear': 1, 'LSTM': 1} # total classic parameters: 650 # ========================================= # qubits num: 4 # gates: {'RX': 1, 'RY': 1, 'PauliX': 1, 'CNOT': 1} # total quantum gates: 4 # total quantum parameter gates: 2 # total quantum parameters: 2 # ######################################################### QNG --------------------------------------------------------------- .. py:class:: pyvqnet.qnn.vqc.qng.QNG(qmodel, stepsize=0.01) Quantum machine learning models generally use the gradient descent method to optimize parameters in variable quantum logic circuits. The formula of the classic gradient descent method is as follows: .. math:: \theta_{t+1} = \theta_t -\eta \nabla \mathcal{L}(\theta), Essentially, at each iteration, we will calculate the direction of the steepest gradient drop in the parameter space as the direction of parameter change. In any direction in space, the speed of descent in the local range is not as fast as that of the negative gradient direction. In different spaces, the derivation of the direction of steepest descent is dependent on the norm of parameter differentiation - the distance metric. The distance metric plays a central role here, Different metrics result in different directions of steepest descent. For the Euclidean space where the parameters in the classical optimization problem are located, the direction of the steepest descent is the direction of the negative gradient. Even so, at each step of parameter optimization, as the loss function changes with parameters, its parameter space is transformed. Make it possible to find another better distance norm. `Quantum natural gradient method `_ draws on concepts from `classical natural gradient method Amari `__ , We instead view the optimization problem as a probability distribution of possible output values for a given input (i.e., maximum likelihood estimation), a better approach is in the distribution Gradient descent is performed in the space, which is dimensionless and invariant with respect to the parameterization. Therefore, regardless of the parameterization, each optimization step will always choose the optimal step size for each parameter. In quantum machine learning tasks, the quantum state space has a unique invariant metric tensor called the Fubini-Study metric tensor :math:`g_{ij}`. This tensor converts the steepest descent in the quantum circuit parameter space to the steepest descent in the distribution space. The formula for the quantum natural gradient is as follows: .. math:: \theta_{t+1} = \theta_t - \eta g^{+}(\theta_t)\nabla \mathcal{L}(\theta), where :math:`g^{+}` is the pseudo-inverse. `wrapper_calculate_qng` is a decorator that needs to be added to the forward function of the model to be calculated for the quantum natural gradient. Only parameters of type `Parameter` registered with the model are optimized. :param qmodel: Quantum variational circuit model, you need to use `wrapper_calculate_qng` as the decorator of the forward function. :param stepsize: The step size of the gradient descent method, the default is 0.01. .. note:: Only tested on non-batch data. Only purely variational quantum circuits are supported. step() will update the gradients of the input and parameters. step() only updates the numerical values of the model parameters. Example:: from pyvqnet.qnn.vqc import QMachine, RX, RY, RZ, CNOT, rz, PauliX, qmatrix, PauliZ, Probability, rx, ry, MeasureAll, U2 from pyvqnet.tensor import QTensor, tensor import pyvqnet import numpy as np from pyvqnet.qnn.vqc import wrapper_calculate_qng class QModel(pyvqnet.nn.Module): def __init__(self, num_wires, dtype): super(QModel, self).__init__() self._num_wires = num_wires self._dtype = dtype self.qm = QMachine(num_wires, dtype=dtype) self.rz_layer1 = RZ(has_params=True, trainable=False, wires=0) self.rz_layer2 = RZ(has_params=True, trainable=False, wires=1) self.u2_layer1 = U2(has_params=True, trainable=False, wires=0) self.l_train1 = RY(has_params=True, trainable=True, wires=1) self.l_train1.params.init_from_tensor( QTensor([333], dtype=pyvqnet.kfloat32)) self.l_train2 = RX(has_params=True, trainable=True, wires=2) self.l_train2.params.init_from_tensor( QTensor([4444], dtype=pyvqnet.kfloat32)) self.xlayer = PauliX(wires=0) self.cnot01 = CNOT(wires=[0, 1]) self.cnot12 = CNOT(wires=[1, 2]) self.measure = MeasureAll(obs={'Y0': 1}) @wrapper_calculate_qng def forward(self, x, *args, **kwargs): self.qm.reset_states(x.shape[0]) ry(q_machine=self.qm, wires=0, params=np.pi / 4) ry(q_machine=self.qm, wires=1, params=np.pi / 3) ry(q_machine=self.qm, wires=2, params=np.pi / 7) self.rz_layer1(q_machine=self.qm, params=x[:, [0]]) self.rz_layer2(q_machine=self.qm, params=x[:, [1]]) self.u2_layer1(q_machine=self.qm, params=x[:, [3, 4]]) # self.cnot01(q_machine=self.qm) self.cnot12(q_machine=self.qm) ry(q_machine=self.qm, wires=0, params=np.pi / 7) self.l_train1(q_machine=self.qm) self.l_train2(q_machine=self.qm) #rx(q_machine=self.qm, wires=2, params=x[:, [3]]) rz(q_machine=self.qm, wires=1, params=x[:, [2]]) ry(q_machine=self.qm, wires=0, params=np.pi / 7) rz(q_machine=self.qm, wires=1, params=x[:, [2]]) self.cnot01(q_machine=self.qm) self.cnot12(q_machine=self.qm) rlt = self.measure(q_machine=self.qm) return rlt qmodel = QModel(3, pyvqnet.kcomplex64) x = QTensor([[1111.0, 2222, 444, 55, 666]]) qng = pyvqnet.qnn.vqc.QNG(qmodel,0.01) qng.step(x) print(qmodel.parameters()) #[[[333.0084]], [[4443.9985]]] wrapper_single_qubit_op_fuse --------------------------------------------------------------- .. py:function:: pyvqnet.qnn.vqc.wrapper_single_qubit_op_fuse(f) A decorator for fusing single-bit operations into Rot operations. .. note:: f is the forward function of the module, and the forward function of the model needs to be run once to take effect. The model defined here inherits from `pyvqnet.qnn.vqc.QModule`, which is a subclass of `pyvqnet.nn.Module`. Example:: from pyvqnet import tensor from pyvqnet.qnn.vqc import QMachine, Operation, apply_unitary_bmm from pyvqnet import kcomplex128 from pyvqnet.tensor import adjoint import numpy as np from pyvqnet.qnn.vqc import single_qubit_ops_fuse, wrapper_single_qubit_op_fuse, QModule,op_history_summary from pyvqnet.qnn.vqc import QMachine, RX, RY, CNOT, PauliX, qmatrix, PauliZ, T, MeasureAll, RZ from pyvqnet.tensor import QTensor, tensor import pyvqnet import numpy as np from pyvqnet.utils import set_random_seed set_random_seed(42) class QModel(QModule): def __init__(self, num_wires, dtype): super(QModel, self).__init__() self._num_wires = num_wires self._dtype = dtype self.qm = QMachine(num_wires, dtype=dtype) self.rx_layer = RX(has_params=True, trainable=False, wires=0, dtype=dtype) self.ry_layer = RY(has_params=True, trainable=False, wires=1, dtype=dtype) self.rz_layer = RZ(has_params=True, trainable=False, wires=1, dtype=dtype) self.rz_layer2 = RZ(has_params=True, trainable=False, wires=1, dtype=dtype) self.tlayer = T(wires=1) self.cnot = CNOT(wires=[0, 1]) self.measure = MeasureAll(obs={ 'wires': [1], 'observables': ['x'], 'coefficient': [1] }) @wrapper_single_qubit_op_fuse def forward(self, x, *args, **kwargs): self.qm.reset_states(x.shape[0]) self.rx_layer(params=x[:, [0]], q_machine=self.qm) self.cnot(q_machine=self.qm) self.ry_layer(params=x[:, [1]], q_machine=self.qm) self.tlayer(q_machine=self.qm) self.rz_layer(params=x[:, [2]], q_machine=self.qm) self.rz_layer2(params=x[:, [3]], q_machine=self.qm) rlt = self.measure(q_machine=self.qm) return rlt input_x = tensor.QTensor([[0.1, 0.2, 0.3, 0.4], [0.1, 0.2, 0.3, 0.4]], dtype=pyvqnet.kfloat64) input_xt = tensor.tile(input_x, (100, 1)) input_xt.requires_grad = True qunatum_model = QModel(num_wires=2, dtype=pyvqnet.kcomplex128) batch_y = qunatum_model(input_xt) print(op_history_summary(qunatum_model.qm.op_history)) # ###################Summary####################### # qubits num: 2 # gates: {'rot': 2, 'cnot': 1} # total gates: 3 # total parameter gates: 2 # total parameters: 6 # ################################################# wrapper_commute_controlled --------------------------------------------------------------- .. py:function:: pyvqnet.qnn.vqc.wrapper_commute_controlled(f, direction = "right") Decorators for controlled door swapping This is a quantum transformation used to move swappable gates in front of the control and target bits of the controlled operation. The diagonal gates on either side of the control bit do not affect the result of the controlled gate; therefore, we can push all single-bit gates acting on the first bit together to the right (and fuse them if necessary). Similarly, X-gates are interchangeable with the target bits of CNOT and Toffoli (as are PauliY and CRY). We can use this transformation to push single-bit gates as deep into controlled operation as possible. .. note:: f is the forward function of the module, and the forward function of the model needs to be run once to take effect. The model defined here inherits from `pyvqnet.qnn.vqc.QModule`, which is a subclass of `pyvqnet.nn.Module`. :param f: forward function. :param direction: The direction to move the single-bit gate, the optional value is "left" or "right", the default is "right". Example:: from pyvqnet import tensor from pyvqnet.qnn.vqc import QMachine from pyvqnet import kcomplex128 from pyvqnet.tensor import adjoint import numpy as np from pyvqnet.qnn.vqc import wrapper_commute_controlled, pauliy, QModule,op_history_summary from pyvqnet.qnn.vqc import QMachine, RX, RY, CNOT, S, CRY, PauliZ, PauliX, T, MeasureAll, RZ, CZ, PhaseShift, Toffoli, cnot, cry, toffoli from pyvqnet.tensor import QTensor, tensor import pyvqnet import numpy as np from pyvqnet.utils import set_random_seed from pyvqnet.qnn import expval, QuantumLayerV2 import time from functools import partial set_random_seed(42) class QModel(QModule): def __init__(self, num_wires, dtype): super(QModel, self).__init__() self._num_wires = num_wires self._dtype = dtype self.qm = QMachine(num_wires, dtype=dtype) self.cz = CZ(wires=[0, 2]) self.paulix = PauliX(wires=2) self.s = S(wires=0) self.ps = PhaseShift(has_params=True, trainable= True, wires=0, dtype=dtype) self.t = T(wires=0) self.rz = RZ(has_params=True, wires=1, dtype=dtype) self.measure = MeasureAll(obs={ 'wires': [0], 'observables': ['z'], 'coefficient': [1] }) @partial(wrapper_commute_controlled, direction="left") def forward(self, x, *args, **kwargs): self.qm.reset_states(x.shape[0]) self.cz(q_machine=self.qm) self.paulix(q_machine=self.qm) self.s(q_machine=self.qm) cnot(q_machine=self.qm, wires=[0, 1]) pauliy(q_machine=self.qm, wires=1) cry(q_machine=self.qm, params=1 / 2, wires=[0, 1]) self.ps(q_machine=self.qm) toffoli(q_machine=self.qm, wires=[0, 1, 2]) self.t(q_machine=self.qm) self.rz(q_machine=self.qm) rlt = self.measure(q_machine=self.qm) return rlt import pyvqnet import pyvqnet.tensor as tensor input_x = tensor.QTensor([[0.1, 0.2, 0.3, 0.4], [0.1, 0.2, 0.3, 0.4]], dtype=pyvqnet.kfloat64) input_xt = tensor.tile(input_x, (100, 1)) input_xt.requires_grad = True qunatum_model = QModel(num_wires=3, dtype=pyvqnet.kcomplex128) batch_y = qunatum_model(input_xt) for d in qunatum_model.qm.op_history: name = d["name"] wires = d["wires"] p = d["params"] print(f"name: {name} wires: {wires}, params = {p}") # name: s wires: (0,), params = None # name: phaseshift wires: (0,), params = [[4.744782]] # name: t wires: (0,), params = None # name: cz wires: (0, 2), params = None # name: paulix wires: (2,), params = None # name: cnot wires: (0, 1), params = None # name: pauliy wires: (1,), params = None # name: cry wires: (0, 1), params = [[0.5]] # name: rz wires: (1,), params = [[4.7447823]] # name: toffoli wires: (0, 1, 2), params = None # name: MeasureAll wires: [0], params = None wrapper_merge_rotations --------------------------------------------------------------- .. py:function:: pyvqnet.qnn.vqc.wrapper_merge_rotations(f) Merge decorators for turnstiles of the same type, including "rx", "ry", "rz", "phaseshift", "crx", "cry", "crz", "controlledphaseshift", "isingxx", "isingyy", "isingzz", "rot". .. note:: f is the forward function of the module, and the forward function of the model needs to be run once to take effect. The model defined here inherits from `pyvqnet.qnn.vqc.QModule`, which is a subclass of `pyvqnet.nn.Module`. :param f: forward function. Example:: import pyvqnet from pyvqnet.tensor import tensor from pyvqnet import tensor from pyvqnet.qnn.vqc import QMachine,op_history_summary from pyvqnet import kcomplex128 from pyvqnet.tensor import adjoint import numpy as np from pyvqnet.qnn.vqc import * from pyvqnet.qnn.vqc import QModule from pyvqnet.tensor import QTensor, tensor import pyvqnet import numpy as np from pyvqnet.utils import set_random_seed set_random_seed(42) class QModel(QModule): def __init__(self, num_wires, dtype): super(QModel, self).__init__() self._num_wires = num_wires self._dtype = dtype self.qm = QMachine(num_wires, dtype=dtype) self.measure = MeasureAll(obs={ 'wires': [0], 'observables': ['z'], 'coefficient': [1] }) @wrapper_merge_rotations def forward(self, x, *args, **kwargs): self.qm.reset_states(x.shape[0]) rx(q_machine=self.qm, params=x[:, [1]], wires=(0, )) rx(q_machine=self.qm, params=x[:, [1]], wires=(0, )) rx(q_machine=self.qm, params=x[:, [1]], wires=(0, )) rot(q_machine=self.qm, params=x, wires=(1, ), use_dagger=True) rot(q_machine=self.qm, params=x, wires=(1, ), use_dagger=True) isingxy(q_machine=self.qm, params=x[:, [2]], wires=(0, 1)) isingxy(q_machine=self.qm, params=x[:, [0]], wires=(0, 1)) cnot(q_machine=self.qm, wires=[1, 2]) ry(q_machine=self.qm, params=x[:, [1]], wires=(1, )) hadamard(q_machine=self.qm, wires=(2, )) crz(q_machine=self.qm, params=x[:, [2]], wires=(2, 0)) ry(q_machine=self.qm, params=-x[:, [1]], wires=1) return self.measure(q_machine=self.qm) input_x = tensor.QTensor([[1, 2, 3], [1, 2, 3]], dtype=pyvqnet.kfloat64) input_x.requires_grad = True qunatum_model = QModel(num_wires=3, dtype=pyvqnet.kcomplex128) qunatum_model.use_merge_rotations = True batch_y = qunatum_model(input_x) print(op_history_summary(qunatum_model.qm.op_history)) # ###################Summary####################### # qubits num: 3 # gates: {'rx': 1, 'rot': 1, 'isingxy': 2, 'cnot': 1, 'hadamard': 1, 'crz': 1} # total gates: 7 # total parameter gates: 5 # total parameters: 7 # ################################################# wrapper_compile --------------------------------------------------------------- .. py:function:: pyvqnet.qnn.vqc.wrapper_compile(f,compile_rules=[commute_controlled_right, merge_rotations, single_qubit_ops_fuse]) Use compilation rules to optimize QModule's circuits. .. note:: f is the forward function of the module, and the forward function of the model needs to be run once to take effect. The model defined here inherits from `pyvqnet.qnn.vqc.QModule`, which is a subclass of `pyvqnet.nn.Module`. :param f: forward function. Example:: from functools import partial from pyvqnet.qnn.vqc import op_history_summary from pyvqnet.qnn.vqc import QModule from pyvqnet import tensor from pyvqnet.qnn.vqc import QMachine, wrapper_compile from pyvqnet.qnn.vqc import pauliy from pyvqnet.qnn.vqc import QMachine, ry,rz, ControlledPhaseShift, \ rx, S, rot, isingxy,CSWAP, PauliX, T, MeasureAll, RZ, CZ, PhaseShift, u3, cnot, cry, toffoli, cy from pyvqnet.tensor import QTensor, tensor import pyvqnet class QModel_before(QModule): def __init__(self, num_wires, dtype): super(QModel_before, self).__init__() self._num_wires = num_wires self._dtype = dtype self.qm = QMachine(num_wires, dtype=dtype) self.qm.set_save_op_history_flag(True) self.cswap = CSWAP(wires=(0, 2, 1)) self.cz = CZ(wires=[0, 2]) self.paulix = PauliX(wires=2) self.s = S(wires=0) self.ps = PhaseShift(has_params=True, trainable=True, wires=0, dtype=dtype) self.cps = ControlledPhaseShift(has_params=True, trainable=True, wires=(1, 0), dtype=dtype) self.t = T(wires=0) self.rz = RZ(has_params=True, wires=1, dtype=dtype) self.measure = MeasureAll(obs={ 'wires': [0], 'observables': ['z'], 'coefficient': [1] }) def forward(self, x, *args, **kwargs): self.qm.reset_states(x.shape[0]) self.cz(q_machine=self.qm) self.paulix(q_machine=self.qm) rx(q_machine=self.qm,wires=1,params = x[:,[0]]) ry(q_machine=self.qm,wires=1,params = x[:,[1]]) rz(q_machine=self.qm,wires=1,params = x[:,[2]]) rot(q_machine=self.qm, params=x[:, 0:3], wires=(1, ), use_dagger=True) rot(q_machine=self.qm, params=x[:, 1:4], wires=(1, ), use_dagger=True) isingxy(q_machine=self.qm, params=x[:, [2]], wires=(0, 1)) u3(q_machine=self.qm, params=x[:, 0:3], wires=1) self.s(q_machine=self.qm) self.cswap(q_machine=self.qm) cnot(q_machine=self.qm, wires=[0, 1]) ry(q_machine=self.qm,wires=2,params = x[:,[1]]) pauliy(q_machine=self.qm, wires=1) cry(q_machine=self.qm, params=1 / 2, wires=[0, 1]) self.ps(q_machine=self.qm) self.cps(q_machine=self.qm) ry(q_machine=self.qm,wires=2,params = x[:,[1]]) rz(q_machine=self.qm,wires=2,params = x[:,[2]]) toffoli(q_machine=self.qm, wires=[0, 1, 2]) self.t(q_machine=self.qm) cy(q_machine=self.qm, wires=(2, 1)) ry(q_machine=self.qm,wires=1,params = x[:,[1]]) self.rz(q_machine=self.qm) rlt = self.measure(q_machine=self.qm) return rlt class QModel(QModule): def __init__(self, num_wires, dtype): super(QModel, self).__init__() self._num_wires = num_wires self._dtype = dtype self.qm = QMachine(num_wires, dtype=dtype) self.cswap = CSWAP(wires=(0, 2, 1)) self.cz = CZ(wires=[0, 2]) self.paulix = PauliX(wires=2) self.s = S(wires=0) self.ps = PhaseShift(has_params=True, trainable=True, wires=0, dtype=dtype) self.cps = ControlledPhaseShift(has_params=True, trainable=True, wires=(1, 0), dtype=dtype) self.t = T(wires=0) self.rz = RZ(has_params=True, wires=1, dtype=dtype) self.measure = MeasureAll(obs={ 'wires': [0], 'observables': ['z'], 'coefficient': [1] }) @partial(wrapper_compile) def forward(self, x, *args, **kwargs): self.qm.reset_states(x.shape[0]) self.cz(q_machine=self.qm) self.paulix(q_machine=self.qm) rx(q_machine=self.qm,wires=1,params = x[:,[0]]) ry(q_machine=self.qm,wires=1,params = x[:,[1]]) rz(q_machine=self.qm,wires=1,params = x[:,[2]]) rot(q_machine=self.qm, params=x[:, 0:3], wires=(1, ), use_dagger=True) rot(q_machine=self.qm, params=x[:, 1:4], wires=(1, ), use_dagger=True) isingxy(q_machine=self.qm, params=x[:, [2]], wires=(0, 1)) u3(q_machine=self.qm, params=x[:, 0:3], wires=1) self.s(q_machine=self.qm) self.cswap(q_machine=self.qm) cnot(q_machine=self.qm, wires=[0, 1]) ry(q_machine=self.qm,wires=2,params = x[:,[1]]) pauliy(q_machine=self.qm, wires=1) cry(q_machine=self.qm, params=1 / 2, wires=[0, 1]) self.ps(q_machine=self.qm) self.cps(q_machine=self.qm) ry(q_machine=self.qm,wires=2,params = x[:,[1]]) rz(q_machine=self.qm,wires=2,params = x[:,[2]]) toffoli(q_machine=self.qm, wires=[0, 1, 2]) self.t(q_machine=self.qm) cy(q_machine=self.qm, wires=(2, 1)) ry(q_machine=self.qm,wires=1,params = x[:,[1]]) self.rz(q_machine=self.qm) rlt = self.measure(q_machine=self.qm) return rlt import pyvqnet import pyvqnet.tensor as tensor input_x = tensor.QTensor([[0.1, 0.2, 0.3, 0.4], [0.1, 0.2, 0.3, 0.4]], dtype=pyvqnet.kfloat64) input_x.requires_grad = True num_wires = 3 qunatum_model = QModel(num_wires=num_wires, dtype=pyvqnet.kcomplex128) qunatum_model_before = QModel_before(num_wires=num_wires, dtype=pyvqnet.kcomplex128) batch_y = qunatum_model(input_x) batch_y = qunatum_model_before(input_x) flatten_oph_names = [] print("before") print(op_history_summary(qunatum_model_before.qm.op_history)) flatten_oph_names = [] for d in qunatum_model.compiled_op_historys: if "compile" in d.keys(): oph = d["op_history"] for i in oph: n = i["name"] w = i["wires"] p = i["params"] flatten_oph_names.append({"name":n,"wires":w, "params": p}) print("after") print(op_history_summary(qunatum_model.qm.op_history)) # ###################Summary####################### # qubits num: 3 # gates: {'cz': 1, 'paulix': 1, 'rx': 1, 'ry': 4, 'rz': 3, 'rot': 2, 'isingxy': 1, 'u3': 1, 's': 1, 'cswap': 1, 'cnot': 1, 'pauliy': 1, 'cry': 1, 'phaseshift': 1, 'controlledphaseshift': 1, 'toffoli': 1, 't': 1, 'cy': 1} # total gates: 24 # total parameter gates: 15 # total parameters: 21 # ################################################# # after # ###################Summary####################### # qubits num: 3 # gates: {'cz': 1, 'rot': 7, 'isingxy': 1, 'u3': 1, 'cswap': 1, 'cnot': 1, 'cry': 1, 'controlledphaseshift': 1, 'toffoli': 1, 'cy': 1} # total gates: 16 # total parameter gates: 11 # total parameters: 27 # #################################################