Basic Operations

QSpace library provides an efficient way of manipulating the tensors, in a similar way as the standard numerical arrays of MATLAB.

First, one can generate the array of empty QSpace objects, similarly as zeros.

M = QSpace

M = (empty QSpace)
M = QSpace(3,1)
M = (empty QSpace)
...
M(3) = (empty QSpace)
size(M)
ans = 1x2
     3    1

And we can add and subtract QSpace objects.

Z

Z =
    Q: 3x [2 2] having 'A,SU2',    { , * }
 data: 2-D double (336 bytes)    3 x 3 => 4 x 4

    1. 1x1        | 1x1        [ -1 0 ; -1 0 ]               1.
    2. 1x1        | 2x2        [  0 1 ;  0 1 ]              -1.
    3. 1x1        | 1x1        [  1 0 ;  1 0 ]              -1.
I.E
ans =
    Q: 3x [2 2] having 'A,SU2',    { , * }
 data: 2-D double (336 bytes)    3 x 3 => 4 x 4

    1. 1x1        | 1x1        [ -1 0 ; -1 0 ]              2.
    2. 1x1        | 2x2        [  0 1 ;  0 1 ]              0.  {1.414}
    3. 1x1        | 1x1        [  1 0 ;  1 0 ]              2.
Z - I.E % minus
ans =
    Q: 3x [2 2] having 'A,SU2',    { , * }
 data: 2-D double (336 bytes)    3 x 3 => 4 x 4

    1. 1x1        | 1x1        [ -1 0 ; -1 0 ]              0.
    2. 1x1        | 2x2        [  0 1 ;  0 1 ]             -2.  {1.414}
    3. 1x1        | 1x1        [  1 0 ;  1 0 ]              0.

Multiply a number to QSpace object.

Z*3 % multiply number

ans =
    Q: 3x [2 2] having 'A,SU2',    { , * }
 data: 2-D double (336 bytes)    3 x 3 => 4 x 4

    1. 1x1        | 1x1        [ -1 0 ; -1 0 ]              3.
    2. 1x1        | 2x2        [  0 1 ;  0 1 ]             -3.  {1.414}
    3. 1x1        | 1x1        [  1 0 ;  1 0 ]              3.

Take complex conjugation.

F

F =
    Q: 2x [2 2 2] having 'A,SU2',   operator,   { , *, * }
 data: 3-D double (224 bytes)     2 x 2 x 1 => 3 x 3 x 2

    1. 1x1x1      | 1x2x2      [ -1 0 ; -1 0 ; -1 1 ]     -1.414.
    2. 1x1x1      | 2x1x2      [  0 1 ;  1 0 ; -1 1 ]     -1.414.
conj(F) % complex conjugation
ans =
    Q: 2x [2 2 2] having 'A,SU2',   operator,   { *, , }
 data: 3-D double (224 bytes)     2 x 2 x 1 => 3 x 3 x 2

    1. 1x1x1      | 1x2x2      [ -1 0 ; 0 1 ; -1 1 ]     -1.414.
    2. 1x1x1      | 2x1x2      [  0 1 ; 1 0 ; -1 1 ]     -1.414.
F1 = F;
F1.data{1} = 1i;
conj(F1)
ans =
    Q: 2x [2 2 2] having 'A,SU2',   operator,   { *, , }   complex
 data: 3-D double (232 bytes)     2 x 2 x 1 => 3 x 3 x 2

    1. 1x1x1      | 1x2x2      [ -1 0 ; 0 1 ; -1 1 ]         -1i
    2. 1x1x1      | 2x1x2      [  0 1 ; 1 0 ; -1 1 ]     -1.414

We see that the complex conjugation of QSpace object flips all the leg directions (inward vs. outward) and takes the complex conjugate to the reduced matrix elements (numerical arrays in .data{..}).

The permutation of the legs can be done by permute, which is the wrap-up routine for the binary MEX function permuteQS.

permute(F,[2 1 3]) % permute top and bottom legs 
ans =
    Q: 2x [2 2 2] having 'A,SU2',   operator,   { * , ,* }   
 data: 3-D double (224 bytes)     2 x 2 x 1 => 3 x 3 x 2

    1. 1x1x1      | 2x1x2      [ 0 1 ; -1 0 ; -1 1 ]     -1.414
    2. 1x1x1      | 1x2x2      [ 1 0 ;  0 1 ; -1 1 ]     -1.414
