# SiteType and op, state, val functions

## Description

`ITensors.SiteType`

— TypeSiteType is a parameterized type which allows making Index tags into Julia types. Use cases include overloading functions such as `op`

, `siteinds`

, and `state`

which generate custom operators, Index arrays, and IndexVals associated with Index objects having a certain tag.

To make a SiteType type, you can use the string macro notation: `SiteType"MyTag"`

To make a SiteType value or object, you can use the notation: `SiteType("MyTag")`

There are currently a few built-in site types recognized by `ITensors.jl`

. The system is easily extensible by users. To add new operators to an existing site type, or to create new site types, you can follow the instructions here.

The current built-in site types are:

`SiteType"S=1/2"`

(or`SiteType"S=½"`

)`SiteType"S=1"`

`SiteType"Qubit"`

`SiteType"Qudit"`

`SiteType"Boson"`

`SiteType"Fermion"`

`SiteType"tJ"`

`SiteType"Electron"`

**Examples**

Tags on indices get turned into SiteTypes internally, and then we search for overloads of functions like `op`

and `siteind`

. For example:

```
julia> s = siteind("S=1/2")
(dim=2|id=862|"S=1/2,Site")
julia> @show op("Sz", s);
op(s, "Sz") = ITensor ord=2
Dim 1: (dim=2|id=862|"S=1/2,Site")'
Dim 2: (dim=2|id=862|"S=1/2,Site")
NDTensors.Dense{Float64,Array{Float64,1}}
2×2
0.5 0.0
0.0 -0.5
julia> @show op("Sx", s);
op(s, "Sx") = ITensor ord=2
Dim 1: (dim=2|id=862|"S=1/2,Site")'
Dim 2: (dim=2|id=862|"S=1/2,Site")
NDTensors.Dense{Float64,Array{Float64,1}}
2×2
0.0 0.5
0.5 0.0
julia> @show op("Sy", s);
op(s, "Sy") = ITensor ord=2
Dim 1: (dim=2|id=862|"S=1/2,Site")'
Dim 2: (dim=2|id=862|"S=1/2,Site")
NDTensors.Dense{Complex{Float64},Array{Complex{Float64},1}}
2×2
0.0 + 0.0im -0.0 - 0.5im
0.0 + 0.5im 0.0 + 0.0im
julia> s = siteind("Electron")
(dim=4|id=734|"Electron,Site")
julia> @show op("Nup", s);
op(s, "Nup") = ITensor ord=2
Dim 1: (dim=4|id=734|"Electron,Site")'
Dim 2: (dim=4|id=734|"Electron,Site")
NDTensors.Dense{Float64,Array{Float64,1}}
4×4
0.0 0.0 0.0 0.0
0.0 1.0 0.0 0.0
0.0 0.0 0.0 0.0
0.0 0.0 0.0 1.0
```

Many operators are available, for example:

`SiteType"S=1/2"`

:`"Sz"`

,`"Sx"`

,`"Sy"`

,`"S+"`

,`"S-"`

, ...`SiteType"Electron"`

:`"Nup"`

,`"Ndn"`

,`"Nupdn"`

,`"Ntot"`

,`"Cup"`

,`"Cdagup"`

,`"Cdn"`

,`"Cdagup"`

,`"Sz"`

,`"Sx"`

,`"Sy"`

,`"S+"`

,`"S-"`

, ...- ...

You can view the source code for the internal SiteType definitions and operators that are defined here.

## Methods

`ITensors.op`

— Function`op(opname::String, s::Index; kwargs...)`

Return an ITensor corresponding to the operator named `opname`

for the Index `s`

. The operator is constructed by calling an overload of either the `op`

or `op!`

methods which take a `SiteType`

argument that corresponds to one of the tags of the Index `s`

and an `OpName"opname"`

argument that corresponds to the input operator name.

Operator names can be combined using the `"*"`

symbol, for example `"S+*S-"`

or `"Sz*Sz*Sz"`

. The result is an ITensor made by forming each operator then contracting them together in a way corresponding to the usual operator product or matrix multiplication.

The `op`

system is used by the OpSum system to convert operator names into ITensors, and can be used directly such as for applying operators to MPS.

**Example**

```
s = Index(2, "Site,S=1/2")
Sz = op("Sz", s)
```

To see all of the operator names defined for the site types included with ITensor, please view the source code for each site type. Note that some site types such as "S=1/2" and "Qubit" are aliases for each other and share operator definitions.

