IsEntanglingGate
IsEntanglingGate | |
Determines if a unitary is an entangling gate | |
Other toolboxes required | none |
---|---|
Related functions | IsProductOperator OperatorSchmidtDecomposition OperatorSchmidtRank |
Function category | Entanglement and separability |
IsEntanglingGate is a function that determines if a bipartite or multipartite unitary is an entangling gate or not (i.e., whether or not there is a product vector that is no longer a product vector after the unitary is applied). If it is an entangling gate, a product vector that is entangled by the gate can be provided, and if it is not an entangling gate then a decomposition that proves that it is not entangling can be provided.
Contents
Syntax
- EG = IsEntanglingGate(U)
- EG = IsEntanglingGate(U,DIM)
- [EG,WIT] = IsEntanglingGate(U,DIM)
Argument descriptions
Input arguments
- U: An operator (typically a unitary operator) that acts on a bipartite or multipartite Hilbert space.
- DIM (optional, by default has two subsystems of equal dimension): A specification of the dimensions of the subsystems that U lives on. DIM can be provided in one of three ways:
- If DIM is a scalar, it is assumed that U lives on the tensor product of two spaces, the first of which has dimension DIM and the second of which has dimension length(U)/DIM.
- If $U \in M_{n_1} \otimes \cdots \otimes M_{n_p}$ then DIM should be a row vector containing the dimensions (i.e., DIM = [n_1, ..., n_p]).
- If the subsystems aren't square (i.e., $U \in M_{m_1, n_1} \otimes \cdots \otimes M_{m_p, n_p}$) then DIM should be a matrix with two rows. The first row of DIM should contain the row dimensions of the subsystems (i.e., the m_{i}'s) and its second row should contain the column dimensions (i.e., the n_{i}'s). In other words, you should set DIM = [m_1, ..., m_p; n_1, ..., n_p].
Output arguments
- EG: Either 1 or 0, indicating that U is or is not an entangling gate.
- WIT (optional): If EG = 0 (i.e., U is not an entangling gate), then WIT is a struct with fields WIT.perm and WIT.dec such that PermutationOperator(DIM,WIT.perm)*Tensor(WIT.dec) equals U and thus verifies that U is indeed not an entangling gate. If EG = 1 (i.e., U is an entangling gate) then WIT is a (sparse) product pure state that is entangled by U. Furthermore, WIT will always have 2 or fewer non-zero entries in this case.
Examples
A bipartite example: the CNOT gate
The following code verifies that the CNOT gate is an entangling gate. The following code also requests a product pure state wit that is entangled by the CNOT gate. The product pure state returned in this case is $(|0\rangle + |1\rangle) \otimes |0\rangle/\sqrt{2}$, which maps to the Bell state $(|00\rangle + |11\rangle)/\sqrt{2}$:
>> U = [1 0 0 0;0 1 0 0;0 0 0 1;0 0 1 0]; >> [eg,wit] = IsEntanglingGate(U) eg = 1 wit = (1,1) 0.7071 (3,1) 0.7071 >> U*wit ans = 0.7071 0 0 0.7071
Notes
Despite the name and description of the function, it can be used on non-unitary (and even non-square) operators just fine. If U is not unitary, the function has the exact same interpretation: it determines whether or not there is a product vector that is mapped to a non-product vector.
Source code
Click on "expand" to the right to view the MATLAB source code for this function.
%% ISENTANGLINGGATE Determines if a unitary is an entangling gate
% This function has one required input argument:
% U: a unitary matrix
%
% EG = IsEntanglingGate(U) is either 1 or 0, indicating that U is or is
% not an entangling quantum gate.
%
% This function has one optional input argument:
% DIM (default has two subsystems of equal size)
%
% [EG,WIT] = IsEntanglingGate(U,DIM) determines that U is or is not an
% entangling gate, as above. DIM is a vector containing the dimensions
% of the subsystems that U acts on.
%
% If EG = 0 then WIT is a struct that contains a decomposition of U that
% verifies that it is not an entangling gate. More specifically, U can be
% written as a product of the permutation operator specified by WIT.perm
% and the elementary tensor with decomposition given by WIT.dec.
%
% If EG = 1 then WIT is a (sparse) product pure state that is entangled
% by U. Furthermore, WIT will always have 2 or fewer non-zero entries in
% this case.
%
% URL: http://www.qetlab.com/IsEntanglingGate
% requires: opt_args.m, IsProductOperator.m, IsProductVector.m,
% perm_inv.m, PermuteSystems.m, SchmidtDecomposition.m
%
% author: Nathaniel Johnston (nathaniel@njohnston.ca)
% package: QETLAB
% last updated: November 28, 2012
function [eg,wit] = IsEntanglingGate(U,varargin)
dU = size(U);
sdU = round(sqrt(dU));
% set optional argument defaults: dim=sqrt(length(U)), k=0
[dim] = opt_args({ [sdU(1) sdU(1);sdU(2) sdU(2)] },varargin{:});
% allow the user to enter a single number for dim
num_sys = length(dim);
if(num_sys == 1)
dim = [dim,dU(1)/dim];
if abs(dim(2) - round(dim(2))) >= 2*dU(1)*eps
error('IsEntanglingGate:InvalidDim','If DIM is a scalar, U must be square and DIM must evenly divide length(U); please provide the DIM array containing the dimensions of the subsystems.');
end
dim(2) = round(dim(2));
num_sys = 2;
end
% allow the user to enter a vector for dim if U is square
if(min(size(dim)) == 1)
dim = dim(:)'; % force dim to be a row vector
dim = [dim;dim];
end
% go through each permutation of the subsystems and check to see if U decomposes into a local unitary with respect to that permutation
p = perms(1:num_sys);
num_sys_fac = factorial(num_sys);
for j = 1:num_sys_fac
[ipo,wit.dec] = IsProductOperator(PermuteSystems(U,p(j,:),dim,1),[dim(1,p(j,:));dim(2,:)]);
if(ipo) % the given permutation of U is a product operator, so U is not entangling
eg = 0;
wit.perm = perm_inv(p(j,:));
return
end
end
% If all of the previous tests failed, the gate is entangling. Find a witness (i.e., a product state that is mapped to an entangled state), if requested.
eg = 1;
if(nargout > 1)
% I don't like using nested for loops in MATLAB, but I'm not sure of a
% way around it here. At least we only have 4 nested loops rather than
% num_sys loops.
for p = 1:num_sys % subsystem with two non-zero entries
% Create a cell that contains three identity matrices of useful sizes (that vary with p).
dp = [prod(dim(2,1:p-1)),dim(2,p),prod(dim(2,p+1:end))];
Id = {speye(dp(1)) speye(dp(2)) speye(dp(3))};
% Choose which one or two entries should be non-zero.
ind = [kron((1:dim(2,p)).',ones(1,2));nchoosek(1:dim(2,p),2)];
indend = nchoosek(dim(2,p)+1,2);
for q = 1:indend
for j = 1:dp(1) % subsystems with only one-non-zero entry
for k = 1:dp(3) % subsystems with only one-non-zero entry
wit = kron(kron(Id{1}(:,j),sum(Id{2}(:,ind(q,:)),2)),Id{3}(:,k));
if(~IsProductVector(U*wit,dim(1,:)))
wit = wit/norm(wit);
return
end
end
end
end
end
end