@@ -36,7 +36,7 @@ function rand(W::Haar, n::Int, doCorrection::Int=1)
3636 else
3737 error (string (" beta = " ,beta, " not implemented." ))
3838 end
39- q* diagm ( 0 => L)
39+ q* Diagonal ( L)
4040 elseif doCorrection== 2
4141 if beta== 1
4242 L= sign .(diag (r))
@@ -46,7 +46,7 @@ function rand(W::Haar, n::Int, doCorrection::Int=1)
4646 else
4747 error (string (" beta = " ,beta, " not implemented." ))
4848 end
49- q* diagm ( 0 => L)
49+ q* Diagonal ( L)
5050 end
5151end
5252
@@ -81,35 +81,58 @@ for (s, elty) in (("dlarfg_", Float64),
8181 end
8282end
8383
84- """
85- Stewarts algorithm for n^2 orthogonal random matrix
86- """
87- function Stewart (:: Type{Float64} , n)
88- τ = Array {Float64} (undef, n)
89- H = randn (n, n)
9084
91- pτ = pointer (τ)
92- pβ = pointer (H)
93- pH = pointer (H, 2 )
85+ import Base. size
86+ import LinearAlgebra: lmul!, rmul!, QRPackedQ, Diagonal, Adjoint
9487
95- for i = 0 : n- 2
96- larfg! (n - i, pβ + (n + 1 )* 8 i, pH + (n + 1 )* 8 i, 1 , pτ + 8 i)
97- end
98- LinearAlgebra. QRPackedQ (H,τ)
88+
89+
90+ struct StewartQ{T,S<: AbstractMatrix{T} ,C<: AbstractVector{T} ,D<: AbstractVector{T} } <: LinearAlgebra.AbstractQ{T}
91+ factors:: S
92+ τ:: C
93+ signs:: D
9994end
95+ size (Q:: StewartQ , dim:: Integer ) = size (Q. factors, dim == 2 ? 1 : dim)
96+ size (Q:: StewartQ ) = (n = size (Q. factors, 1 ); (n, n))
10097
101- function Stewart (:: Type{ComplexF64} , n)
102- τ = Array {ComplexF64} (undef, n)
103- H = complex .(randn (n, n), randn (n,n))
98+ lmul! (A:: StewartQ , B:: AbstractVecOrMat ) = lmul! (QRPackedQ (A. factors,A. τ), lmul! (Diagonal (A. signs), B))
99+ rmul! (A:: AbstractVecOrMat , B:: StewartQ ) = rmul! (rmul! (A, QRPackedQ (B. factors,B. τ)), Diagonal (B. signs))
100+
101+ @static if VERSION ≥ v " 1.10"
102+ import LinearAlgebra. AdjointQ
103+ lmul! (adjA:: AdjointQ{<:Any,<:StewartQ} , B:: AbstractVecOrMat ) =
104+ lmul! (Diagonal (adjA. Q. signs), lmul! (QRPackedQ (adjA. Q. factors, adjA. Q. τ)' , B))
105+ rmul! (A:: AbstractVecOrMat , adjB:: AdjointQ{<:Any,<:StewartQ} ) =
106+ rmul! (rmul! (A, Diagonal (adjB. Q. signs)), QRPackedQ (adjB. Q. factors, adjB. Q. τ)' )
107+ else
108+ lmul! (adjA:: Adjoint{<:Any,<:StewartQ} , B:: AbstractVecOrMat ) =
109+ lmul! (Diagonal (adjA. parent. signs), lmul! (QRPackedQ (adjA. parent. factors, adjA. parent. τ)' , B))
110+ rmul! (A:: AbstractVecOrMat , adjB:: Adjoint{<:Any,<:StewartQ} ) =
111+ rmul! (rmul! (A, Diagonal (adjB. parent. signs)), QRPackedQ (adjB. parent. factors,adjB. parent. τ)' )
112+ end
113+
114+ StewartQ {T} (Q:: StewartQ ) where {T} = StewartQ (convert (AbstractMatrix{T}, Q. factors), convert (Vector{T}, Q. τ), convert (Vector{T}, Q. signs))
115+ AbstractMatrix {T} (Q:: StewartQ{T} ) where {T} = Q
116+ AbstractMatrix {T} (Q:: StewartQ ) where {T} = StewartQ {T} (Q)
117+
118+ """
119+ Stewart's algorithm for sampling orthogonal/unitary random matrices in time O(n^2)
120+ """
121+ function Stewart (:: Type{T} , n) where {T<: Union{Float64,ComplexF64} }
122+ τ = Array {T} (undef, n)
123+ signs = Vector {T} (undef, n)
124+ H = randn (T, n, n)
104125
105126 pτ = pointer (τ)
106127 pβ = pointer (H)
107128 pH = pointer (H, 2 )
108129
109- for i = 0 : n- 2
110- larfg! (n - i, pβ + (n + 1 )* 16 i, pH + (n + 1 )* 16 i, 1 , pτ + 16 i)
130+ incr = (T <: Real ? 1 : 2 )
131+ for i = 0 : n- 1
132+ larfg! (n - i, pβ + (n + 1 )* 8 * incr* i, pH + (n + 1 )* 8 * incr* i, 1 , pτ + 8 * incr* i)
133+ signs[i+ 1 ] = sign (real (H[i+ 1 , i+ 1 ]))
111134 end
112- LinearAlgebra . QRPackedQ (H,τ )
135+ return StewartQ (H, τ, signs )
113136end
114137
115138export randfast
0 commit comments