### Install and Use pre-commit for Formatting Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/faq/Development.md Install pre-commit and set it up to automatically format code before each commit. This is an alternative to manual formatting. ```shell pip install pre-commit ``` ```shell pre-commit install ``` -------------------------------- ### Full Example: ITensor SVD Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/examples/ITensor.md A complete example demonstrating the SVD of an ITensor, including index definition, ITensor creation, SVD computation, and verification of reconstruction. ```julia i = Index(3,"i") j = Index(4,"j") k = Index(5,"k") T = random_itensor(i,j,k) U,S,V = svd(T,(i,k)) @show norm(U*S*V-T) ``` -------------------------------- ### Full Example: Truncated ITensor SVD Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/examples/ITensor.md A comprehensive example of truncated SVD, including index setup, ITensor generation, SVD with a cutoff, and calculation of both absolute and squared relative errors. ```julia i = Index(10,"i"); j = Index(40,"j"); k = Index(20,"k"); T = random_itensor(i,j,k) U,S,V = svd(T,(i,k),cutoff=1E-2) @show norm(U*S*V-T) @show (norm(U*S*V - T)/norm(T))^2 ``` -------------------------------- ### Install ITensors.jl using Pkg API Source: https://github.com/itensor/itensors.jl/blob/main/README.md Install the ITensors package programmatically using the Pkg API. ```julia julia> import Pkg; Pkg.add("ITensors") ``` -------------------------------- ### Run CTMRG Test Example Source: https://github.com/itensor/itensors.jl/blob/main/examples/ctmrg/anisotropic/README.md Execute the test example for contracting the 2D classical Ising model partition function using the CTMRG code. Ensure you have the main.jl file in your current directory. ```julia include("main.jl"); main() ``` -------------------------------- ### Install ITensors.jl using Pkg REPL Source: https://github.com/itensor/itensors.jl/blob/main/README.md Install the ITensors package using the Julia package manager's REPL mode. ```julia julia> ] pkg> add ITensors ``` -------------------------------- ### Install ITensor Julia Kernel for Jupyter Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/getting_started/RunningCodes.md Run this command in the Julia REPL to install a new Jupyter kernel that uses the ITensor sysimage. Ensure the sysimage path is correct. ```julia using IJulia installkernel("julia_ITensors","--sysimage=~/.julia/sysimages/sys_itensors.so") ``` -------------------------------- ### Install Julia on a Linux Cluster Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/getting_started/Installing.md Commands to download, uncompress, and link a Julia binary on a Linux-based cluster. Ensure you use a Julia version compatible with ITensors.jl (1.6 or newer). ```bash $ cd $ mkdir -p bin $ wget https://julialang-s3.julialang.org/bin/linux/x64/1.7/julia-1.7.2-linux-x86_64.tar.gz $ tar xvzf julia-1.7.2-linux-x86_64.tar.gz $ ln -s julia-1.7.2/bin/julia bin/julia ``` -------------------------------- ### S=1/2 site type QN convention for conserved Sz Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/UpgradeGuide_0.1_to_0.2.md This example shows the previous QN convention for the 'S=1/2' site type, which conserved Sz (Quantum Number Sz from +1 to -1). ```julia julia> s = siteinds("S=1/2", 4; conserve_sz=true) 4-element Vector{Index{Vector{Pair{QN, Int64}}}}: (dim=2|id=364|"S=1/2,Site,n=1") 1: QN("Sz",1) => 1 2: QN("Sz",-1) => 1 (dim=2|id=823|"S=1/2,Site,n=2") 1: QN("Sz",1) => 1 2: QN("Sz",-1) => 1 (dim=2|id=295|"S=1/2,Site,n=3") 1: QN("Sz",1) => 1 2: QN("Sz",-1) => 1 (dim=2|id=810|"S=1/2,Site,n=4") 1: QN("Sz",1) => 1 2: QN("Sz",-1) => 1 ``` -------------------------------- ### Get Available CPU Threads Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/Multithreading.md Obtain the number of CPU threads available on your system. ```julia julia> Sys.CPU_THREADS 6 ``` -------------------------------- ### Start Julia with Multiple Threads Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/Multithreading.md Launch Julia with a specified number of threads using the -t flag. This enables Strided.jl's multithreading by default. ```bash $ julia -t 4 julia> Threads.nthreads() 4 julia> using Strided julia> Strided.get_num_threads() 4 ``` -------------------------------- ### Verify ITensor SVD Reconstruction Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/examples/ITensor.md After performing an SVD, the product of the resulting U, S, and V ITensors should reconstruct the original ITensor T. This example shows how to verify the reconstruction using the norm. ```julia @show norm(U*S*V - T) ``` -------------------------------- ### Shell Alias for Julia with System Image Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/getting_started/RunningCodes.md Create a shell alias to conveniently launch Julia with a pre-loaded ITensor system image and the ITensor library. This simplifies starting interactive sessions or running scripts. ```shell alias julia_itensors="julia --sysimage ~/.julia/sysimages/sys_itensors.so -e \"using ITensors\" -i " ``` -------------------------------- ### Get single-site ITensor states with state Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/UpgradeGuide_0.1_to_0.2.md The `state` function now returns single-index ITensors representing specific single-site states. This allows for more general state definitions. ```julia julia> @show state(s[1], "Up"); state(s[1], "Up") = ITensor ord=1 Dim 1: (dim=2|id=597|"S=1/2,Site,n=1") ITensors.NDTensors.Dense{Float64, Vector{Float64}} 2-element 1.0 0.0 ``` ```julia julia> @show state(s[1], "Dn"); state(s[1], "Dn") = ITensor ord=1 Dim 1: (dim=2|id=597|"S=1/2,Site,n=1") ITensors.NDTensors.Dense{Float64, Vector{Float64}} 2-element 0.0 1.0 ``` ```julia julia> @show state(s[1], "X+"); state(s[1], "X+") = ITensor ord=1 Dim 1: (dim=2|id=597|"S=1/2,Site,n=1") ITensors.NDTensors.Dense{Float64, Vector{Float64}} 2-element 0.7071067811865475 0.7071067811865475 ``` ```julia julia> @show state(s[1], "X-"); state(s[1], "X-") = ITensor ord=1 Dim 1: (dim=2|id=597|"S=1/2,Site,n=1") ITensors.NDTensors.Dense{Float64, Vector{Float64}} 2-element 0.7071067811865475 -0.7071067811865475 ``` -------------------------------- ### Generic Function for IndexSet Type Parameter Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/UpgradeGuide_0.1_to_0.2.md This example shows the old way of defining a function that relied on the type parameter N of IndexSet. This approach is no longer valid. ```julia function myorder2(is::IndexSet{N}) where {N} return N^2 end ``` -------------------------------- ### Compare Serial and Threaded Block Sparse Contractions Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/Multithreading.md This example benchmarks a sparse tensor contraction using both serial and threaded block sparse operations to demonstrate performance differences. It disables BLAS and Strided threading to isolate the effect of block sparse threading. ```julia using BenchmarkTools using ITensors using LinearAlgebra using Strided function main(; d = 20, order = 4) BLAS.set_num_threads(1) Strided.set_num_threads(1) println("#################################################") println("# order = ", order) println("# d = ", d) println("#################################################") println() i(n) = Index(QN(0) => d, QN(1) => d; tags = "i$n") is = ntuple(i, order ÷ 2) A = random_itensor(is'..., dag(is)...) B = random_itensor(is'..., dag(is)...) ITensors.enable_threaded_blocksparse(false) println("Serial contract:") @disable_warn_order begin C_contract = @btime $A' * $B samples = 5 end println() println("Threaded contract:") @disable_warn_order begin ITensors.enable_threaded_blocksparse(true) C_threaded_contract = @btime $A' * $B samples = 5 ITensors.enable_threaded_blocksparse(false) end println() @show C_contract ≈ C_threaded_contract return nothing end main(d = 20, order = 4) ``` -------------------------------- ### Set BLAS Threads via Environment Variables Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/Multithreading.md Control the number of BLAS threads by setting environment variables before starting Julia. This is useful for optimizing dense tensor operations. ```bash $ MKL_NUM_THREADS=4 julia # Set the number of MKL threads to 4 $ OPENBLAS_NUM_THREADS=4 julia # Set the number of OpenBLAS threads to 4 $ OMP_NUM_THREADS=4 julia # Set the number of OpenMP threads to 4, which will be used by MKL or OpenBLAS if they are not specifically set ``` -------------------------------- ### Add ITensors Package in Julia REPL Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/getting_started/Installing.md Steps to add the ITensors package using Julia's package manager within an interactive Julia session. It is recommended to compile the library after installation. ```julia julia> ] pkg> add ITensors julia> using ITensors; ITensors.compile() ``` -------------------------------- ### Element Access Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/ITensorType.md Functions for getting and setting elements within an ITensor. ```APIDOC ## Getting and setting elements ### Description Functions for accessing and modifying elements of an ITensor. ### Methods - `getindex(::ITensor, ::Any...) - `setindex!(::ITensor, ::Number, ::Int...) ``` -------------------------------- ### Write ITensor to HDF5 File Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/examples/ITensor.md Save an ITensor to an HDF5 file for persistent storage. Ensure the HDF5 package is installed. The string argument to `write` can be any identifier for the tensor within the file. ```julia using ITensors, HDF5 i = Index(2) T = random_itensor(i) f = h5open("myfile.h5","w") do f write(f,"T",T) end ``` -------------------------------- ### Running Julia with a Compiled System Image Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/getting_started/RunningCodes.md Launch Julia using a pre-compiled system image to significantly reduce startup time. This is useful for both interactive sessions and script execution. ```shell $ julia --sysimage ~/.julia/sysimages/sys_itensors.so ``` -------------------------------- ### QN Type and Constructors Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/QN.md This section covers the definition of the QN type and its various constructors, allowing for flexible initialization. ```APIDOC ## QN Type ### Description Represents a quantum number. ### Constructors - `QN(qvs...)`: Constructs a QN from a list of quantum number values. - `QN(name, val::Int, modulus::Int=1)`: Constructs a QN with a specific name, value, and optional modulus. - `QN(val::Int, modulus::Int=1)`: Constructs a QN with a value and optional modulus. ``` -------------------------------- ### ITensor Construction, Element Setting, Contraction, and Addition Source: https://github.com/itensor/itensors.jl/blob/main/README.md Demonstrates the basic usage of ITensors.jl, including constructing Index and ITensor objects, setting elements, contracting tensors, and adding ITensors. Requires ITensors package to be imported. ```julia using ITensors let i = Index(3) j = Index(5) k = Index(2) l = Index(7) A = ITensor(i,j,k) B = ITensor(j,l) # Set elements of A A[i=>1,j=>1,k=>1] = 11.1 A[i=>2,j=>1,k=>2] = -21.2 A[k=>1,i=>3,j=>1] = 31.1 # can provide Index values in any order # ... # Contract over shared index j C = A * B @show hasinds(C,i,k,l) # = true D = random_itensor(k,j,i) # ITensor with random elements # Add two ITensors # must have same set of indices # but can be in any order R = A + D nothing end ``` -------------------------------- ### Example of Debug Check Triggering an Error Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/getting_started/DebugChecks.md When debug checks are enabled, ITensor will throw an error if indices are not unique, preventing undefined behavior in tensor operations. This example shows an error when creating an ITensor with duplicate indices. ```julia julia> using ITensors julia> i = Index(2) (dim=2|id=913) julia> A = random_itensor(i', i) ITensor ord=2 (dim=2|id=913)' (dim=2|id=913) NDTensors.Dense{Float64, Vector{Float64}} julia> noprime(A) ITensor ord=2 (dim=2|id=913) (dim=2|id=913) NDTensors.Dense{Float64, Vector{Float64}} julia> ITensors.enable_debug_checks() using_debug_checks (generic function with 1 method) julia> noprime(A) ERROR: Trying to create ITensors with collection of indices ((dim=2|id=913), (dim=2|id=913)). Indices must be unique. Stacktrace: [1] error(s::String) @ Base ./error.jl:33 [2] macro expansion @ ~/.julia/packages/ITensors/cu9Bo/src/itensor.jl:85 [inlined] [3] macro expansion @ ~/.julia/packages/ITensors/cu9Bo/src/global_variables.jl:177 [inlined] [4] ITensor @ ~/.julia/packages/ITensors/cu9Bo/src/itensor.jl:82 [inlined] [5] #itensor#123 @ ~/.julia/packages/ITensors/cu9Bo/src/itensor.jl:123 [inlined] [6] itensor(args::NDTensors.DenseTensor{Float64, 2, Tuple{Index{Int64}, Index{Int64}}, NDTensors.Dense{Float64, Vector{Float64}}}) @ ITensors ~/.julia/packages/ITensors/cu9Bo/src/itensor.jl:123 [7] noprime(::ITensor; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}) @ ITensors ~/.julia/packages/ITensors/cu9Bo/src/itensor.jl:1211 [8] noprime(::ITensor) @ ITensors ~/.julia/packages/ITensors/cu9Bo/src/itensor.jl:1211 [9] top-level scope @ REPL[7]:1 ``` -------------------------------- ### Run ITensor Unit Tests Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/faq/Development.md Navigate to the test/ folder and execute this command to run all unit tests. Individual test scripts can be included in a Julia REPL session. ```julia include("runtests.jl") ``` ```julia include("itensor.jl") ``` -------------------------------- ### Get Element from ITensor Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/examples/ITensor.md Retrieve a specific element from an ITensor using the same index-value pair notation used for setting elements. ```julia el = T[j=>1,i=>2,k=>3] println("The (i,j,k) = (2,1,3) element of T is ",el) ``` -------------------------------- ### QN Constructor Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/QN.md Constructs a QN object. Use QN(qvs...) for multiple quantum numbers, QN(name, val, modulus) for a named quantum number with a specific value and modulus, and QN(val, modulus) for an unnamed quantum number. ```julia QN(qvs...) ``` ```julia QN(name,val::Int,modulus::Int=1) ``` ```julia QN(val::Int,modulus::Int=1) ``` -------------------------------- ### Get and Set ITensor Elements Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/ITensorType.md Accesses or modifies elements of an ITensor using indices. Note that `setindex!` modifies the tensor in place. ```julia getindex(::ITensor, ::Any...) ``` ```julia setindex!(::ITensor, ::Number, ::Int...) ``` -------------------------------- ### Read and Write ITensors to HDF5 Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/HDF5FileFormats.md Demonstrates how to read and write ITensors to HDF5 files using the HDF5.jl library. Compression parameters can also be passed. ```julia using ITensors, HDF5 i = Index(2) T = random_itensor(i) f = h5open("myfile.h5","w") do f write(f,"T",T) end T2 = h5open("myfile.h5","r") do f read(f,"T",ITensor) end T == T2 ``` -------------------------------- ### Get ITensor Indices using inds() Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/UpgradeGuide_0.1_to_0.2.md The `inds` function now returns a Tuple of Indices instead of an IndexSet. This change affects how you access the indices of an ITensor. ```julia julia> inds(A) # Previously returned IndexSet, now returns Tuple ((dim=2|id=320)', (dim=2|id=320)) ``` -------------------------------- ### Index Constructors Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/IndexType.md Constructors for creating Index objects. ```APIDOC ## Constructors ### `Index(::Int)` Creates an Index with a specified integer ID. ### `Index(::Int, ::Union{AbstractString, TagSet})` Creates an Index with a specified integer ID and tags. ### `Index(::Pair{QN, Int}...` Creates an Index from a variable number of QN-integer pairs. ### `Index(::Vector{Pair{QN, Int}})` Creates an Index from a vector of QN-integer pairs. ### `Index(::Vector{Pair{QN, Int}}, ::Union{AbstractString, TagSet})` Creates an Index from a vector of QN-integer pairs and tags. ``` -------------------------------- ### Format Code with JuliaFormatter Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/faq/Development.md Run this command in the project directory to ensure code formatting compliance before submitting changes. ```julia using JuliaFormatter; format(".") ``` -------------------------------- ### GPU Tensor Operations with Metal Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/RunningOnGPUs.md Demonstrates moving tensors to an Apple GPU using Metal.jl and performing tensor operations. ```julia using Metal # This will trigger the loading of `NDTensorsMetalExt` in the background # Move tensors to Apple GPU Amtl = mtl(A) Bmtl = mtl(B) # Perform tensor operations on Apple GPU Amtl * Bmtl ``` -------------------------------- ### QN Related Functions Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/QN.md This section covers related functions for QN, such as creating a zero QN. ```APIDOC ## Related Functions ### Description Functions related to QN operations. ### Functions - `zero(q::QN)`: Returns the zero element for the QN type. ``` -------------------------------- ### QN BlockSparse Constructors Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/ITensorType.md Constructs QN BlockSparse ITensors. Use when dealing with quantum numbers and sparsity. ```julia ITensor(::Type{<:Number}, ::QN, ::ITensors.QNIndices) ``` ```julia ITensor(::ITensors.AliasStyle, ::Type{<:Number}, ::Array{<:Number}, ::ITensors.QNIndices; tol = 0) ``` ```julia ITensor(::Type{<:Number}, ::UndefInitializer, ::QN, ::ITensors.Indices) ``` -------------------------------- ### Compiling ITensor System Image Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/getting_started/RunningCodes.md Compile ITensors.jl, ITensorMPS.jl, and PackageCompiler.jl to create a system image for faster Julia startup times. This process creates a 'sys_itensors.so' file. ```julia julia> using ITensors, ITensorMPS, PackageCompiler julia> ITensors.compile() ``` -------------------------------- ### QN Properties Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/QN.md This section describes how to access the value and modulus of a QN for a given name. ```APIDOC ## QN Properties ### Description Accessors for QN properties. ### Properties - `val(q::QN, name)`: Returns the value of the QN associated with the given name. - `modulus(q::QN, name)`: Returns the modulus of the QN associated with the given name. ``` -------------------------------- ### Tensor Index Properties with ITensors.jl Source: https://github.com/itensor/itensors.jl/blob/main/README.md Demonstrates the creation and properties of ITensor Index objects, including dimension, unique ID, copying, tags, and prime levels. Shows how equality comparison works with these properties. ```julia using ITensors let i = Index(3) @show dim(i) @show id(i) ci = copy(i) @show ci == i j = Index(5,"j") @show j == i s = Index(2,"n=1,Site") @show hastags(s,"Site") @show hastags(s,"n=1") i1 = prime(i) @show i1 == i nothing end ``` -------------------------------- ### Including a Julia Script in REPL Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/getting_started/RunningCodes.md Load and run a Julia script file within an active Julia REPL session using the 'include' command. Ensure you are in the same directory as the script or provide the full path. ```julia julia> include("code.jl") ``` -------------------------------- ### Basic ITensor Code Template with let block Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/getting_started/RunningCodes.md Use a 'let...end' block for your ITensor code to avoid potential issues with Julia's global scope. This is a standard template for organizing your ITensor computations. ```julia using ITensors let # ... your own code goes here ... # For example: i = Index(2,"i") j = Index(3,"j") T = random_itensor(i,j) @show T end ``` -------------------------------- ### Running a Julia Script from Command Line Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/getting_started/RunningCodes.md Execute a Julia script file (e.g., 'code.jl') directly from the command line. This method is suitable for longer jobs or execution on clusters. ```shell $ julia code.jl ``` -------------------------------- ### Threaded vs. Serial Contract Performance Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/Multithreading.md Compares the execution time and memory allocations for serial and threaded matrix contraction. Demonstrates the performance benefits of threading for computational tasks. ```text Threads.nthreads() = 5 Sys.CPU_THREADS = 6 BLAS.get_num_threads() = 1 Strided.get_num_threads() = 1 Serial contract: 21.558 ms (131 allocations: 7.34 MiB) Threaded contract: 5.934 ms (446 allocations: 7.37 MiB) C_contract ≈ C_threaded_contract = true ``` -------------------------------- ### GPU Tensor Operations with CUDA Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/RunningOnGPUs.md Demonstrates moving tensors to an NVIDIA GPU using CUDA.jl and performing tensor operations. ```julia using ITensors i, j, k = Index.((2, 2, 2)) A = random_itensor(i, j) B = random_itensor(j, k) # Perform tensor operations on CPU A * B ########################################### using CUDA # This will trigger the loading of `NDTensorsCUDAExt` in the background # Move tensors to NVIDIA GPU Acu = cu(A) Bcu = cu(B) # Perform tensor operations on NVIDIA GPU Acu * Bcu ``` -------------------------------- ### QN Diagonal Constructors Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/ITensorType.md Constructs QN-labeled diagonal ITensors. Use for sparse diagonal tensors with quantum number support. ```julia diag_itensor(::Type{<:Number}, ::QN, ::ITensors.Indices) ``` ```julia delta(::Type{<:Number}, ::QN, ::ITensors.Indices) ``` -------------------------------- ### Create ITensor from Julia Array (2D) Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/examples/ITensor.md Initialize an ITensor with specified indices from a 2D Julia array (matrix). ```julia M = [1.0 2.0; 3.0 4.0] i = Index(2,"i") j = Index(2,"j") A = ITensor(M,i,j) ``` -------------------------------- ### Find Optimal Contraction Sequence and Cost Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/ContractionSequenceOptimization.md Systematically search for the optimal contraction sequence for a tensor network across a range of dimensions and calculate its symbolic cost. Requires TensorOperations.jl to be loaded. ```julia using ITensors using Symbolics using ITensors: contraction_cost, optimal_contraction_sequence using TensorOperations: TensorOperations function tensor_network(; m, k, d) l = Index(m, "l") r = Index(m, "r") h₁ = Index(k, "h₁") h₂ = Index(k, "h₂") h₃ = Index(k, "h₃") s₁ = Index(d, "s₁") s₂ = Index(d, "s₂") ψ = ITensor(l, s₁, s₂, r) L = ITensor(dag(l), l', h₁) H₁ = ITensor(dag(s₁), s₁', dag(h₁), h₂) H₂ = ITensor(dag(s₂), s₂', dag(h₂), h₃) R = ITensor(dag(r), r', h₃) return [ψ, L, H₁, H₂, R] end function main() mrange = 50:10:80 krange = 50:10:80 sequence_costs = Matrix{Any}(undef, length(mrange), length(krange)) for iₘ in eachindex(mrange), iₖ in eachindex(krange) m_val = mrange[iₘ] k_val = krange[iₖ] d_val = 4 TN = tensor_network(; m = m_val, k = k_val, d = d_val) sequence = optimal_contraction_sequence(TN) cost = contraction_cost(TN; sequence = sequence) @variables m, k, d TN_symbolic = tensor_network(; m = m, k = k, d = d) cost_symbolic = contraction_cost(TN_symbolic; sequence = sequence) sequence_cost = (dims = (m = m_val, k = k_val, d = d_val), sequence = sequence, cost = cost, symbolic_cost = cost_symbolic) sequence_costs[iₘ, iₖ] = sequence_cost end return sequence_costs end sequence_costs = main() # Analyze the results. println("Index dimensions") display(getindex.(sequence_costs, :dims)) println("\nContraction sequences") display(getindex.(sequence_costs, :sequence)) println("\nSymbolic contraction cost with d = 4") ``` -------------------------------- ### ITensor Constructors with EmptyStorage Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/UpgradeGuide_0.1_to_0.2.md Plain ITensor constructors now return ITensors with EmptyStorage. Contracting two EmptyStorage ITensors results in another EmptyStorage ITensor. Storage is allocated when elements are set. ```julia julia> i = Index(2) (dim=2|id=346) julia> A = ITensor(i', dag(i)) ITensor ord=2 (dim=2|id=346)' (dim=2|id=346) ITensors.NDTensors.EmptyStorage{ITensors.NDTensors.EmptyNumber, ITensors.NDTensors.Dense{ITensors.NDTensors.EmptyNumber, Vector{ITensors.NDTensors.EmptyNumber}}} julia> A' * A ITensor ord=2 (dim=2|id=346)'' (dim=2|id=346) ITensors.NDTensors.EmptyStorage{ITensors.NDTensors.EmptyNumber, ITensors.NDTensors.Dense{ITensors.NDTensors.EmptyNumber, Vector{ITensors.NDTensors.EmptyNumber}}} ``` ```julia julia> A[i' => 1, i => 1] = 0.0 0.0 julia> @show A; A = ITensor ord=2 Dim 1: (dim=2|id=346)' Dim 2: (dim=2|id=346) ITensors.NDTensors.Dense{Float64, Vector{Float64}} 2×2 0.0 0.0 0.0 0.0 ``` ```julia julia> A = ITensor(i', dag(i)) ITensor ord=2 (dim=2|id=346)' (dim=2|id=346) ITensors.NDTensors.EmptyStorage{ITensors.NDTensors.EmptyNumber, ITensors.NDTensors.Dense{ITensors.NDTensors.EmptyNumber, Vector{ITensors.NDTensors.EmptyNumber}}} julia> A[i' => 1, i => 1] = 1.0 + 0.0im 1.0 + 0.0im julia> @show A; A = ITensor ord=2 Dim 1: (dim=2|id=346)' Dim 2: (dim=2|id=346) ITensors.NDTensors.Dense{ComplexF64, Vector{ComplexF64}} 2×2 1.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im ``` -------------------------------- ### ITensor Constructors Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/ITensorType.md Various constructors for creating ITensor objects, including dense, QN block-sparse, and diagonal types. ```APIDOC ## ITensor Constructors ### Description Constructors for creating ITensor objects. ### Methods - `ITensor(::Type{<:Number}, ::ITensors.Indices)` - `ITensor(::Type{<:Number}, ::UndefInitializer, ::ITensors.Indices)` - `ITensor(::Type{<:Number}, ::Number, ::ITensors.Indices)` - `ITensor(::ITensors.AliasStyle, ::Type{<:Number}, ::Array{<:Number}, ::ITensors.Indices{Index{Int}}; kwargs...)` - `random_itensor(::Type{<:Number}, ::ITensors.Indices)` - `onehot` ### Dense View Constructors - `itensor(::Array{<:Number}, ::ITensors.Indices)` ### QN BlockSparse Constructors - `ITensor(::Type{<:Number}, ::QN, ::ITensors.QNIndices)` - `ITensor(::ITensors.AliasStyle, ::Type{<:Number}, ::Array{<:Number}, ::ITensors.QNIndices; tol=0)` - `ITensor(::Type{<:Number}, ::UndefInitializer, ::QN, ::ITensors.Indices)` ### Diagonal Constructors - `diag_itensor(::Type{<:Number}, ::ITensors.Indices)` - `diag_itensor(::ITensors.AliasStyle, ::Type{<:Number}, ::Vector{<:Number}, ::ITensors.Indices)` - `diag_itensor(::ITensors.AliasStyle, ::Type{<:Number}, ::Number, ::ITensors.Indices)` - `delta(::Type{<:Number}, ::ITensors.Indices)` ### QN Diagonal Constructors - `diag_itensor(::Type{<:Number}, ::QN, ::ITensors.Indices)` - `delta(::Type{<:Number}, ::QN, ::ITensors.Indices)` ``` -------------------------------- ### Enable ITensor Debug Checks Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/getting_started/DebugChecks.md Use this command to turn on optional debug checks in ITensor. It is recommended to enable these during development and testing. ```julia ITensors.enable_debug_checks() ``` -------------------------------- ### Create ITensor from Julia Array (nD) Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/examples/ITensor.md Initialize an ITensor with specified indices from an n-dimensional Julia array. ```julia T = randn(4,7,2) k = Index(4,"index_k") l = Index(7,"index_l") m = Index(2,"index_m") B = ITensor(T,k,l,m) ``` -------------------------------- ### Add Specific ITensors.jl Version Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/faq/JuliaPkg.md Use this command to attempt adding a specific version of ITensors.jl. If it fails, the package manager will list blocking dependencies. ```julia julia> ] pkg> add ITensors@v0.3.0 ``` -------------------------------- ### Priming and Tagging Methods Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/IndexType.md Methods for modifying the prime level and tags of an Index. ```APIDOC ## Priming and Tagging Methods ### `prime(::Index, ::Int)` Increases the prime level of the Index by a specified amount. ### `adjoint(::Index)` Returns the adjoint of the Index (equivalent to priming by 1). ### `^(::Index, ::Int)` Raises the Index to a specified prime level. ### `setprime(::Index, ::Int)` Sets the prime level of the Index to a specific value. ### `noprime(::Index)` Resets the prime level of the Index to 0. ### `settags(::Index, ::Any)` Sets the tags of the Index to a new set of tags. ### `addtags(::Index, ::Any)` Adds specified tags to the Index. ### `removetags(::Index, ::Any)` Removes specified tags from the Index. ### `replacetags(::Index, ::Any, ::Any)` Replaces existing tags with new tags. ``` -------------------------------- ### Create One-Hot ITensor with Single Index Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/examples/ITensor.md Generates an ITensor with a single non-zero element (1.0) at a specified index position. Requires the ITensors package. ```julia using ITensors # hide i = Index(2) O1 = onehot(i=>1) println(O1) ``` ```julia using ITensors # hide i = Index(2) # hide O2 = onehot(i=>2) println(O2) ``` -------------------------------- ### Configure VS Code for ITensor Sysimage Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/getting_started/RunningCodes.md Add this argument to your VS Code `settings.json` under `julia.additionalArgs` to use the ITensor sysimage. This setting applies to all Julia sessions within VS Code. ```json "--sysimage ~/.julia/sysimages/sys_itensors.so" ``` -------------------------------- ### Iteration Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/IndexType.md Methods for iterating over the values of an Index. ```APIDOC ## Iterating ### `eachval(::Index)` Returns an iterator over the values of the Index. ### `eachindval(::Index)` Returns an iterator over index-value pairs of the Index. ``` -------------------------------- ### Create One-Hot ITensor with Multiple Indices Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/examples/ITensor.md Creates an ITensor with a single non-zero element (1.0) specified by multiple index-value pairs. Requires the ITensors package. ```julia using ITensors # hide i = Index(2) # hide j = Index(3) T = onehot(i=>2,j=>3) println(T) ``` -------------------------------- ### Dense View Constructor Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/ITensorType.md Creates an ITensor from an existing array and indices, providing a view. Useful for efficient data handling. ```julia itensor(::Array{<:Number}, ::ITensors.Indices) ``` -------------------------------- ### Enable Block Sparse Multithreading Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/Multithreading.md Enable multithreaded execution for block sparse tensor operations within ITensors.jl. This is beneficial for QN conserving tensors. ```julia ```@docs ITensors.enable_threaded_blocksparse ``` ``` -------------------------------- ### QN HDF5 Format Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/HDF5FileFormats.md HDF5 file format for the ITensors.QN type. Stores names, values, and moduli of quantum numbers. ```julia # Attributes: # "version" = 1 # "type" = "QN" # Datasets and Subgroups: # "names" [group] = array of strings (length 4) of names of quantum numbers # "vals" [group] = array of integers (length 4) of quantum number values # "mods" [group] = array of integers (length 4) of moduli of quantum numbers ``` -------------------------------- ### Other Methods Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/IndexType.md Miscellaneous methods for Index manipulation. ```APIDOC ## Methods ### `sim(::Index)` Returns a similar Index with the same properties. ### `dag(::Index)` Returns the dagger (conjugate transpose) of the Index. ### `removeqns(::Index)` Removes QNs from the Index. ``` -------------------------------- ### Calculate Contraction Cost for Specific Sequences Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/ContractionSequenceOptimization.md Compute and display the contraction cost for predefined contraction sequences of a tensor network. This helps in understanding how different contraction orders affect computational cost. ```julia using ITensors using Symbolics using ITensors: contraction_cost @variables m, k, d l = Index(m, "l") r = Index(m, "r") h₁ = Index(k, "h₁") h₂ = Index(k, "h₂") h₃ = Index(k, "h₃") s₁ = Index(d, "s₁") s₂ = Index(d, "s₂") H₁ = ITensor(dag(s₁), s₁', dag(h₁), h₂) H₂ = ITensor(dag(s₂), s₂', dag(h₂), h₃) L = ITensor(dag(l), l', h₁) R = ITensor(dag(r), r', h₃) ψ = ITensor(l, s₁, s₂, r) TN = [ψ, L, H₁, H₂, R] sequence1 = Any[2, Any[3, Any[4, Any[1, 5]]]] sequence2 = Any[Any[4, 5], Any[1, Any[2, 3]]] cost1 = contraction_cost(TN; sequence = sequence1) cost2 = contraction_cost(TN; sequence = sequence2) println("First sequence") display(sequence1) display(cost1) @show sum(cost1) @show substitute(sum(cost1), Dict(d => 4)) println("\nSecond sequence") display(sequence2) display(cost2) @show sum(cost2) @show substitute(sum(cost2), Dict(d => 4)) ``` -------------------------------- ### Read ITensor from HDF5 File Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/examples/ITensor.md Load an ITensor from an HDF5 file. The `ITensor` type argument to `read` specifies how to interpret the stored data. The file and dataset names must match those used during writing. ```julia T = h5open("myfile.h5","r") do f read(f,"T",ITensor) end ``` -------------------------------- ### Decompositions Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/ITensorType.md Decomposition methods for ITensors, such as SVD and eigenvalue decomposition. ```APIDOC ## Decompositions ### Description Decomposition algorithms for ITensors. ### Methods - `svd(::ITensor, ::Any...) - `eigen(::ITensor, ::Any, ::Any) - `factorize(::ITensor, ::Any...) ``` -------------------------------- ### Replacing IndexVal with Pair Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/UpgradeGuide_0.1_to_0.2.md Demonstrates the modern way to represent an index and its integer value using Julia's Pair type, which replaces the deprecated IndexVal type. ```julia i = Index(2) i => 2 ``` ```julia i = Index(2) # Or: Pair(i, 2) ``` -------------------------------- ### Add Custom Debug Checks with Macro Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/getting_started/DebugChecks.md You can add your own debug checks to your code by wrapping specific code sections with the `ITensors.@debug_check` macro. ```julia ITensors.@debug_check ``` -------------------------------- ### Control BLAS Threads at Runtime Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/Multithreading.md Manage the number of BLAS threads directly within a Julia session using the LinearAlgebra package. This allows dynamic adjustment of threading for linear algebra operations. ```julia julia> using LinearAlgebra julia> BLAS.vendor() :mkl julia> BLAS.get_num_threads() 6 julia> BLAS.set_num_threads(4) julia> BLAS.get_num_threads() 4 ``` -------------------------------- ### Dispatch on ITensor Order with Order Type Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/UpgradeGuide_0.1_to_0.2.md An alternative to if-statements for dispatching on ITensor order using the `Order` type. Note that this method is not type stable and may incur a small runtime overhead. ```julia function mynorm(::Order{N}, A::ITensor) where {N} return norm(A)^N end function mynorm(::Order{1}, A::ITensor) return norm(A) end function mynorm(::Order{2}, A::ITensor) return norm(A)^2 end function mynorm(A::ITensor) return mynorm(Order(A), A) end ``` -------------------------------- ### Index Properties Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/IndexType.md Methods to access properties of an Index object. ```APIDOC ## Properties ### `id(::Index)` Returns the unique identifier of the Index. ### `hasid(::Index, ::ITensors.IDType)` Checks if the Index has a specific ID type. ### `tags(::Index)` Returns the tags associated with the Index. ### `ITensors.set_strict_tags!(::Bool)` Sets the strict tag mode for ITensors. ### `ITensors.using_strict_tags()` Checks if strict tag mode is currently enabled. ### `hastags(::Index, ::Union{AbstractString,TagSet})` Checks if the Index has the specified tags. ### `plev(::Index)` Returns the physical level of the Index. ### `hasplev(::Index, ::Int)` Checks if the Index has a specific physical level. ### `dim(::Index)` Returns the dimension of the Index. ### `==(::Index, ::Index)` Compares two Index objects for equality. ### `dir(::Index)` Returns the direction of the Index. ### `hasqns(::Index)` Checks if the Index has associated QNs (Quantum Numbers). ``` -------------------------------- ### Compute QR Factorization of an ITensor Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/examples/ITensor.md Compute the QR factorization of an ITensor by specifying the indices that should belong to the Q tensor. The `positive=true` option ensures unique factorization by making diagonal elements of R non-negative. ```julia T = random_itensor(i,j,k) Q,R = qr(T,(i,k);positive=true) ``` -------------------------------- ### Diagonal Constructors Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/ITensorType.md Constructs diagonal ITensors. Efficient for tensors with only diagonal elements. ```julia diag_itensor(::Type{<:Number}, ::ITensors.Indices) ``` ```julia diag_itensor(::ITensors.AliasStyle, ::Type{<:Number}, ::Vector{<:Number}, ::ITensors.Indices) ``` ```julia diag_itensor(::ITensors.AliasStyle, ::Type{<:Number}, ::Number, ::ITensors.Indices) ``` ```julia delta(::Type{<:Number}, ::ITensors.Indices) ``` -------------------------------- ### Decompositions Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/ITensorType.md Performs tensor decompositions such as SVD, eigenvalue decomposition, and factorization. ```julia svd(::ITensor, ::Any...) ``` ```julia eigen(::ITensor, ::Any, ::Any) ``` ```julia factorize(::ITensor, ::Any...) ``` -------------------------------- ### ITensor Constructors Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/ITensorType.md Constructs an ITensor with specified element type, indices, and optional initial values. Use for creating dense tensors. ```julia ITensor(::Type{<:Number}, ::ITensors.Indices) ``` ```julia ITensor(::Type{<:Number}, ::UndefInitializer, ::ITensors.Indices) ``` ```julia ITensor(::Type{<:Number}, ::Number, ::ITensors.Indices) ``` ```julia ITensor(::ITensors.AliasStyle, ::Type{<:Number}, ::Array{<:Number}, ::ITensors.Indices{Index{Int}}; kwargs...) ``` ```julia random_itensor(::Type{<:Number}, ::ITensors.Indices) ``` ```julia onehot ``` -------------------------------- ### Convert ITensor to Julia Array Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/examples/ITensor.md Convert an ITensor back into a regular Julia array. The order of indices must be explicitly provided. ```julia using ITensors # hide k = Index(4,"index_k") m = Index(2,"index_m") T = random_itensor(k,m) @show T display(T) # hide A = Array(T,k,m) @show A ``` -------------------------------- ### Element-wise Addition with Coefficients Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/examples/ITensor.md Performs element-wise addition of two ITensors with scalar coefficients applied to each. ```julia A .= (2.0 .* A) .+ (-3.0 .* B) ``` -------------------------------- ### Dispatch on ITensor Order with If-Statements Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/UpgradeGuide_0.1_to_0.2.md Replace dispatch on the ITensor order type parameter with if-statements checking the order of the ITensor. This approach uses `order(A)` to determine the tensor order. ```julia using ITensors function mynorm(A::ITensor{N}) where {N} return norm(A)^N end function mynorm(A::ITensor{1}) return norm(A) end function mynorm(A::ITensor{2}) return norm(A)^2 end ``` ```julia function mynormN(A::ITensor) return norm(A)^order(A) end function mynorm1(A::ITensor) return norm(A) end function mynorm2(A::ITensor) return norm(A)^2 end function mynorm(A::ITensor) return if order(A) == 1 mynorm1(A) elseif order(A) == 2 mynorm2(A) else return mynormN(A) end end ``` -------------------------------- ### QN Properties Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/QN.md Retrieves the value or modulus of a quantum number associated with a specific name from a QN object. ```julia val(q::QN,name) ``` ```julia modulus(q::QN,name) ``` -------------------------------- ### Array Conversion Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/ITensorType.md Methods for converting ITensors to and from Array types. ```APIDOC ## Convert to Array ### Description Methods for converting ITensors to and from Array types. ### Methods - `Array{ElT, N}(::ITensor, ::ITensors.Indices) where {ElT, N}` - `array(::ITensor, ::Any...) - `matrix(::ITensor, ::Any...) - `vector(::ITensor, ::Any...) - `array(::ITensor) - `matrix(::ITensor) - `vector(::ITensor)` ``` -------------------------------- ### ITensor Construction from Array Element Type Conversion Source: https://github.com/itensor/itensors.jl/blob/main/docs/src/UpgradeGuide_0.1_to_0.2.md ITensor constructors from Array now convert to floating point only for Array{Int} and Array{Complex{Int}}. This change ensures consistency between QN and non-QN ITensor constructors. ```julia ITensor(i, j, k) ```