@@ -2,285 +2,8 @@ module ITensorBase
22
33export ITensor, Index
44
5- using Accessors: @set
6- using MapBroadcast: Mapped
7- using NamedDimsArrays:
8- NamedDimsArrays,
9- AbstractName,
10- AbstractNamedDimsArray,
11- AbstractNamedInteger,
12- AbstractNamedUnitRange,
13- AbstractNamedVector,
14- NamedDimsArray,
15- dename,
16- dimnames,
17- mapnameddimsindices,
18- name,
19- named,
20- nameddimsindices,
21- randname,
22- replacenameddimsindices,
23- setname,
24- setnameddimsindices,
25- unname
26-
27- const Tag = String
28- const TagSet = Set{Tag}
29-
30- tagset (tags:: String ) = Set (filter (! isempty, String .(strip .(split (tags, " ," )))))
31- tagset (tags:: TagSet ) = tags
32-
33- function tagsstring (tags:: TagSet )
34- str = " "
35- length (tags) == 0 && return str
36- tags_vec = collect (tags)
37- for n in 1 : (length (tags_vec) - 1 )
38- str *= " $(tags_vec[n]) ,"
39- end
40- str *= " $(tags_vec[end ]) "
41- return str
42- end
43-
44- @kwdef struct IndexName <: AbstractName
45- id:: UInt64 = rand (UInt64)
46- tags:: TagSet = TagSet ()
47- plev:: Int = 0
48- end
49- NamedDimsArrays. randname (n:: IndexName ) = IndexName (; tags= tags (n), plev= plev (n))
50-
51- id (n:: IndexName ) = n. id
52- tags (n:: IndexName ) = n. tags
53- plev (n:: IndexName ) = n. plev
54-
55- settags (n:: IndexName , tags) = @set n. tags = tags
56- addtags (n:: IndexName , ts) = settags (n, tags (n) ∪ tagset (ts))
57-
58- setprime (n:: IndexName , plev) = @set n. plev = plev
59- prime (n:: IndexName ) = setprime (n, plev (n) + 1 )
60- noprime (n:: IndexName ) = setprime (n, 0 )
61- sim (n:: IndexName ) = randname (n)
62-
63- function Base. show (io:: IO , i:: IndexName )
64- idstr = " id=$(id (i) % 1000 ) "
65- tagsstr = ! isempty (tags (i)) ? " |\" $(tagsstring (tags (i))) \" " : " "
66- primestr = primestring (plev (i))
67- str = " IndexName($(idstr)$(tagsstr) )$(primestr) "
68- print (io, str)
69- return nothing
70- end
71-
72- struct IndexVal{Value<: Integer } <: AbstractNamedInteger{Value,IndexName}
73- value:: Value
74- name:: IndexName
75- end
76-
77- # Interface
78- NamedDimsArrays. dename (i:: IndexVal ) = i. value
79- NamedDimsArrays. name (i:: IndexVal ) = i. name
80-
81- # Constructor
82- NamedDimsArrays. named (i:: Integer , name:: IndexName ) = IndexVal (i, name)
83-
84- struct Index{T,Value<: AbstractUnitRange{T} } <: AbstractNamedUnitRange{T,Value,IndexName}
85- value:: Value
86- name:: IndexName
87- end
88-
89- function Index (length:: Int ; tags= TagSet (), kwargs... )
90- return Index (Base. OneTo (length), IndexName (; tags= tagset (tags), kwargs... ))
91- end
92- function Index (length:: Int , tags:: String ; kwargs... )
93- return Index (Base. OneTo (length), IndexName (; kwargs... , tags= tagset (tags)))
94- end
95-
96- # TODO : Define for `NamedDimsArrays.NamedViewIndex`.
97- id (i:: Index ) = id (name (i))
98- tags (i:: Index ) = tags (name (i))
99- plev (i:: Index ) = plev (name (i))
100-
101- # TODO : Define for `NamedDimsArrays.NamedViewIndex`.
102- addtags (i:: Index , tags) = setname (i, addtags (name (i), tags))
103- prime (i:: Index ) = setname (i, prime (name (i)))
104- Base. adjoint (i:: Index ) = prime (i)
105- noprime (i:: Index ) = setname (i, noprime (name (i)))
106- sim (i:: Index ) = setname (i, sim (name (i)))
107-
108- # Interface
109- # TODO : Overload `Base.parent` instead.
110- NamedDimsArrays. dename (i:: Index ) = i. value
111- NamedDimsArrays. name (i:: Index ) = i. name
112-
113- # Constructor
114- NamedDimsArrays. named (i:: AbstractUnitRange , name:: IndexName ) = Index (i, name)
115-
116- function primestring (plev)
117- if plev < 0
118- return " (warning: prime level $plev is less than 0)"
119- end
120- if plev == 0
121- return " "
122- elseif plev > 3
123- return " '$plev "
124- else
125- return " '" ^ plev
126- end
127- end
128-
129- function Base. show (io:: IO , i:: Index )
130- lenstr = " length=$(dename (length (i))) "
131- idstr = " |id=$(id (i) % 1000 ) "
132- tagsstr = ! isempty (tags (i)) ? " |\" $(tagsstring (tags (i))) \" " : " "
133- primestr = primestring (plev (i))
134- str = " Index($(lenstr)$(idstr)$(tagsstr) )$(primestr) "
135- print (io, str)
136- return nothing
137- end
138-
139- struct NoncontiguousIndex{T,Value<: AbstractVector{T} } < :
140- AbstractNamedVector{T,Value,IndexName}
141- value:: Value
142- name:: IndexName
143- end
144-
145- # Interface
146- # TODO : Overload `Base.parent` instead.
147- NamedDimsArrays. dename (i:: NoncontiguousIndex ) = i. value
148- NamedDimsArrays. name (i:: NoncontiguousIndex ) = i. name
149-
150- # Constructor
151- NamedDimsArrays. named (i:: AbstractVector , name:: IndexName ) = NoncontiguousIndex (i, name)
152-
153- abstract type AbstractITensor <: AbstractNamedDimsArray{Any,Any} end
154-
155- NamedDimsArrays. nameddimsarraytype (:: Type{<:IndexName} ) = ITensor
156-
157- Base. ndims (:: Type{<:AbstractITensor} ) = Any
158-
159- using FillArrays: Zeros
160- using UnallocatedArrays: UnallocatedZeros, allocate
161- using UnspecifiedTypes: UnspecifiedZero
162-
163- # TODO : Make this more general, maybe with traits `is_unallocated`
164- # and `is_eltype_unspecified`.
165- function specify_eltype (a:: Zeros{UnspecifiedZero} , elt:: Type )
166- return Zeros {elt} (axes (a))
167- end
168- function specify_eltype (a:: AbstractArray , elt:: Type )
169- return a
170- end
171-
172- # TODO : Use `adapt` to reach down into the storage.
173- function specify_eltype! (a:: AbstractITensor , elt:: Type )
174- setdenamed! (a, specify_eltype (dename (a), elt))
175- return a
176- end
177-
178- # Assume it is allocated.
179- allocate! (a:: AbstractArray ) = a
180-
181- # TODO : Use `adapt` to reach down into the storage.
182- function allocate! (a:: AbstractITensor )
183- setdenamed! (a, allocate (dename (a)))
184- return a
185- end
186-
187- using DerivableInterfaces: @derive , @interface , AbstractArrayInterface
188-
189- abstract type AbstractAllocatableArrayInterface <: AbstractArrayInterface end
190- struct AllocatableArrayInterface <: AbstractAllocatableArrayInterface end
191-
192- unallocatable (a:: AbstractITensor ) = NamedDimsArray (a)
193-
194- function setindex_allocatable! (a:: AbstractArray , value, I... )
195- allocate! (specify_eltype! (a, typeof (value)))
196- # TODO : Maybe use `@interface interface(a) a[I...] = value`?
197- unallocatable (a)[I... ] = value
198- return a
199- end
200-
201- # TODO : Combine these by using `Base.to_indices`.
202- @interface :: AbstractAllocatableArrayInterface function Base. setindex! (
203- a:: AbstractArray , value, I:: Int...
204- )
205- setindex_allocatable! (a, value, I... )
206- return a
207- end
208- @interface :: AbstractAllocatableArrayInterface function Base. setindex! (
209- a:: AbstractArray , value, I:: AbstractNamedInteger...
210- )
211- setindex_allocatable! (a, value, I... )
212- return a
213- end
214-
215- @derive AllocatableArrayInterface () (T= AbstractITensor,) begin
216- Base. setindex! (:: T , :: Any , :: Int... )
217- Base. setindex! (:: T , :: Any , :: AbstractNamedInteger... )
218- end
219-
220- mutable struct ITensor <: AbstractITensor
221- parent:: AbstractArray
222- nameddimsindices
223- end
224- Base. parent (a:: ITensor ) = a. parent
225- NamedDimsArrays. nameddimsindices (a:: ITensor ) = a. nameddimsindices
226-
227- using Accessors: @set
228- setdenamed (a:: ITensor , denamed) = (@set a. parent = denamed)
229- setdenamed! (a:: ITensor , denamed) = (a. parent = denamed)
230-
231- function ITensor (elt:: Type , I1:: Index , I_rest:: Index... )
232- I = (I1, I_rest... )
233- # TODO : Use `FillArrays.Zeros`.
234- return ITensor (zeros (elt, length .(dename .(I))... ), I)
235- end
236-
237- function ITensor (I1:: Index , I_rest:: Index... )
238- I = (I1, I_rest... )
239- return ITensor (Zeros {UnspecifiedZero} (length .(dename .(I))... ), I)
240- end
241-
242- function ITensor ()
243- return ITensor (Zeros {UnspecifiedZero} (), ())
244- end
245-
246- inds (a:: AbstractITensor ) = nameddimsindices (a)
247- setinds (a:: AbstractITensor , inds) = setnameddimsindices (a, inds)
248-
249- function uniqueinds (a1:: AbstractITensor , a_rest:: AbstractITensor... )
250- return setdiff (inds (a1), inds .(a_rest)... )
251- end
252- function uniqueind (a1:: AbstractITensor , a_rest:: AbstractITensor... )
253- return only (uniqueinds (a1, a_rest... ))
254- end
255-
256- function commoninds (a1:: AbstractITensor , a_rest:: AbstractITensor... )
257- return intersect (inds (a1), inds .(a_rest)... )
258- end
259- function commonind (a1:: AbstractITensor , a_rest:: AbstractITensor... )
260- return only (commoninds (a1, a_rest... ))
261- end
262-
263- # TODO : Use `replaceinds`/`mapinds`, based on
264- # `replacenameddimsindices`/`mapnameddimsindices`.
265- prime (a:: AbstractITensor ) = setinds (a, prime .(inds (a)))
266- noprime (a:: AbstractITensor ) = setinds (a, noprime .(inds (a)))
267- sim (a:: AbstractITensor ) = setinds (a, sim .(inds (a)))
268-
269- function replaceinds (a:: AbstractITensor , replacements:: Pair... )
270- return replacenameddimsindices (a, replacements... )
271- end
272-
273- function replaceinds (f, a:: AbstractITensor )
274- return replacenameddimsindices (f, a)
275- end
276-
277- function mapinds (f, a:: AbstractITensor )
278- return mapnameddimsindices (f, a)
279- end
280-
281- using VectorInterface: VectorInterface, scalartype
282- VectorInterface. scalartype (a:: AbstractITensor ) = scalartype (unallocatable (a))
283-
5+ include (" index.jl" )
6+ include (" abstractitensor.jl" )
2847include (" quirks.jl" )
2858
2869end
0 commit comments