diff --git a/Project.toml b/Project.toml index e5befc8145..d881749ba7 100644 --- a/Project.toml +++ b/Project.toml @@ -3,5 +3,11 @@ uuid = "9136182c-28ba-11e9-034c-db9fb085ebd5" authors = ["ITensor developers and contributors"] version = "0.8.0" +[deps] +BroadcastMapConversion = "4a4adec5-520f-4750-bb37-d5e66b4ddeb2" +NamedDimsArrays = "60cbd0c0-df58-4cb7-918c-6f5607b73fde" + [compat] +BroadcastMapConversion = "0.1.2" +NamedDimsArrays = "0.3.0" julia = "1.10" diff --git a/README.md b/README.md index f3db44263e..81c3269b8f 100644 --- a/README.md +++ b/README.md @@ -9,21 +9,7 @@ ## Installation instructions -This package resides in the `ITensor/ITensorRegistry` local registry. -In order to install, simply add that registry through your package manager. -This step is only required once. -```julia -julia> using Pkg: Pkg - -julia> Pkg.Registry.add(url="https://github.com/ITensor/ITensorRegistry") -``` -or: -```julia -julia> Pkg.Registry.add(url="git@github.com:ITensor/ITensorRegistry.git") -``` -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. - -Then, the package can be added as usual through the package manager: +The package can be added as usual through the package manager: ```julia julia> Pkg.add("ITensors") @@ -32,10 +18,31 @@ julia> Pkg.add("ITensors") ## Examples ````julia -using ITensors: ITensors +using ITensors: ITensors, ITensor, Index ```` -Examples go here. +TODO: This should be `TensorAlgebra.qr`. + +````julia +using LinearAlgebra: qr +using NamedDimsArrays: NamedDimsArray, aligndims, dimnames, name, unname +using Test: @test +i = Index(2) +j = Index(2) +k = Index(2) +a = randn(i, j) +@test a[j[2], i[1]] == a[1, 2] +@test a[j => 2, i => 1] == a[1, 2] +a′ = randn(j, i) +b = randn(j, k) +c = a * b +@test unname(c, (i, k)) ≈ unname(a, (i, j)) * unname(b, (j, k)) +d = a + a′ +@test unname(d, (i, j)) ≈ unname(a, (i, j)) + unname(a′, (i, j)) +@test a ≈ aligndims(a, (j, i)) +q, r = qr(a, (i,)) +@test q * r ≈ a +```` --- diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000000..dbeebed684 --- /dev/null +++ b/TODO.md @@ -0,0 +1,54 @@ +- Logic around element type promotion, BangBang.jl syntax. +```julia +module MutableStorageArrays + +module NoBang +function setindex(a::AbstractArray, value, I::Int...) + a′ = similar(a, typeof(value)) + a′ .= a + a′[I...] = value + return a′ +end + +function setindex(a::AbstractArray, value, I...) + a′ = similar(a, eltype(value)) + a′ .= a + a′[I...] = value + return a′ +end +end + +function may(f!, args...) + if possible(f!, args...) + return f!(args...) + end + return pure(f!)(args...) +end + +implements(f!, x) = implements(f!, typeof(x)) +implements(f!, ::Type) = false + +function setindex!! end +setindex!!(a::AbstractArray, value, I...) = may(setindex!, a, value, I...) +implements(::typeof(setindex!), ::Type{<:AbstractArray}) = true +pure(::typeof(setindex!)) = NoBang.setindex +maymutate(::typeof(setindex!)) = setindex!! +function possible(::typeof(setindex!), a::AbstractArray, value, I::Int...) + return implements(setindex!, a) && promote_type(eltype(a), typeof(value)) <: eltype(a) +end +function possible(::typeof(setindex!), a::AbstractArray, value, I...) + return implements(setindex!, a) && promote_type(eltype(a), eltype(value)) <: eltype(a) +end + +struct MutableStorageArrayInterface <: AbstractArrayInterface end + +# Minimal interface. +function storage end +function setstorage! end + +@interface ::MutableStorageArrayInterface function Base.setindex!(a::AbstractArray, value, I...) + return setstorage!(a, storage(setindex!!(a, value, I...))) +end + +end +``` diff --git a/docs/Project.toml b/docs/Project.toml index d0900102a4..0a8148e75f 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,4 +1,5 @@ [deps] -ITensors = "3b3c2350-9fb7-4c22-a0c2-b3f20f86ea25" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +ITensors = "9136182c-28ba-11e9-034c-db9fb085ebd5" Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306" +NamedDimsArrays = "60cbd0c0-df58-4cb7-918c-6f5607b73fde" diff --git a/examples/Project.toml b/examples/Project.toml index e8bc93e8a6..2d73659e0d 100644 --- a/examples/Project.toml +++ b/examples/Project.toml @@ -1,2 +1,4 @@ [deps] -ITensors = "3b3c2350-9fb7-4c22-a0c2-b3f20f86ea25" +ITensors = "9136182c-28ba-11e9-034c-db9fb085ebd5" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +NamedDimsArrays = "60cbd0c0-df58-4cb7-918c-6f5607b73fde" diff --git a/examples/README.jl b/examples/README.jl index 00d68cfe9d..5ece9c9ba5 100644 --- a/examples/README.jl +++ b/examples/README.jl @@ -9,25 +9,7 @@ # ## Installation instructions -# This package resides in the `ITensor/ITensorRegistry` local registry. -# In order to install, simply add that registry through your package manager. -# This step is only required once. -#= -```julia -julia> using Pkg: Pkg - -julia> Pkg.Registry.add(url="https://github.com/ITensor/ITensorRegistry") -``` -=# -# or: -#= -```julia -julia> Pkg.Registry.add(url="git@github.com:ITensor/ITensorRegistry.git") -``` -=# -# 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. - -# Then, the package can be added as usual through the package manager: +# The package can be added as usual through the package manager: #= ```julia @@ -37,5 +19,23 @@ julia> Pkg.add("ITensors") # ## Examples -using ITensors: ITensors -# Examples go here. +using ITensors: ITensors, ITensor, Index +# TODO: This should be `TensorAlgebra.qr`. +using LinearAlgebra: qr +using NamedDimsArrays: NamedDimsArray, aligndims, dimnames, name, unname +using Test: @test +i = Index(2) +j = Index(2) +k = Index(2) +a = randn(i, j) +@test a[j[2], i[1]] == a[1, 2] +@test a[j => 2, i => 1] == a[1, 2] +a′ = randn(j, i) +b = randn(j, k) +c = a * b +@test unname(c, (i, k)) ≈ unname(a, (i, j)) * unname(b, (j, k)) +d = a + a′ +@test unname(d, (i, j)) ≈ unname(a, (i, j)) + unname(a′, (i, j)) +@test a ≈ aligndims(a, (j, i)) +q, r = qr(a, (i,)) +@test q * r ≈ a diff --git a/src/ITensors.jl b/src/ITensors.jl index ce4be0e50f..222c546a8b 100644 --- a/src/ITensors.jl +++ b/src/ITensors.jl @@ -1,5 +1,79 @@ module ITensors -# Write your package code here. +using BroadcastMapConversion: Mapped +using NamedDimsArrays: + NamedDimsArrays, + AbstractName, + AbstractNamedDimsArray, + AbstractNamedInteger, + AbstractNamedUnitRange, + AbstractNamedVector, + dename, + dimnames, + name, + named, + unname + +@kwdef struct IndexName <: AbstractName + id::UInt64 = rand(UInt64) + plev::Int = 0 + tags::Set{String} = Set{String}() + namedtags::Dict{Symbol,String} = Dict{Symbol,String}() +end +NamedDimsArrays.randname(n::IndexName) = IndexName() + +struct IndexVal{Value<:Integer} <: AbstractNamedInteger{Value,IndexName} + value::Value + name::IndexName +end + +# Interface +NamedDimsArrays.dename(i::IndexVal) = i.value +NamedDimsArrays.name(i::IndexVal) = i.name + +# Constructor +NamedDimsArrays.named(i::Integer, name::IndexName) = IndexVal(i, name) + +struct Index{T,Value<:AbstractUnitRange{T}} <: AbstractNamedUnitRange{T,Value,IndexName} + value::Value + name::IndexName +end + +Index(length::Int) = Index(Base.OneTo(length), IndexName()) + +# Interface +# TODO: Overload `Base.parent` instead. +NamedDimsArrays.dename(i::Index) = i.value +NamedDimsArrays.name(i::Index) = i.name + +# Constructor +NamedDimsArrays.named(i::AbstractUnitRange, name::IndexName) = Index(i, name) + +struct NoncontiguousIndex{T,Value<:AbstractVector{T}} <: + AbstractNamedVector{T,Value,IndexName} + value::Value + name::IndexName +end + +# Interface +# TODO: Overload `Base.parent` instead. +NamedDimsArrays.dename(i::NoncontiguousIndex) = i.value +NamedDimsArrays.name(i::NoncontiguousIndex) = i.name + +# Constructor +NamedDimsArrays.named(i::AbstractVector, name::IndexName) = NoncontiguousIndex(i, name) + +abstract type AbstractITensor <: AbstractNamedDimsArray{Any,Any} end + +NamedDimsArrays.nameddimsarraytype(::Type{<:IndexName}) = ITensor + +Base.ndims(::Type{<:AbstractITensor}) = Any + +struct ITensor <: AbstractITensor + parent::AbstractArray + nameddimsindices +end +Base.parent(a::ITensor) = a.parent +NamedDimsArrays.nameddimsindices(a::ITensor) = a.nameddimsindices end diff --git a/test/Project.toml b/test/Project.toml index e9c291ea3a..6d76ee2d69 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -1,5 +1,8 @@ [deps] Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" +ITensors = "9136182c-28ba-11e9-034c-db9fb085ebd5" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +NamedDimsArrays = "60cbd0c0-df58-4cb7-918c-6f5607b73fde" SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" Suppressor = "fd094767-a336-5f1f-9728-57cf17d0bbfb" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"