comparison test/LazyTensors/lazy_tensor_operations_test.jl @ 1002:271aa6ae1055 refactor/lazy_tensors

Split out a file for tensor types
author Jonatan Werpers <jonatan@werpers.com>
date Fri, 18 Mar 2022 22:18:04 +0100
parents 20c376dffe84
children 7fd37aab84fe
comparison
equal deleted inserted replaced
1001:a3df203861d3 1002:271aa6ae1055
21 @test apply_transpose(m', zeros(Float64,(0,0,0)), 0, 0) == :apply 21 @test apply_transpose(m', zeros(Float64,(0,0,0)), 0, 0) == :apply
22 22
23 @test range_size(m') == :domain_size 23 @test range_size(m') == :domain_size
24 @test domain_size(m') == :range_size 24 @test domain_size(m') == :range_size
25 end 25 end
26
26 27
27 @testset "TensorApplication" begin 28 @testset "TensorApplication" begin
28 struct SizeDoublingMapping{T,R,D} <: LazyTensor{T,R,D} 29 struct SizeDoublingMapping{T,R,D} <: LazyTensor{T,R,D}
29 domain_size::NTuple{D,Int} 30 domain_size::NTuple{D,Int}
30 end 31 end
106 @inferred m*v 107 @inferred m*v
107 @inferred (m*v)[1] 108 @inferred (m*v)[1]
108 end 109 end
109 end 110 end
110 111
112
111 @testset "LazyTensor binary operations" begin 113 @testset "LazyTensor binary operations" begin
112 A = ScalingTensor(2.0, (3,)) 114 A = ScalingTensor(2.0, (3,))
113 B = ScalingTensor(3.0, (3,)) 115 B = ScalingTensor(3.0, (3,))
114 116
115 v = [1.1,1.2,1.3] 117 v = [1.1,1.2,1.3]
153 155
154 @test (Ã∘B̃*ComplexF64[1.,2.,3.,4.])[1] isa ComplexF64 156 @test (Ã∘B̃*ComplexF64[1.,2.,3.,4.])[1] isa ComplexF64
155 @test ((Ã∘B̃)'*ComplexF64[1.,2.])[1] isa ComplexF64 157 @test ((Ã∘B̃)'*ComplexF64[1.,2.])[1] isa ComplexF64
156 end 158 end
157 159
158 @testset "LazyLinearMap" begin
159 # Test a standard matrix-vector product
160 # mapping vectors of size 4 to vectors of size 3.
161 A = rand(3,4)
162 Ã = LazyLinearMap(A, (1,), (2,))
163 v = rand(4)
164 w = rand(3)
165
166 @test à isa LazyLinearMap{T,1,1} where T
167 @test à isa LazyTensor{T,1,1} where T
168 @test range_size(Ã) == (3,)
169 @test domain_size(Ã) == (4,)
170
171 @test Ã*ones(4) ≈ A*ones(4) atol=5e-13
172 @test Ã*v ≈ A*v atol=5e-13
173 @test Ã'*w ≈ A'*w
174
175 A = rand(2,3,4)
176 @test_throws DomainError LazyLinearMap(A, (3,1), (2,))
177
178 # Test more exotic mappings
179 B = rand(3,4,2)
180 # Map vectors of size 2 to matrices of size (3,4)
181 B̃ = LazyLinearMap(B, (1,2), (3,))
182 v = rand(2)
183
184 @test range_size(B̃) == (3,4)
185 @test domain_size(B̃) == (2,)
186 @test B̃ isa LazyTensor{T,2,1} where T
187 @test B̃*ones(2) ≈ B[:,:,1] + B[:,:,2] atol=5e-13
188 @test B̃*v ≈ B[:,:,1]*v[1] + B[:,:,2]*v[2] atol=5e-13
189
190 # Map matrices of size (3,2) to vectors of size 4
191 B̃ = LazyLinearMap(B, (2,), (1,3))
192 v = rand(3,2)
193
194 @test range_size(B̃) == (4,)
195 @test domain_size(B̃) == (3,2)
196 @test B̃ isa LazyTensor{T,1,2} where T
197 @test B̃*ones(3,2) ≈ B[1,:,1] + B[2,:,1] + B[3,:,1] +
198 B[1,:,2] + B[2,:,2] + B[3,:,2] atol=5e-13
199 @test B̃*v ≈ B[1,:,1]*v[1,1] + B[2,:,1]*v[2,1] + B[3,:,1]*v[3,1] +
200 B[1,:,2]v[1,2] + B[2,:,2]*v[2,2] + B[3,:,2]*v[3,2] atol=5e-13
201
202
203 # TODO:
204 # @inferred (B̃*v)[2]
205 end
206
207
208 @testset "IdentityTensor" begin
209 @test IdentityTensor{Float64}((4,5)) isa IdentityTensor{T,2} where T
210 @test IdentityTensor{Float64}((4,5)) isa LazyTensor{T,2,2} where T
211 @test IdentityTensor{Float64}((4,5)) == IdentityTensor{Float64}(4,5)
212
213 @test IdentityTensor(3,2) isa IdentityTensor{Float64,2}
214
215 for sz ∈ [(4,5),(3,),(5,6,4)]
216 I = IdentityTensor{Float64}(sz)
217 v = rand(sz...)
218 @test I*v == v
219 @test I'*v == v
220
221 v = rand(ComplexF64,sz...)
222 @test I*v == v
223 @test I'*v == v
224
225 @test range_size(I) == sz
226 @test domain_size(I) == sz
227 end
228
229 I = IdentityTensor{Float64}((4,5))
230 v = rand(4,5)
231 @inferred (I*v)[3,2]
232 @inferred (I'*v)[3,2]
233 @inferred range_size(I)
234
235 @inferred range_dim(I)
236 @inferred domain_dim(I)
237
238 Ã = rand(4,2)
239 A = LazyLinearMap(Ã,(1,),(2,))
240 I1 = IdentityTensor{Float64}(2)
241 I2 = IdentityTensor{Float64}(4)
242 @test A∘I1 == A
243 @test I2∘A == A
244 @test I1∘I1 == I1
245 @test_throws SizeMismatch I1∘A
246 @test_throws SizeMismatch A∘I2
247 @test_throws SizeMismatch I1∘I2
248 end
249
250 @testset "ScalingTensor" begin
251 st = ScalingTensor(2.,(3,4))
252 @test st isa LazyTensor{Float64, 2, 2}
253 @test range_size(st) == (3,4)
254 @test domain_size(st) == (3,4)
255
256 v = rand(3,4)
257 @test st*v == 2.0 .* v
258 @test st'*v == 2.0 .* v
259
260 @inferred (st*v)[2,2]
261 @inferred (st'*v)[2,2]
262 end
263 160
264 @testset "InflatedLazyTensor" begin 161 @testset "InflatedLazyTensor" begin
265 I(sz...) = IdentityTensor(sz...) 162 I(sz...) = IdentityTensor(sz...)
266 163
267 Ã = rand(4,2) 164 Ã = rand(4,2)
393 @test InflatedLazyTensor(I(2), I(2), I(2)) isa InflatedLazyTensor # The constructor should always return its type. 290 @test InflatedLazyTensor(I(2), I(2), I(2)) isa InflatedLazyTensor # The constructor should always return its type.
394 end 291 end
395 end 292 end
396 293
397 @testset "LazyOuterProduct" begin 294 @testset "LazyOuterProduct" begin
398
399 A = ScalingTensor(2.0, (5,)) 295 A = ScalingTensor(2.0, (5,))
400 B = ScalingTensor(3.0, (3,)) 296 B = ScalingTensor(3.0, (3,))
401 C = ScalingTensor(5.0, (3,2)) 297 C = ScalingTensor(5.0, (3,2))
402 298
403 AB = LazyOuterProduct(A,B) 299 AB = LazyOuterProduct(A,B)
443 339
444 I1 = IdentityTensor(3,2) 340 I1 = IdentityTensor(3,2)
445 I2 = IdentityTensor(4) 341 I2 = IdentityTensor(4)
446 @test I1⊗Ã⊗I2 == InflatedLazyTensor(I1, Ã, I2) 342 @test I1⊗Ã⊗I2 == InflatedLazyTensor(I1, Ã, I2)
447 end 343 end
448 344 end
449 end