Skip to content

Commit 0f92925

Browse files
authored
Initial basic working implementation of ITensor and Index (#1)
1 parent 985c06e commit 0f92925

File tree

10 files changed

+191
-50
lines changed

10 files changed

+191
-50
lines changed

LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2025 ITensor developers
3+
Copyright (c) 2024 ITensor developers
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

Project.toml

+6
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,11 @@ uuid = "4795dd04-0d67-49bb-8f44-b89c448a1dc7"
33
authors = ["ITensor developers <[email protected]> and contributors"]
44
version = "0.1.0"
55

6+
[deps]
7+
BroadcastMapConversion = "4a4adec5-520f-4750-bb37-d5e66b4ddeb2"
8+
NamedDimsArrays = "60cbd0c0-df58-4cb7-918c-6f5607b73fde"
9+
610
[compat]
11+
BroadcastMapConversion = "0.1.2"
12+
NamedDimsArrays = "0.3.0"
713
julia = "1.10"

README.md

+24-17
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,7 @@
99

1010
## Installation instructions
1111

12-
This package resides in the `ITensor/ITensorRegistry` local registry.
13-
In order to install, simply add that registry through your package manager.
14-
This step is only required once.
15-
```julia
16-
julia> using Pkg: Pkg
17-
18-
julia> Pkg.Registry.add(url="https://github.com/ITensor/ITensorRegistry")
19-
```
20-
or:
21-
```julia
22-
julia> Pkg.Registry.add(url="[email protected]:ITensor/ITensorRegistry.git")
23-
```
24-
if you want to use SSH credentials, which can make it so you don't have to enter your Github ursername and password when registering packages.
25-
26-
Then, the package can be added as usual through the package manager:
12+
The package can be added as usual through the package manager:
2713

2814
```julia
2915
julia> Pkg.add("ITensorBase")
@@ -32,10 +18,31 @@ julia> Pkg.add("ITensorBase")
3218
## Examples
3319

3420
````julia
35-
using ITensorBase: ITensorBase
21+
using ITensorBase: ITensorBase, ITensor, Index
3622
````
3723

38-
Examples go here.
24+
TODO: This should be `TensorAlgebra.qr`.
25+
26+
````julia
27+
using LinearAlgebra: qr
28+
using NamedDimsArrays: NamedDimsArray, aligndims, dimnames, name, unname
29+
using Test: @test
30+
i = Index(2)
31+
j = Index(2)
32+
k = Index(2)
33+
a = randn(i, j)
34+
@test a[j[2], i[1]] == a[1, 2]
35+
@test a[j => 2, i => 1] == a[1, 2]
36+
a′ = randn(j, i)
37+
b = randn(j, k)
38+
c = a * b
39+
@test unname(c, (i, k)) unname(a, (i, j)) * unname(b, (j, k))
40+
d = a + a′
41+
@test unname(d, (i, j)) unname(a, (i, j)) + unname(a′, (i, j))
42+
@test a aligndims(a, (j, i))
43+
q, r = qr(a, (i,))
44+
@test q * r a
45+
````
3946

4047
---
4148

TODO.md

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
- Logic around element type promotion, BangBang.jl syntax.
2+
```julia
3+
module MutableStorageArrays
4+
5+
module NoBang
6+
function setindex(a::AbstractArray, value, I::Int...)
7+
a′ = similar(a, typeof(value))
8+
a′ .= a
9+
a′[I...] = value
10+
return a′
11+
end
12+
13+
function setindex(a::AbstractArray, value, I...)
14+
a′ = similar(a, eltype(value))
15+
a′ .= a
16+
a′[I...] = value
17+
return a′
18+
end
19+
end
20+
21+
function may(f!, args...)
22+
if possible(f!, args...)
23+
return f!(args...)
24+
end
25+
return pure(f!)(args...)
26+
end
27+
28+
implements(f!, x) = implements(f!, typeof(x))
29+
implements(f!, ::Type) = false
30+
31+
function setindex!! end
32+
setindex!!(a::AbstractArray, value, I...) = may(setindex!, a, value, I...)
33+
implements(::typeof(setindex!), ::Type{<:AbstractArray}) = true
34+
pure(::typeof(setindex!)) = NoBang.setindex
35+
maymutate(::typeof(setindex!)) = setindex!!
36+
function possible(::typeof(setindex!), a::AbstractArray, value, I::Int...)
37+
return implements(setindex!, a) && promote_type(eltype(a), typeof(value)) <: eltype(a)
38+
end
39+
function possible(::typeof(setindex!), a::AbstractArray, value, I...)
40+
return implements(setindex!, a) && promote_type(eltype(a), eltype(value)) <: eltype(a)
41+
end
42+
43+
struct MutableStorageArrayInterface <: AbstractArrayInterface end
44+
45+
# Minimal interface.
46+
function storage end
47+
function setstorage! end
48+
49+
@interface ::MutableStorageArrayInterface function Base.setindex!(a::AbstractArray, value, I...)
50+
return setstorage!(a, storage(setindex!!(a, value, I...)))
51+
end
52+
53+
end
54+
```

docs/Project.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
[deps]
2-
ITensorBase = "4795dd04-0d67-49bb-8f44-b89c448a1dc7"
32
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
3+
ITensorBase = "4795dd04-0d67-49bb-8f44-b89c448a1dc7"
44
Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306"
5+
NamedDimsArrays = "60cbd0c0-df58-4cb7-918c-6f5607b73fde"

docs/make.jl

+3-9
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
using ITensorBase: ITensorBase
22
using Documenter: Documenter, DocMeta, deploydocs, makedocs
33

4-
DocMeta.setdocmeta!(
5-
ITensorBase, :DocTestSetup, :(using ITensorBase); recursive=true
6-
)
4+
DocMeta.setdocmeta!(ITensorBase, :DocTestSetup, :(using ITensorBase); recursive=true)
75

86
include("make_index.jl")
97

@@ -12,13 +10,9 @@ makedocs(;
1210
authors="ITensor developers <[email protected]> and contributors",
1311
sitename="ITensorBase.jl",
1412
format=Documenter.HTML(;
15-
canonical="https://ITensor.github.io/ITensorBase.jl",
16-
edit_link="main",
17-
assets=String[],
13+
canonical="https://ITensor.github.io/ITensorBase.jl", edit_link="main", assets=String[]
1814
),
1915
pages=["Home" => "index.md"],
2016
)
2117

22-
deploydocs(;
23-
repo="github.com/ITensor/ITensorBase.jl", devbranch="main", push_preview=true
24-
)
18+
deploydocs(; repo="github.com/ITensor/ITensorBase.jl", devbranch="main", push_preview=true)

examples/Project.toml

+2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
[deps]
22
ITensorBase = "4795dd04-0d67-49bb-8f44-b89c448a1dc7"
3+
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
4+
NamedDimsArrays = "60cbd0c0-df58-4cb7-918c-6f5607b73fde"

examples/README.jl

+21-21
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,7 @@
99

1010
# ## Installation instructions
1111

12-
# This package resides in the `ITensor/ITensorRegistry` local registry.
13-
# In order to install, simply add that registry through your package manager.
14-
# This step is only required once.
15-
#=
16-
```julia
17-
julia> using Pkg: Pkg
18-
19-
julia> Pkg.Registry.add(url="https://github.com/ITensor/ITensorRegistry")
20-
```
21-
=#
22-
# or:
23-
#=
24-
```julia
25-
julia> Pkg.Registry.add(url="[email protected]:ITensor/ITensorRegistry.git")
26-
```
27-
=#
28-
# if you want to use SSH credentials, which can make it so you don't have to enter your Github ursername and password when registering packages.
29-
30-
# Then, the package can be added as usual through the package manager:
12+
# The package can be added as usual through the package manager:
3113

3214
#=
3315
```julia
@@ -37,5 +19,23 @@ julia> Pkg.add("ITensorBase")
3719

3820
# ## Examples
3921

40-
using ITensorBase: ITensorBase
41-
# Examples go here.
22+
using ITensorBase: ITensorBase, ITensor, Index
23+
# TODO: This should be `TensorAlgebra.qr`.
24+
using LinearAlgebra: qr
25+
using NamedDimsArrays: NamedDimsArray, aligndims, dimnames, name, unname
26+
using Test: @test
27+
i = Index(2)
28+
j = Index(2)
29+
k = Index(2)
30+
a = randn(i, j)
31+
@test a[j[2], i[1]] == a[1, 2]
32+
@test a[j => 2, i => 1] == a[1, 2]
33+
a′ = randn(j, i)
34+
b = randn(j, k)
35+
c = a * b
36+
@test unname(c, (i, k)) unname(a, (i, j)) * unname(b, (j, k))
37+
d = a + a′
38+
@test unname(d, (i, j)) unname(a, (i, j)) + unname(a′, (i, j))
39+
@test a aligndims(a, (j, i))
40+
q, r = qr(a, (i,))
41+
@test q * r a

src/ITensorBase.jl

+75-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,79 @@
11
module ITensorBase
22

3-
# Write your package code here.
3+
using BroadcastMapConversion: Mapped
4+
using NamedDimsArrays:
5+
NamedDimsArrays,
6+
AbstractName,
7+
AbstractNamedDimsArray,
8+
AbstractNamedInteger,
9+
AbstractNamedUnitRange,
10+
AbstractNamedVector,
11+
dename,
12+
dimnames,
13+
name,
14+
named,
15+
unname
16+
17+
@kwdef struct IndexName <: AbstractName
18+
id::UInt64 = rand(UInt64)
19+
plev::Int = 0
20+
tags::Set{String} = Set{String}()
21+
namedtags::Dict{Symbol,String} = Dict{Symbol,String}()
22+
end
23+
NamedDimsArrays.randname(n::IndexName) = IndexName()
24+
25+
struct IndexVal{Value<:Integer} <: AbstractNamedInteger{Value,IndexName}
26+
value::Value
27+
name::IndexName
28+
end
29+
30+
# Interface
31+
NamedDimsArrays.dename(i::IndexVal) = i.value
32+
NamedDimsArrays.name(i::IndexVal) = i.name
33+
34+
# Constructor
35+
NamedDimsArrays.named(i::Integer, name::IndexName) = IndexVal(i, name)
36+
37+
struct Index{T,Value<:AbstractUnitRange{T}} <: AbstractNamedUnitRange{T,Value,IndexName}
38+
value::Value
39+
name::IndexName
40+
end
41+
42+
Index(length::Int) = Index(Base.OneTo(length), IndexName())
43+
44+
# Interface
45+
# TODO: Overload `Base.parent` instead.
46+
NamedDimsArrays.dename(i::Index) = i.value
47+
NamedDimsArrays.name(i::Index) = i.name
48+
49+
# Constructor
50+
NamedDimsArrays.named(i::AbstractUnitRange, name::IndexName) = Index(i, name)
51+
52+
struct NoncontiguousIndex{T,Value<:AbstractVector{T}} <:
53+
AbstractNamedVector{T,Value,IndexName}
54+
value::Value
55+
name::IndexName
56+
end
57+
58+
# Interface
59+
# TODO: Overload `Base.parent` instead.
60+
NamedDimsArrays.dename(i::NoncontiguousIndex) = i.value
61+
NamedDimsArrays.name(i::NoncontiguousIndex) = i.name
62+
63+
# Constructor
64+
NamedDimsArrays.named(i::AbstractVector, name::IndexName) = NoncontiguousIndex(i, name)
65+
66+
abstract type AbstractITensor <: AbstractNamedDimsArray{Any,Any} end
67+
68+
NamedDimsArrays.nameddimsarraytype(::Type{<:IndexName}) = ITensor
69+
70+
Base.ndims(::Type{<:AbstractITensor}) = Any
71+
72+
struct ITensor <: AbstractITensor
73+
parent::AbstractArray
74+
nameddimsindices
75+
end
76+
Base.parent(a::ITensor) = a.parent
77+
NamedDimsArrays.nameddimsindices(a::ITensor) = a.nameddimsindices
478

579
end

test/Project.toml

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
[deps]
22
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
3+
ITensorBase = "4795dd04-0d67-49bb-8f44-b89c448a1dc7"
4+
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
5+
NamedDimsArrays = "60cbd0c0-df58-4cb7-918c-6f5607b73fde"
36
SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
47
Suppressor = "fd094767-a336-5f1f-9728-57cf17d0bbfb"
58
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

0 commit comments

Comments
 (0)