PermuteSystems

From QETLAB
Jump to: navigation, search
PermuteSystems
Permutes subsystems within a state or operator

Other toolboxes required none
Related functions PermutationOperator
Swap
SwapOperator
Function category Permutations and symmetry of subsystems

PermuteSystems is a function that allows the user to permute the order of the subsystems underlying a quantum state or operator that is defined on the tensor product of 2 or more subsystems. It works with full and sparse numeric matrices as well as symbolic matrices.

Syntax

  • PX = PermuteSystems(X,PERM)
  • PX = PermuteSystems(X,PERM,DIM)
  • PX = PermuteSystems(X,PERM,DIM,ROW_ONLY)
  • PX = PermuteSystems(X,PERM,DIM,ROW_ONLY,INV_PERM)

Argument Descriptions

  • X: a vector (e.g., a pure quantum state) or a matrix to have its subsystems permuted
  • PERM: a permutation vector (i.e., a permutation of the vector 1:n)
  • 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 two ways:
    • 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].
  • ROW_ONLY (optional, default 0): If set equal to 1, only the rows of X are permuted (this is equivalent to multiplying X on the left by PermutationOperator(DIM,PERM)). If equal to 0, both the rows and columns of X are permuted (this is equivalent to multiplying X on both the left and right by the permutation operator).
  • INV_PERM (optional, default 0): If equal to 0, this argument has no effect. If equal to 1, the subsystems are permuted according to the inverse of PERM rather than PERM itself.

Examples

All subsystems of equal dimension

In cases when all subsystems have the same dimension, most arguments can be omitted. Let's start with a matrix $X \in M_2 \otimes M_2$:

>> X = [1 2 3 4;5 6 7 8;9 10 11 12;13 14 15 16]
 
X =
 
     1     2     3     4
     5     6     7     8
     9    10    11    12
    13    14    15    16

If we want to permute the two subsystems, we can call PermuteSystems with the permutation vector PERM = [2,1] (though if your needs are as simple as this, you may be better off using the Swap function):

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

Similarly, the following code acts on a matrix $X \in M_A \otimes M_B \otimes M_C$ (where each subsystem has dimension 2) and outputs a matrix representation in the standard basis of $M_B \otimes M_C \otimes M_A$:

>> X = reshape(1:64,8,8)'
 
X =
 
     1     2     3     4     5     6     7     8
     9    10    11    12    13    14    15    16
    17    18    19    20    21    22    23    24
    25    26    27    28    29    30    31    32
    33    34    35    36    37    38    39    40
    41    42    43    44    45    46    47    48
    49    50    51    52    53    54    55    56
    57    58    59    60    61    62    63    64
 
>> PermuteSystems(X,[2,3,1])
 
ans =
 
     1     5     2     6     3     7     4     8
    33    37    34    38    35    39    36    40
     9    13    10    14    11    15    12    16
    41    45    42    46    43    47    44    48
    17    21    18    22    19    23    20    24
    49    53    50    54    51    55    52    56
    25    29    26    30    27    31    28    32
    57    61    58    62    59    63    60    64