`op(opname::String,sites::Vector{<:Index},n::Int; kwargs...)`

Return an ITensor corresponding to the operator named `opname`

for the n'th Index in the array `sites`

.

**Example**

```
s = siteinds("S=1/2", 4)
Sz2 = op("Sz", s, 2)
```

`ITensors.state`

— Function`state(s::Index, name::String; kwargs...)`

Return an ITensor corresponding to the state named `name`

for the Index `s`

. The returned ITensor will have `s`

as its only index.

The terminology here is based on the idea of a single-site state or wavefunction in physics.

The `state`

function is implemented for various Index tags by overloading either the `state`

or `state!`

methods which take a `SiteType`

argument corresponding to one of the tags of the Index `s`

and an `StateName"name"`

argument that corresponds to the input state name.

The `state`

system is used by the MPS type to construct product-state MPS and for other purposes.

**Example**

```
s = Index(2, "Site,S=1/2")
sup = state(s,"Up")
sdn = state(s,"Dn")
sxp = state(s,"X+")
sxm = state(s,"X-")
```

`ITensors.val`

— Function`val(q::QN,name)`

Get the value within the QN q corresponding to the string `name`

`val(s::Index, name::String)`

Return an integer corresponding to the `name`

of a certain value the Index `s`

can take. In other words, the `val`

function maps strings to specific integer values within the range `1:dim(s)`

.

The `val`

function is implemented for various Index tags by overloading methods named `val`

which take a `SiteType`

argument corresponding to one of the tags of the Index `s`

and an `ValName"name"`

argument that corresponds to the input name.

**Example**

```
s = Index(2, "Site,S=1/2")
val(s,"Up") == 1
val(s,"Dn") == 2
s = Index(2, "Site,Fermion")
val(s,"Emp") == 1
val(s,"Occ") == 2
```

`ITensors.space`

— Function```
space(::SiteType"Qubit";
conserve_qns = false,
conserve_parity = conserve_qns,
conserve_number = false,
qnname_parity = "Parity",
qnname_number = "Number")
```

Create the Hilbert space for a site of type "Qubit".

Optionally specify the conserved symmetries and their quantum number labels.

```
space(::SiteType"S=1/2";
conserve_qns = false,
conserve_sz = conserve_qns,
conserve_szparity = false,
qnname_sz = "Sz",
qnname_szparity = "SzParity")
```

Create the Hilbert space for a site of type "S=1/2".

Optionally specify the conserved symmetries and their quantum number labels.

```
space(::SiteType"S=1";
conserve_qns = false,
conserve_sz = conserve_qns,
qnname_sz = "Sz")
```

Create the Hilbert space for a site of type "S=1".

Optionally specify the conserved symmetries and their quantum number labels.

```
space(::SiteType"Fermion";
conserve_qns=false,
conserve_nf=conserve_qns,
conserve_nfparity=conserve_qns,
qnname_nf = "Nf",
qnname_nfparity = "NfParity",
qnname_sz = "Sz",
conserve_sz = false)
```

Create the Hilbert space for a site of type "Fermion".

Optionally specify the conserved symmetries and their quantum number labels.

```
space(::SiteType"Electron";
conserve_qns = false,
conserve_sz = conserve_qns,
conserve_nf = conserve_qns,
conserve_nfparity = conserve_qns,
qnname_sz = "Sz",
qnname_nf = "Nf",
qnname_nfparity = "NfParity")
```

Create the Hilbert space for a site of type "Electron".

Optionally specify the conserved symmetries and their quantum number labels.

```
space(::SiteType"tJ";
conserve_qns = false,
conserve_sz = conserve_qns,
conserve_nf = conserve_qns,
conserve_nfparity = conserve_qns,
qnname_sz = "Sz",
qnname_nf = "Nf",
qnname_nfparity = "NfParity")
```

Create the Hilbert space for a site of type "tJ".

Optionally specify the conserved symmetries and their quantum number labels.

```
space(::SiteType"Qudit";
dim = 2,
conserve_qns = false,
conserve_number = false,
qnname_number = "Number")
```

Create the Hilbert space for a site of type "Qudit".

Optionally specify the conserved symmetries and their quantum number labels.

```
space(::SiteType"Boson";
dim = 2,
conserve_qns = false,
conserve_number = false,
qnname_number = "Number")
```

Create the Hilbert space for a site of type "Boson".

Optionally specify the conserved symmetries and their quantum number labels.