Skip to content

Commit 6a2b4d7

Browse files
committed
Rewrite using NamedDimsArrays.jl
1 parent b2b3450 commit 6a2b4d7

File tree

5 files changed

+158
-23
lines changed

5 files changed

+158
-23
lines changed

Project.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,11 @@ uuid = "9136182c-28ba-11e9-034c-db9fb085ebd5"
33
authors = ["ITensor developers <[email protected]> and contributors"]
44
version = "0.8.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"

TODO.md

Lines changed: 54 additions & 0 deletions
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+
```

examples/Project.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
[deps]
2-
ITensors = "3b3c2350-9fb7-4c22-a0c2-b3f20f86ea25"
2+
ITensors = "9136182c-28ba-11e9-034c-db9fb085ebd5"
3+
NamedDimsArrays = "60cbd0c0-df58-4cb7-918c-6f5607b73fde"

examples/README.jl

Lines changed: 21 additions & 21 deletions
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("ITensors")
3719

3820
# ## Examples
3921

40-
using ITensors: ITensors
41-
# Examples go here.
22+
using ITensors: ITensors, 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/ITensors.jl

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,79 @@
11
module ITensors
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

0 commit comments

Comments
 (0)