@@ -36,7 +36,7 @@ function rand(W::Haar, n::Int, doCorrection::Int=1)
36
36
else
37
37
error (string (" beta = " ,beta, " not implemented." ))
38
38
end
39
- q* diagm ( 0 => L)
39
+ q* Diagonal ( L)
40
40
elseif doCorrection== 2
41
41
if beta== 1
42
42
L= sign .(diag (r))
@@ -46,7 +46,7 @@ function rand(W::Haar, n::Int, doCorrection::Int=1)
46
46
else
47
47
error (string (" beta = " ,beta, " not implemented." ))
48
48
end
49
- q* diagm ( 0 => L)
49
+ q* Diagonal ( L)
50
50
end
51
51
end
52
52
@@ -81,35 +81,58 @@ for (s, elty) in (("dlarfg_", Float64),
81
81
end
82
82
end
83
83
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)
90
84
91
- pτ = pointer (τ)
92
- pβ = pointer (H)
93
- pH = pointer (H, 2 )
85
+ import Base. size
86
+ import LinearAlgebra: lmul!, rmul!, QRPackedQ, Diagonal, Adjoint
94
87
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
99
94
end
95
+ size (Q:: StewartQ , dim:: Integer ) = size (Q. factors, dim == 2 ? 1 : dim)
96
+ size (Q:: StewartQ ) = (n = size (Q. factors, 1 ); (n, n))
100
97
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)
104
125
105
126
pτ = pointer (τ)
106
127
pβ = pointer (H)
107
128
pH = pointer (H, 2 )
108
129
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 ]))
111
134
end
112
- LinearAlgebra . QRPackedQ (H,τ )
135
+ return StewartQ (H, τ, signs )
113
136
end
114
137
115
138
export randfast
0 commit comments