permute(F,'213') % equivalent expression to the above 
ans =
    Q: 2x [2 2 2] having 'A,SU2',   operator,   { * , ,* }   
 data: 3-D double (224 bytes)     2 x 2 x 1 => 3 x 3 x 2

    1. 1x1x1      | 2x1x2      [ 0 1 ; -1 0 ; -1 1 ]     -1.414
    2. 1x1x1      | 1x2x2      [ 1 0 ;  0 1 ; -1 1 ]     -1.414

Also the complex conjugation can be done together with permutation, by setting the option 'conj' in the syntax of permute. Then the Hermitian conjugate, which is the combination of the complex conjugate and transpose, to the particle annihilation operator F is obtained by:

permute(F, [2 1 3],'conj') % creation operator 
ans =
    Q: 2x [2 2 2] having 'A,SU2',   operator,   { , *, }   
 data: 3-D double (224 bytes)     2 x 2 x 1 => 3 x 3 x 2

    1. 1x1x1      | 2x1x2      [ 0 1 ; -1 0 ; -1 1 ]     -1.414
    2. 1x1x1      | 1x2x2      [ 1 0 ;  0 1 ; -1 1 ]     -1.414
permute(F,'213*') % equivalent expression to the above 
ans =
    Q: 2x [2 2 2] having 'A,SU2',   operator,   { , *, }   
 data: 3-D double (224 bytes)     2 x 2 x 1 => 3 x 3 x 2

    1. 1x1x1      | 2x1x2      [ 0 1 ; -1 0 ; -1 1 ]     -1.414
    2. 1x1x1      | 1x2x2      [ 1 0 ;  0 1 ; -1 1 ]     -1.414

That is, it becomes the particle creation operator. The tensor network diagram for this is:

Alt Text

The Hermitian conjugation for rank-2 operator is:

permute(I.E,[2 1],'conj') 
ans =
    Q: 3x [2 2] having 'A,SU2',     { , * }   
 data: 2-D double (336 bytes)       3 x 3 => 4 x 4

    1. 1x1      | 1x1         [ -1 0 ; -1 0 ]           -1.
    2. 1x1      | 2x2         [  0 1 ;  0 1 ]           -1.  {-1.414}
    3. 1x1      | 1x1         [  1 0 ;  1 0 ]           -1.

We see that the identity operator is Hermtian:

I.E - permute(I.E,[2 1],'conj') 
ans =
    Q: 3x [2 2] having 'A,SU2',     { , * }   
 data: 2-D double (336 bytes)       3 x 3 => 4 x 4

    1. 1x1      | 1x1         [ -1 0 ; -1 0 ]           0.
    2. 1x1      | 2x2         [  0 1 ;  0 1 ]           0.  {-1.414}
    3. 1x1      | 1x1         [  1 0 ;  1 0 ]           0.

Interestingly, the wrap-up function has the same name as the MATLAB bulit-in permute. Will it be a problem? Answer is no. MATLAB finds and executes a proper routine depending on the type of input variables. When it detects QSpace objects as input, it calls the routine QSpace/Class/@QSpace/permute which is the wrap-up of the MEX function QSpace/bin/permuteQS .

which permute(F) 
/Users/S.Lee/Documents/MATLAB/QSpace_v3/Class/@QSpace/permute.m   % QSpace method

On the other hand, if we give a numeric array, then MATLAB calls the built-in function.

M = [1,2;3,4];
which permute(F) 
built-in (/Applications/MATLAB_R220a.app/toolbox/matlab/elmat/@double/permute)   % double method
permute(M,[2 1]) % transpose 
ans = 2 x 2
     1       3
     2       4

To see the documentations for MEX functions (which are binary files stored in QSpace/bin), type in the MATLAB Command Window:

>>Name_of_MEX_function -?

For example, for permuteQS, type:

permuteQS   -? 
Usage: A = **permuteQS**(A, P [,'conj'])
     permute input QSpace using given permutation P.

     Optional trailing 'conj' also applies (complex) conjugation
     (note that this also affects real QSpaces in that qdir and
     itags are altered!).

     For convenience, P[,'conj'] may also be represented as
     single string, e.e. [2 1],'conj' is equivalent to '2,1;*'
     or '21*' where the convention on string notation
     follows that of contraction indices [ctrIdx]

     NB! [06/02/2019] the provided permutation can be shorter
     than the rank of the QSpace; in this case it only affects the
     leading range of indices, i.e., acts like an identity
     on the remainder of indices.

AW (C) Aug 2006 ; May 2010 ; Oct 2014