Working with Tensors I

Here I am going to begin a review of how to manipulate tensors in Mathematica, and introduce some routines for making them easier to work with.  The routines were just quickly thrown together for this course, and broadly mimic the implementation of tensors in ITensor -- one of the popular tensor manipulation packages for C++.  For production code you would want to introduce various error checking, etc.    In a later part of the course we will add “quantum numbers” which will be important for efficiency of DMRG.

Note :  Mathematica has fundamental design choices in how it deals with Arrays, which means that you cannot make a true production-level DMRG code with Mathematica.  This is just a learning exercise.

Basics

How Mathematica Stores Tensors

Suppose we want to encode the tensor

M=(({{a↑, 0, 0, 0}, {0, b↑, c↓, 0}, {0, 0, 0, d↓}}))

This is a rank 3 tensor.  Lets call the left index α (which has 3 values -- this is indices the rows), the right index β (which has 4 values -- corresponding to the column) and the spin index σ (2 values).  I find the easiest way to wrap my head around things is to use a Sparse Array.  We will order our spin basis as (↑,↓).  We will order the indices {α ,β,σ }

M=SparseArray[{{1,1,1}->a,{2,2,1}->b,{2,3,2}->c,{3,4,2}->d},{3,4,2}]

A lightweight “NamedTensor”

Rather than having to remember the order of indices, it is easier if we store the names together with the tensor

Mb={"tensor"->M,"names"->{"α","β","σ"}}

We can retrieve the tensor with

"tensor"/.Mb

"names"/.Mb

Visualizing tensors

We can visualize the tensor with

MatrixForm[M]

Or we can slice -- to show the up-spin component of M

MatrixForm[M[[All,All,1]]]

or we can get the sparse description with

ArrayRules[M]

Re-ordering indices

We also need to be able to change the ordering of the indices.  The command “Transpose” does this.  The syntax is that Transpose[M,{n1,n2,...}] gives M where the kth level in the original ordering is now the nk’th.  So if we want to order the indices {“α”, “σ” , “β”} we want ordering {1,3,2}.  Don’t spend too long trying to parse this -- we are going to write a helper routine which does the thinking for you.

M2=Transpose[M,{1,3,2}]

We can verify that we got it right by looking at the “dimensions” label of the Sparse Array

Now, slicing out the up - spin component of M would be

MatrixForm[M2[[All,1,All]]]

I find the notation of Transpose to be confusing, so here is a helper function

NamedTranspose[mat_,orig_,final_]:=Module[{ord=Flatten[Position[final,#]&/@orig]},Transpose[mat,ord]]

M3=NamedTranspose[M,{"α","β","σ"},{"α","σ","β"}]

M3==M2

We can encapsulate this as

ReOrder[tensordescription_List,finalnames_]:=Module[{
tensor="tensor"/.tensordescription, (* Extract Tensor *)
names="names"/.tensordescription, (* Extract names of indices *)
newtensor (* Declare local variables *)
},
(* Calculate new Tensor *)
newtensor=NamedTranspose[tensor,names,finalnames];
(* Assemble into rules *)
{"tensor"->newtensor,"names"->finalnames}
]

Mb

Mc=ReOrder[Mb,{"σ","α","β"}]

MatrixForm["tensor"/.Mc]

Exercise

Last day in class we discussed rank-3 tensors of the form

Make this tensor as a “named tensor” object

Visualize it using MatrixForm

Order the indices so that the two bond indices come first, then the spin index -- then visualize again

Order the indices so that the site index comes first, then the bond index -- then visualize again