Source code

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

  1. %%  PERMUTESYSTEMS    Permutes subsystems within a state or operator
  2. %   This function has two required arguments:
  3. %     X: the vector or matrix
  4. %     PERM: a permutation vector
  5. %
  6. %   PX = PermuteSystems(X,PERM) permutes the order of the subsystems
  7. %   of the vector or matrix X according to the permutation vector PERM,
  8. %   where each subsystem is assumed to have equal dimension
  9. %
  10. %   This function has three optional arguments:
  11. %     DIM (default has all subsystems of equal dimension)
  12. %     ROW_ONLY (default 0)
  13. %     INV_PERM (default 0)
  14. %   
  15. %   PX = PermuteSystems(X,PERM,DIM,ROW_ONLY,INV_PERM) permutes the order of
  16. %   the subsystems of the vector or matrix X according to the permutation
  17. %   vector PERM, where the dimensions of the subsystems are given by the
  18. %   vector DIM. If X is non-square and not a vector, different row and
  19. %   column dimensions can be specified by putting the row dimensions in the
  20. %   first row of DIM and the column dimensions in the second row of DIM.
  21. %   If ROW_ONLY is set to 1, then only the rows of X are permuted, but not
  22. %   the columns -- this is equivalent tomultiplying X on the left by the
  23. %   corresponding permutation operator, but not on the right. If ROW_ONLY
  24. %   is set to 1 then DIM only needs to contain the row dimensions of the
  25. %   subsystems, even if X is not square. If INV_PERM equals 1 then the
  26. %   inverse permutation of PERM is applied instead of PERM itself.
  27. %
  28. %   URL: http://www.qetlab.com/PermuteSystems
  29.  
  30. %   requires: opt_args.m
  31. %   author: Nathaniel Johnston (nathaniel@njohnston.ca)
  32. %   package: QETLAB
  33. %   last updated: November 6, 2014
  34.  
  35. function PX = PermuteSystems(X,perm,varargin)
  36.  
  37. dX = size(X);
  38. is_vec = (min(dX) == 1);
  39. num_sys = length(perm);
  40. if(is_vec)
  41.     vec_orien = 3 - find(dX == 1, 1); % 1 if column vector, 2 if row vector
  42. end
  43.  
  44. % set optional argument defaults: dim=round(lX^(1/num_sys)), row_only=0, inv_perm=0
  45. [dim,row_only,inv_perm] = opt_args({ [round(dX(1)^(1/num_sys))*ones(1,num_sys); round(dX(2)^(1/num_sys))*ones(1,num_sys)], 0, 0 },varargin{:});
  46.  
  47. % allow the user to enter a vector for dim if X is square
  48. if(min(size(dim)) == 1)
  49.     dim_tmp = dim(:)'; % force dim to be a row vector
  50.     if(is_vec)
  51.         dim = ones(2,length(dim));
  52.         dim(vec_orien,:) = dim_tmp;
  53.     else
  54.         dim = [dim_tmp;dim_tmp];
  55.     end
  56. end
  57.  
  58. prod_dimR = prod(dim(1,:));
  59. prod_dimC = prod(dim(2,:));
  60.  
  61. % Do some basic input checking.
  62. if length(perm) ~= num_sys
  63.     error('PermuteSystems:InvalidPerm','length(PERM) must equal length(DIM).')
  64. elseif ~all(sort(perm) == 1:num_sys)
  65.     error('PermuteSystems:InvalidPerm','PERM must be a permutation vector.')
  66. elseif(dX(1) ~= prod_dimR || (~row_only && dX(2) ~= prod_dimC))
  67.     error('PermuteSystems:InvalidDim','The dimensions specified in DIM do not agree with the size of X.')
  68. end
  69.  
  70. % Permuting systems for pure states is easy enough, so just make the vector
  71. % full and then perform the permutation (new-ish versions of MATLAB don't
  72. % like sparse multidimensional arrays).
  73. if(is_vec)
  74.     if(inv_perm)
  75.         PX = reshape(ipermute(reshape(full(X),dim(vec_orien,end:-1:1)),num_sys+1-perm(end:-1:1)),dX);
  76.     else
  77.         PX = reshape(permute(reshape(full(X),dim(vec_orien,end:-1:1)),num_sys+1-perm(end:-1:1)),dX);
  78.     end
  79.  
  80.     % Preserve the sparsity of X.
  81.     if(issparse(X))
  82.         PX = sparse(PX);
  83.     end
  84.     return
  85. end
  86.  
  87. % If X is not a pure state, it's slightly trickier... do *not* just use the
  88. % same pure state trick with repeated indices though, since that has an
  89. % intermediate step of making the matrix a multidimensional array, which
  90. % you can't do with sparse matrices in new-ish version of MATLAB. The trick
  91. % used here reduces the problem to the pure state version of the problem in
  92. % another way that plays nicely with both full and sparse matrices
  93. row_perm = PermuteSystems(1:dX(1),perm,dim(1,:),0,inv_perm);
  94. PX = X(row_perm,:);
  95. if ~row_only
  96.     col_perm = PermuteSystems(1:dX(2),perm,dim(2,:),0,inv_perm);
  97.     PX = PX(:,col_perm);
  98. end