Skip to content

Commit 30fb498

Browse files
authored
Merge pull request #170 from Jutho/jh/randisometry
restore randisometry, add tests and deprecations
2 parents a012324 + d95dfd0 commit 30fb498

File tree

5 files changed

+96
-66
lines changed

5 files changed

+96
-66
lines changed

src/TensorKit.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export spacetype, sectortype, storagetype, scalartype, tensormaptype
5656
export blocksectors, blockdim, block, blocks
5757

5858
# random methods for constructor
59-
export randuniform, randnormal, randisometry, randhaar
59+
export randisometry, randisometry!, rand, rand!, randn, randn!
6060

6161
# special purpose constructors
6262
export zero, one, one!, id, isomorphism, unitary, isometry
@@ -123,7 +123,7 @@ using SparseArrays: SparseMatrixCSC, sparse, nzrange, rowvals, nonzeros
123123

124124
import Base.Meta
125125

126-
using Random: Random
126+
using Random: Random, rand!, randn!
127127

128128
using PackageExtensionCompat
129129

src/auxiliary/deprecate.jl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,24 @@ for f in (:rand, :randn, :zeros, :ones)
3636
end
3737
end
3838

39+
Base.@deprecate(randuniform(dims::Base.Dims), rand(dims))
40+
Base.@deprecate(randuniform(T::Type{<:Number}, dims::Base.Dims), rand(T, dims))
41+
Base.@deprecate(randnormal(dims::Base.Dims), randn(dims))
42+
Base.@deprecate(randnormal(T::Type{<:Number}, dims::Base.Dims), randn(T, dims))
43+
Base.@deprecate(randhaar(dims::Base.Dims), randisometry(dims))
44+
Base.@deprecate(randhaar(T::Type{<:Number}, dims::Base.Dims), randisometry(T, dims))
45+
46+
for (f1, f2) in ((:randuniform, :rand), (:randnormal, :randn), (:randisometry, :randisometry), (:randhaar, :randisometry))
47+
@eval begin
48+
Base.@deprecate TensorMap(::typeof($f1), T::Type, P::HomSpace) $f2(T, P)
49+
Base.@deprecate TensorMap(::typeof($f1), P::HomSpace) $f2(P)
50+
Base.@deprecate TensorMap(::typeof($f1), T::Type, cod::TensorSpace, dom::TensorSpace) $f2(T, P, cod, dom)
51+
Base.@deprecate TensorMap(::typeof($f1), cod::TensorSpace, dom::TensorSpace) $f2(cod, dom)
52+
Base.@deprecate Tensor(::typeof($f1), T::Type, space::TensorSpace) $f2(T, space)
53+
Base.@deprecate Tensor(::typeof($f1), space::TensorSpace) $f2(space)
54+
end
55+
end
56+
3957
Base.@deprecate EuclideanProduct() EuclideanInnerProduct()
4058

4159
#! format: on

src/auxiliary/random.jl

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,3 @@
1-
"""
2-
randuniform([::Type{T}=Float64], dims::Dims{N}) -> Array{T,N}
3-
4-
Create an array of size `dims` with random entries uniformly distributed in the allowed
5-
values of `T`.
6-
7-
See also [`randnormal`](@ref), [`randisometry`](@ref) and[`randhaar`](@ref).
8-
"""
9-
randuniform(dims::Base.Dims) = randuniform(Float64, dims)
10-
randuniform(::Type{T}, dims::Base.Dims) where {T<:Number} = rand(T, dims)
11-
12-
"""
13-
randnormal([::Type{T}=Float64], dims::Dims{N}) -> Array{T,N}
14-
15-
Create an array of size `dims` with random entries distributed according to the standard normal distribution.
16-
17-
See also [`randuniform`](@ref), [`randisometry`](@ref) and[`randhaar`](@ref).
18-
"""
19-
randnormal(dims::Base.Dims) = randnormal(Float64, dims)
20-
randnormal(::Type{T}, dims::Base.Dims) where {T<:Number} = randn(T, dims)
21-
221
"""
232
randisometry([::Type{T}=Float64], dims::Dims{2}) -> Array{T,2}
243
randhaar([::Type{T}=Float64], dims::Dims{2}) -> Array{T,2}
@@ -29,9 +8,18 @@ See also [`randuniform`](@ref) and [`randnormal`](@ref).
298
"""
309
randisometry(dims::Base.Dims{2}) = randisometry(Float64, dims)
3110
function randisometry(::Type{T}, dims::Base.Dims{2}) where {T<:Number}
32-
return dims[1] >= dims[2] ?
33-
MatrixAlgebra.leftorth!(randnormal(T, dims), QRpos(), 0)[1] :
34-
throw(DimensionMismatch("cannot create isometric matrix with dimensions $dims; isometry needs to be tall or square"))
11+
return randisometry(Random.default_rng(), T, dims)
12+
end
13+
function randisometry(rng::Random.AbstractRNG, ::Type{T},
14+
dims::Base.Dims{2}) where {T<:Number}
15+
return randisometry!(rng, Matrix{T}(undef, dims))
3516
end
3617

