Source code for pennylane.measurements.mutual_info
# Copyright 2018-2021 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.# pylint: disable=protected-access"""This module contains the qml.mutual_info measurement."""fromcollections.abcimportSequencefromcopyimportcopyfromtypingimportOptionalimportpennylaneasqmlfrompennylane.wiresimportWiresfrom.measurementsimportMutualInfo,StateMeasurement
[docs]defmutual_info(wires0,wires1,log_base=None):r"""Mutual information between the subsystems prior to measurement: .. math:: I(A, B) = S(\rho^A) + S(\rho^B) - S(\rho^{AB}) where :math:`S` is the von Neumann entropy. The mutual information is a measure of correlation between two subsystems. More specifically, it quantifies the amount of information obtained about one system by measuring the other system. Args: wires0 (Sequence[int] or int): the wires of the first subsystem wires1 (Sequence[int] or int): the wires of the second subsystem log_base (float): Base for the logarithm. Returns: MutualInfoMP: measurement process instance **Example:** .. code-block:: python3 dev = qml.device("default.qubit", wires=2) @qml.qnode(dev) def circuit_mutual(x): qml.IsingXX(x, wires=[0, 1]) return qml.mutual_info(wires0=[0], wires1=[1]) Executing this QNode: >>> circuit_mutual(np.pi/2) 1.3862943611198906 It is also possible to get the gradient of the previous QNode: >>> param = np.array(np.pi/4, requires_grad=True) >>> qml.grad(circuit_mutual)(param) tensor(1.24645048, requires_grad=True) .. note:: Calculating the derivative of :func:`~.mutual_info` is currently supported when using the classical backpropagation differentiation method (``diff_method="backprop"``) with a compatible device and finite differences (``diff_method="finite-diff"``). .. seealso:: :func:`~pennylane.vn_entropy`, :func:`pennylane.math.mutual_info` """wires0=qml.wires.Wires(wires0)wires1=qml.wires.Wires(wires1)# the subsystems cannot overlapifnotany(qml.math.is_abstract(w)forwinwires0+wires1)and[wireforwireinwires0ifwireinwires1]:raiseqml.QuantumFunctionError("Subsystems for computing mutual information must not overlap.")returnMutualInfoMP(wires=(wires0,wires1),log_base=log_base)
[docs]classMutualInfoMP(StateMeasurement):"""Measurement process that computes the mutual information between the provided wires. Please refer to :func:`pennylane.mutual_info` for detailed documentation. Args: wires (Sequence[.Wires]): The wires the measurement process applies to. id (str): custom label given to a measurement instance, can be useful for some applications where the instance has to be identified log_base (float): base for the logarithm """def__str__(self):return"mutualinfo"_shortname=MutualInfo#! Note: deprecated. Change the value to "mutualinfo" in v0.42def_flatten(self):metadata=(("wires",tuple(self.raw_wires)),("log_base",self.log_base))return(None,None),metadata# pylint: disable=too-many-argumentsdef__init__(self,wires:Optional[Sequence[Wires]]=None,id:Optional[str]=None,log_base:Optional[float]=None,):self.log_base=log_basesuper().__init__(wires=wires,id=id)# pylint: disable=arguments-differ@classmethoddef_primitive_bind_call(cls,wires:Sequence,**kwargs):ifcls._wires_primitiveisNone:# pragma: no cover# just a safety checkreturntype.__call__(cls,wires=wires,**kwargs)# pragma: no coverreturncls._wires_primitive.bind(*wires[0],*wires[1],n_wires0=len(wires[0]),**kwargs)def__repr__(self):returnf"MutualInfo(wires0={self.raw_wires[0].tolist()}, wires1={self.raw_wires[1].tolist()}, log_base={self.log_base})"@propertydefhash(self):"""int: returns an integer hash uniquely representing the measurement process"""fingerprint=(self.__class__.__name__,tuple(self.raw_wires[0].tolist()),tuple(self.raw_wires[1].tolist()),self.log_base,)returnhash(fingerprint)@propertydefnumeric_type(self):returnfloat