PartialTranspose

From QETLAB
Revision as of 15:33, 29 September 2014 by Nathaniel (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search
PartialTranspose
Computes the partial transpose of a matrix

Other toolboxes required none
Related functions PartialMap
PartialTrace
Function category Superoperators

PartialTranspose is a function that computes the partial transpose of a matrix. The transposition may be taken on any subset of the subsystems on which the matrix acts.

Syntax

  • XPT = PartialTranspose(X)
  • XPT = PartialTranspose(X,SYS)
  • XPT = PartialTranspose(X,SYS,DIM)

Argument descriptions

  • X: A matrix to have its partial transpose returned.
  • SYS (optional, default 2): A scalar or vector containing the indices of the subsystems on which the transpose is to be applied.
  • DIM (optional, by default has all subsystems of equal dimension): A specification of the dimensions of the subsystems that X lives on. DIM can be provided in one of three ways:
    • If DIM is a scalar, it is assumed that X lives on the tensor product of two spaces, the first of which has dimension DIM and the second of which has dimension length(X)/DIM.
    • If $X \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., $X \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 mi's) and its second row should contain the column dimensions (i.e., the ni's). In other words, you should set DIM = [m_1, ..., m_p; n_1, ..., n_p].

Examples

A bipartite square matrix

By default, the PartialTranspose function performs the transposition on the second subsystem:

>> X = reshape(1:16,4,4)'
 
X =
 
     1     2     3     4
     5     6     7     8
     9    10    11    12
    13    14    15    16
 
>> PartialTranspose(X)
 
ans =
 
     1     5     3     7
     2     6     4     8
     9    13    11    15
    10    14    12    16

By specifying the SYS argument, you can perform the transposition on the first subsystem instead:

>> PartialTranspose(X,1)
 
ans =
 
     1     2     9    10
     5     6    13    14
     3     4    11    12
     7     8    15    16

Applying the transpose to both the first and second subsystems results in the standard transpose of X:

>> norm(PartialTranspose(X,[1,2]) - X.')
 
ans =
 
     0

Source code

Click on "expand" to the right to view the MATLAB source code for this function.

  1. %%  PARTIALTRANSPOSE    Computes the partial transpose of a matrix
  2. %   This function has one required argument:
  3. %     X: a matrix
  4. %
  5. %   XPT = PartialTranspose(X) is the partial transpose of the matrix X,
  6. %   where it is assumed that the number of rows and columns of X are both
  7. %   perfect squares and both subsystems have equal dimension. The transpose
  8. %   is applied to the second subsystem.
  9. %
  10. %   This function has two optional arguments:
  11. %     SYS (default 2)
  12. %     DIM (default has all subsystems of equal dimension)
  13. %
  14. %   XPT = PartialTranspose(X,SYS,DIM) gives the partial transpose of the
  15. %   matrix X, where the dimensions of the (possibly more than 2)
  16. %   subsystems are given by the vector DIM and the subsystems to take the
  17. %   partial transpose on are given by the scalar or vector SYS. If X is
  18. %   non-square, different row and column dimensions can be specified by
  19. %   putting the row dimensions in the first row of DIM and the column
  20. %   dimensions in the second row of DIM.
  21. %
  22. %   URL: http://www.qetlab.com/PartialTranspose
  23.  
  24. %   requires: opt_args.m, PermuteSystems.m
  25. %   author: Nathaniel Johnston (nathaniel@njohnston.ca)
  26. %   package: QETLAB
  27. %   last updated: December 28, 2012
  28.  
  29. function Xpt = PartialTranspose(X,varargin)
  30.  
  31. dX = size(X);
  32. sdX = round(sqrt(dX));
  33.  
  34. % set optional argument defaults: sys=2, dim=round(sqrt(length(X)))
  35. [sys,dim] = opt_args({ 2, [sdX(1) sdX(1);sdX(2) sdX(2)] },varargin{:});
  36.  
  37. num_sys = length(dim);
  38.  
  39. % allow the user to enter a single number for dim
  40. if(num_sys == 1)
  41.     dim = [dim,dX(1)/dim];
  42.     if abs(dim(2) - round(dim(2))) >= 2*dX(1)*eps
  43.         error('PartialTranspose:InvalidDim','If DIM is a scalar, X must be square and DIM must evenly divide length(X); please provide the DIM array containing the dimensions of the subsystems.');
  44.     end
  45.     dim(2) = round(dim(2));
  46.     num_sys = 2;
  47. end
  48.  
  49. % allow the user to enter a vector for dim if X is square
  50. if(min(size(dim)) == 1)
  51.     dim = dim(:).'; % force dim to be a row vector
  52.     dim = [dim;dim];
  53. end
  54.  
  55. % prepare the partial transposition
  56. prod_dimR = prod(dim(1,:));
  57. prod_dimC = prod(dim(2,:));
  58. sub_prodR = prod(dim(1,sys));
  59. sub_prodC = prod(dim(2,sys));
  60. sub_sys_vecR = prod_dimR*ones(1,sub_prodR)/sub_prodR;
  61. sub_sys_vecC = prod_dimC*ones(1,sub_prodC)/sub_prodC;
  62. perm = [sys,setdiff(1:num_sys,sys)];
  63.  
  64. Xpt = PermuteSystems(X,perm,dim); % permute the subsystems so that we just have to do the partial transpose on the first (potentially larger) subsystem
  65.  
  66. if(isnumeric(Xpt)) % if the input is a numeric matrix, perform the partial transpose operation the fastest way we know how
  67.     Xpt = cell2mat(mat2cell(Xpt, sub_sys_vecR, sub_sys_vecC).'); % partial transpose on first subsystem
  68. else % if the input is not numeric (such as a variable in a semidefinite program), do a slower method that avoids mat2cell (mat2cell doesn't like non-numeric arrays)
  69.     Xpt = reshape(permute(reshape(Xpt,[sub_sys_vecR(1),sub_prodR,sub_sys_vecC(1),sub_prodC]),[1,4,3,2]),[prod_dimR,prod_dimC]);
  70. end
  71.  
  72. % return the subsystems back to their original positions
  73. dim(:,sys) = dim([2,1],sys);
  74. dim = dim(:,perm);
  75. Xpt = PermuteSystems(Xpt,perm,dim,0,1);