37-
const randhaar = randisometry
18+
randisometry!(A::AbstractMatrix) = randisometry!(Random.default_rng(), A)
19+
function randisometry!(rng::Random.AbstractRNG, A::AbstractMatrix)
20+
dims = size(A)
21+
dims[1] >= dims[2] ||
22+
throw(DimensionMismatch("cannot create isometric matrix with dimensions $dims; isometry needs to be tall or square"))
23+
Q, = MatrixAlgebra.leftorth!(Random.randn!(rng, A), QRpos(), 0)
24+
return copy!(A, Q)
25+
end

src/tensors/tensor.jl

Lines changed: 47 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -179,73 +179,84 @@ for (fname, felt) in ((:zeros, :zero), (:ones, :one))
179179
end
180180
end
181181

182-
for randfun in (:rand, :randn, :randexp)
183-
randfun! = Symbol(randfun, :!)
182+
for randf in (:rand, :randn, :randexp, :randisometry)
184183
_docstr = """
185-
$randfun([rng=default_rng()], [T=Float64], codomain::ProductSpace{S,N₁},
184+
$randf([rng=default_rng()], [T=Float64], codomain::ProductSpace{S,N₁},
186185
domain::ProductSpace{S,N₂}) where {S,N₁,N₂,T} -> t
187-
$randfun([rng=default_rng()], [T=Float64], codomain ← domain) -> t
186+
$randf([rng=default_rng()], [T=Float64], codomain ← domain) -> t
188187
189-
Generate a tensor `t` with entries generated by `$randfun`.
188+
Generate a tensor `t` with entries generated by `$randf`.
189+
190+
See also [`($randf)!`](@ref).
190191
"""
191192
_docstr! = """
192-
$randfun!([rng=default_rng()], t::AbstractTensorMap) -> t
193+
$(randf)!([rng=default_rng()], t::AbstractTensorMap) -> t
193194
194-
Fill the tensor `t` with entries generated by `$randfun!`.
195+
Fill the tensor `t` with entries generated by `$(randf)!`.
196+
197+
See also [`($randf)`](@ref).
195198
"""
196199

200+
if randf != :randisometry
201+
randfun = GlobalRef(Random, randf)
202+
randfun! = GlobalRef(Random, Symbol(randf, :!))
203+
else
204+
randfun = randf
205+
randfun! = Symbol(randf, :!)
206+
end
207+
197208
@eval begin
198-
@doc $_docstr Random.$randfun(::Type, ::HomSpace)
199-
@doc $_docstr! Random.$randfun!(::Type, ::HomSpace)
209+
@doc $_docstr $randfun(::Type, ::HomSpace)
210+
@doc $_docstr! $randfun!(::Type, ::HomSpace)
200211

201212
# converting `codomain` and `domain` into `HomSpace`
202-
function Random.$randfun(codomain::TensorSpace{S},
203-
domain::TensorSpace{S}) where {S<:IndexSpace}
204-
return Random.$randfun(codomain domain)
213+
function $randfun(codomain::TensorSpace{S},
214+
domain::TensorSpace{S}) where {S<:IndexSpace}
215+
return $randfun(codomain domain)
205216
end
206-
function Random.$randfun(::Type{T}, codomain::TensorSpace{S},
207-
domain::TensorSpace{S}) where {T,S<:IndexSpace}
208-
return Random.$randfun(T, codomain domain)
217+
function $randfun(::Type{T}, codomain::TensorSpace{S},
218+
domain::TensorSpace{S}) where {T,S<:IndexSpace}
219+
return $randfun(T, codomain domain)
209220
end
210-
function Random.$randfun(rng::Random.AbstractRNG, ::Type{T},
211-
codomain::TensorSpace{S},
212-
domain::TensorSpace{S}) where {T,S<:IndexSpace}
213-
return Random.$randfun(rng, T, codomain domain)
221+
function $randfun(rng::Random.AbstractRNG, ::Type{T},
222+
codomain::TensorSpace{S},
223+
domain::TensorSpace{S}) where {T,S<:IndexSpace}
224+
return $randfun(rng, T, codomain domain)
214225
end
215226

