1
1
module ITensorBase
2
2
3
+ export ITensor, Index
4
+
5
+ using Accessors: @set
3
6
using MapBroadcast: Mapped
4
7
using NamedDimsArrays:
5
8
NamedDimsArrays,
@@ -14,16 +17,53 @@ using NamedDimsArrays:
14
17
name,
15
18
named,
16
19
nameddimsindices,
20
+ setname,
21
+ setnameddimsindices,
17
22
unname
18
23
24
+ const Tag = String
25
+ const TagSet = Set{Tag}
26
+
27
+ tagset (tags:: String ) = Set (filter (! isempty, String .(strip .(split (tags, " ," )))))
28
+ tagset (tags:: TagSet ) = tags
29
+
30
+ function tagsstring (tags:: TagSet )
31
+ str = " "
32
+ length (tags) == 0 && return str
33
+ tags_vec = collect (tags)
34
+ for n in 1 : (length (tags_vec) - 1 )
35
+ str *= " $(tags_vec[n]) ,"
36
+ end
37
+ str *= " $(tags_vec[end ]) "
38
+ return str
39
+ end
40
+
19
41
@kwdef struct IndexName <: AbstractName
20
42
id:: UInt64 = rand (UInt64)
43
+ tags:: TagSet = TagSet ()
21
44
plev:: Int = 0
22
- tags:: Set{String} = Set {String} ()
23
- namedtags:: Dict{Symbol,String} = Dict {Symbol,String} ()
24
45
end
25
46
NamedDimsArrays. randname (n:: IndexName ) = IndexName ()
26
47
48
+ id (n:: IndexName ) = n. id
49
+ tags (n:: IndexName ) = n. tags
50
+ plev (n:: IndexName ) = n. plev
51
+
52
+ settags (n:: IndexName , tags) = @set n. tags = tags
53
+ addtags (n:: IndexName , ts) = settags (n, tags (n) ∪ tagset (ts))
54
+
55
+ setprime (n:: IndexName , plev) = @set n. plev = plev
56
+ prime (n:: IndexName ) = setprime (n, plev (n) + 1 )
57
+
58
+ function Base. show (io:: IO , i:: IndexName )
59
+ idstr = " id=$(id (i) % 1000 ) "
60
+ tagsstr = ! isempty (tags (i)) ? " |\" $(tagsstring (tags (i))) \" " : " "
61
+ primestr = primestring (plev (i))
62
+ str = " IndexName($(idstr)$(tagsstr) )$(primestr) "
63
+ print (io, str)
64
+ return nothing
65
+ end
66
+
27
67
struct IndexVal{Value<: Integer } <: AbstractNamedInteger{Value,IndexName}
28
68
value:: Value
29
69
name:: IndexName
@@ -41,7 +81,22 @@ struct Index{T,Value<:AbstractUnitRange{T}} <: AbstractNamedUnitRange{T,Value,In
41
81
name:: IndexName
42
82
end
43
83
44
- Index (length:: Int ) = Index (Base. OneTo (length), IndexName ())
84
+ function Index (length:: Int ; tags= TagSet (), kwargs... )
85
+ return Index (Base. OneTo (length), IndexName (; tags= tagset (tags), kwargs... ))
86
+ end
87
+ function Index (length:: Int , tags:: String ; kwargs... )
88
+ return Index (Base. OneTo (length), IndexName (; kwargs... , tags= tagset (tags)))
89
+ end
90
+
91
+ # TODO : Define for `NamedDimsArrays.NamedViewIndex`.
92
+ id (i:: Index ) = id (name (i))
93
+ tags (i:: Index ) = tags (name (i))
94
+ plev (i:: Index ) = plev (name (i))
95
+
96
+ # TODO : Define for `NamedDimsArrays.NamedViewIndex`.
97
+ addtags (i:: Index , tags) = setname (i, addtags (name (i), tags))
98
+ prime (i:: Index ) = setname (i, prime (name (i)))
99
+ Base. adjoint (i:: Index ) = prime (i)
45
100
46
101
# Interface
47
102
# TODO : Overload `Base.parent` instead.
@@ -51,6 +106,29 @@ NamedDimsArrays.name(i::Index) = i.name
51
106
# Constructor
52
107
NamedDimsArrays. named (i:: AbstractUnitRange , name:: IndexName ) = Index (i, name)
53
108
109
+ function primestring (plev)
110
+ if plev < 0
111
+ return " (warning: prime level $plev is less than 0)"
112
+ end
113
+ if plev == 0
114
+ return " "
115
+ elseif plev > 3
116
+ return " '$plev "
117
+ else
118
+ return " '" ^ plev
119
+ end
120
+ end
121
+
122
+ function Base. show (io:: IO , i:: Index )
123
+ lenstr = " length=$(dename (length (i))) "
124
+ idstr = " |id=$(id (i) % 1000 ) "
125
+ tagsstr = ! isempty (tags (i)) ? " |\" $(tagsstring (tags (i))) \" " : " "
126
+ primestr = primestring (plev (i))
127
+ str = " Index($(lenstr)$(idstr)$(tagsstr) )$(primestr) "
128
+ print (io, str)
129
+ return nothing
130
+ end
131
+
54
132
struct NoncontiguousIndex{T,Value<: AbstractVector{T} } < :
55
133
AbstractNamedVector{T,Value,IndexName}
56
134
value:: Value
@@ -103,17 +181,30 @@ struct AllocatableArrayInterface <: AbstractAllocatableArrayInterface end
103
181
104
182
unallocatable (a:: AbstractITensor ) = NamedDimsArray (a)
105
183
106
- @interface :: AbstractAllocatableArrayInterface function Base. setindex! (
107
- a:: AbstractArray , value, I:: Int...
108
- )
184
+ function setindex_allocatable! (a:: AbstractArray , value, I... )
109
185
allocate! (specify_eltype! (a, typeof (value)))
110
186
# TODO : Maybe use `@interface interface(a) a[I...] = value`?
111
187
unallocatable (a)[I... ] = value
112
188
return a
113
189
end
114
190
191
+ # TODO : Combine these by using `Base.to_indices`.
192
+ @interface :: AbstractAllocatableArrayInterface function Base. setindex! (
193
+ a:: AbstractArray , value, I:: Int...
194
+ )
195
+ setindex_allocatable! (a, value, I... )
196
+ return a
197
+ end
198
+ @interface :: AbstractAllocatableArrayInterface function Base. setindex! (
199
+ a:: AbstractArray , value, I:: AbstractNamedInteger...
200
+ )
201
+ setindex_allocatable! (a, value, I... )
202
+ return a
203
+ end
204
+
115
205
@derive AllocatableArrayInterface () (T= AbstractITensor,) begin
116
206
Base. setindex! (:: T , :: Any , :: Int... )
207
+ Base. setindex! (:: T , :: Any , :: AbstractNamedInteger... )
117
208
end
118
209
119
210
mutable struct ITensor <: AbstractITensor
@@ -127,9 +218,42 @@ using Accessors: @set
127
218
setdenamed (a:: ITensor , denamed) = (@set a. parent = denamed)
128
219
setdenamed! (a:: ITensor , denamed) = (a. parent = denamed)
129
220
221
+ function ITensor (elt:: Type , I1:: Index , I_rest:: Index... )
222
+ I = (I1, I_rest... )
223
+ # TODO : Use `FillArrays.Zeros`.
224
+ return ITensor (zeros (elt, length .(dename .(I))... ), I)
225
+ end
226
+
130
227
function ITensor (I1:: Index , I_rest:: Index... )
131
228
I = (I1, I_rest... )
132
229
return ITensor (Zeros {UnspecifiedZero} (length .(dename .(I))... ), I)
133
230
end
134
231
232
+ function ITensor ()
233
+ return ITensor (Zeros {UnspecifiedZero} (), ())
234
+ end
235
+
236
+ inds (a:: AbstractITensor ) = nameddimsindices (a)
237
+ setinds (a:: AbstractITensor , inds) = setnameddimsindices (a, inds)
238
+
239
+ function uniqueinds (a1:: AbstractITensor , a_rest:: AbstractITensor... )
240
+ return setdiff (inds (a1), inds .(a_rest)... )
241
+ end
242
+ function uniqueind (a1:: AbstractITensor , a_rest:: AbstractITensor... )
243
+ return only (uniqueinds (a1, a_rest... ))
244
+ end
245
+
246
+ function commoninds (a1:: AbstractITensor , a_rest:: AbstractITensor... )
247
+ return intersect (inds (a1), inds .(a_rest)... )
248
+ end
249
+ function commonind (a1:: AbstractITensor , a_rest:: AbstractITensor... )
250
+ return only (commoninds (a1, a_rest... ))
251
+ end
252
+
253
+ # TODO : Use `replaceinds`/`mapinds`, based on
254
+ # `replacenameddimsindices`/`mapnameddimsindices`.
255
+ prime (a:: AbstractITensor ) = setinds (a, prime .(inds (a)))
256
+
257
+ include (" quirks.jl" )
258
+
135
259
end
0 commit comments