Source code for pennylane.templates.subroutines.prepselprep
# Copyright 2018-2024 Xanadu Quantum Technologies Inc.# Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at# http://www.apache.org/licenses/LICENSE-2.0# Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License."""Contains the PrepSelPrep template."""# pylint: disable=arguments-differ,import-outside-toplevel,too-many-argumentsimportcopyimportpennylaneasqmlfrompennylane.operationimportOperationdef_get_new_terms(lcu):"""Compute a new sum of unitaries with positive coefficients"""coeffs,ops=lcu.terms()coeffs=qml.math.stack(coeffs)angles=qml.math.angle(coeffs)new_ops=[]forangle,opinzip(angles,ops):new_op=op@qml.GlobalPhase(-angle,wires=op.wires)new_ops.append(new_op)returnqml.math.abs(coeffs),new_ops
[docs]classPrepSelPrep(Operation):"""Implements a block-encoding of a linear combination of unitaries. .. warning:: Derivatives of this operator are not always guaranteed to exist. Args: lcu (Union[.Hamiltonian, .Sum, .Prod, .SProd, .LinearCombination]): The operator written as a linear combination of unitaries. control (Iterable[Any], Wires): The control qubits for the PrepSelPrep operator. **Example** We define an operator and a block-encoding circuit as: >>> lcu = qml.dot([0.3, -0.1], [qml.X(2), qml.Z(2)]) >>> control = [0, 1] >>> @qml.qnode(qml.device("default.qubit")) ... def circuit(lcu, control): ... qml.PrepSelPrep(lcu, control) ... return qml.state() We can see that the operator matrix, up to a normalization constant, is block encoded in the circuit matrix: >>> matrix_psp = qml.matrix(circuit, wire_order = [0, 1, 2])(lcu, control = control) >>> print(matrix_psp.real[0:2, 0:2]) [[-0.25 0.75] [ 0.75 0.25]] >>> matrix_lcu = qml.matrix(lcu) >>> print(qml.matrix(lcu).real / sum(abs(np.array(lcu.terms()[0])))) [[-0.25 0.75] [ 0.75 0.25]] """grad_method=Nonedef__init__(self,lcu,control=None,id=None):coeffs,ops=lcu.terms()control=qml.wires.Wires(control)self.hyperparameters["lcu"]=qml.ops.LinearCombination(coeffs,ops)self.hyperparameters["coeffs"]=coeffsself.hyperparameters["ops"]=opsself.hyperparameters["control"]=controlifany(control_wireinqml.wires.Wires.all_wires([op.wiresforopinops])forcontrol_wireincontrol):raiseValueError("Control wires should be different from operation wires.")target_wires=qml.wires.Wires.all_wires([op.wiresforopinops])self.hyperparameters["target_wires"]=target_wiresall_wires=target_wires+controlsuper().__init__(*self.data,wires=all_wires,id=id)def_flatten(self):return(self.lcu,),(self.control,)@classmethoddef_unflatten(cls,data,metadata)->"PrepSelPrep":returncls(data[0],metadata[0])def__repr__(self):returnf"PrepSelPrep(coeffs={tuple(self.coeffs)}, ops={tuple(self.ops)}, control={self.control})"
def__copy__(self):"""Copy this op"""cls=self.__class__copied_op=cls.__new__(cls)new_data=copy.copy(self.data)forattr,valueinvars(self).items():ifattr!="data":setattr(copied_op,attr,value)copied_op.data=new_datareturncopied_op@propertydefdata(self):"""Create data property"""returnself.lcu.data@data.setterdefdata(self,new_data):"""Set the data property"""self.hyperparameters["lcu"].data=new_data@propertydefcoeffs(self):"""The coefficients of the LCU."""returnself.hyperparameters["coeffs"]@propertydefops(self):"""The operations of the LCU."""returnself.hyperparameters["ops"]@propertydeflcu(self):"""The LCU to be block-encoded."""returnself.hyperparameters["lcu"]@propertydefcontrol(self):"""The control wires."""returnself.hyperparameters["control"]@propertydeftarget_wires(self):"""The wires of the input operators."""returnself.hyperparameters["target_wires"]@propertydefwires(self):"""All wires involved in the operation."""returnself.hyperparameters["control"]+self.hyperparameters["target_wires"]