216227
# accepting single `TensorSpace`
217-
Random.$randfun(codomain::TensorSpace) = Random.$randfun(codomain one(codomain))
218-
function Random.$randfun(::Type{T}, codomain::TensorSpace) where {T}
219-
return Random.$randfun(T, codomain one(codomain))
228+
$randfun(codomain::TensorSpace) = $randfun(codomain one(codomain))
229+
function $randfun(::Type{T}, codomain::TensorSpace) where {T}
230+
return $randfun(T, codomain one(codomain))
220231
end
221-
function Random.$randfun(rng::Random.AbstractRNG, ::Type{T},
222-
codomain::TensorSpace) where {T}
223-
return Random.$randfun(rng, T, codomain one(domain))
232+
function $randfun(rng::Random.AbstractRNG, ::Type{T},
233+
codomain::TensorSpace) where {T}
234+
return $randfun(rng, T, codomain one(domain))
224235
end
225236

226237
# filling in default eltype
227-
Random.$randfun(V::TensorMapSpace) = Random.$randfun(Float64, V)
228-
function Random.$randfun(rng::Random.AbstractRNG, V::TensorMapSpace)
229-
return Random.$randfun(rng, Float64, V)
238+
$randfun(V::TensorMapSpace) = $randfun(Float64, V)
239+
function $randfun(rng::Random.AbstractRNG, V::TensorMapSpace)
240+
return $randfun(rng, Float64, V)
230241
end
231242

232243
# filling in default rng
233-
function Random.$randfun(::Type{T}, V::TensorMapSpace) where {T}
234-
return Random.$randfun(Random.default_rng(), T, V)
244+
function $randfun(::Type{T}, V::TensorMapSpace) where {T}
245+
return $randfun(Random.default_rng(), T, V)
235246
end
236-
Random.$randfun!(t::AbstractTensorMap) = Random.$randfun!(Random.default_rng(), t)
247+
$randfun!(t::AbstractTensorMap) = $randfun!(Random.default_rng(), t)
237248

238249
# implementation
239-
function Random.$randfun(rng::Random.AbstractRNG, ::Type{T},
240-
V::TensorMapSpace) where {T}
250+
function $randfun(rng::Random.AbstractRNG, ::Type{T},
251+
V::TensorMapSpace) where {T}
241252
t = TensorMap{T}(undef, V)
242-
Random.$randfun!(rng, t)
253+
$randfun!(rng, t)
243254
return t
244255
end
245256

246-
function Random.$randfun!(rng::Random.AbstractRNG, t::AbstractTensorMap)
257+
function $randfun!(rng::Random.AbstractRNG, t::AbstractTensorMap)
247258
for (_, b) in blocks(t)
248-
Random.$randfun!(rng, b)
259+
$randfun!(rng, b)
249260
end
250261
return t
251262
end

test/tensors.jl

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -308,12 +308,25 @@ for V in spacelist
308308
@test HrA12array convert(Array, HrA12)
309309
end
310310
end
311+
@timedtestset "Multiplication of isometries: test properties" begin
312+
W2 = V4 V5
313+
W1 = W2 (oneunit(V1) oneunit(V1))
314+
for T in (Float64, ComplexF64)
315+
t1 = randisometry(T, W1, W2)
316+
t2 = randisometry(T, W2 W2)
317+
@test t1' * t1 one(t2)
318+
@test t2' * t2 one(t2)
319+
@test t2 * t2' one(t2)
320+
P = t1 * t1'
321+
@test P * P P
322+
end
323+
end
311324
@timedtestset "Multiplication and inverse: test compatibility" begin
312325
W1 = V1 V2 V3
313326
W2 = V4 V5
314327
for T in (Float64, ComplexF64)
315328
t1 = rand(T, W1, W1)
316-
t2 = rand(T, W2, W2)
329+
t2 = rand(T, W2 W2)
317330
t = rand(T, W1, W2)
318331
@test t1 * (t1 \ t) t
319332
@test (t / t2) * t2 t
@@ -331,9 +344,9 @@ for V in spacelist
331344
W1 = V1 V2 V3
332345
W2 = V4 V5
333346
for T in (Float32, Float64, ComplexF32, ComplexF64)
334-
t1 = rand(T, W1, W1)
347+
t1 = rand(T, W1 W1)
335348
t2 = rand(T, W2, W2)
336-
t = rand(T, W1, W2)
349+
t = rand(T, W1 W2)
337350
d1 = dim(W1)
338351
d2 = dim(W2)
339352
At1 = reshape(convert(Array, t1), d1, d1)

0 commit comments

Comments
 (0)