1
1
# define our own struct since LinearAlgebra.QR are restricted to Matrix
2
- struct QR{Q,R}
2
+ struct QR{Q,R,P }
3
3
Q:: Q
4
4
R:: R
5
+ p:: P
5
6
end
6
7
7
8
# iteration for destructuring into components
8
9
Base. iterate (S:: QR ) = (S. Q, Val (:R ))
9
- Base. iterate (S:: QR , :: Val{:R} ) = (S. R, Val (:done ))
10
+ Base. iterate (S:: QR , :: Val{:R} ) = (S. R, Val (:p ))
11
+ Base. iterate (S:: QR , :: Val{:p} ) = (S. p, Val (:done ))
10
12
Base. iterate (S:: QR , :: Val{:done} ) = nothing
11
13
12
14
"""
33
35
```
34
36
"""
35
37
@inline function qr (A:: StaticMatrix , pivot:: Union{Val{false}, Val{true}} = Val (false ))
36
- Q, R = _qr (Size (A), A, pivot)
37
- return QR (Q, R)
38
+ QRp = _qr (Size (A), A, pivot)
39
+ if length (QRp) === 2
40
+ # create an identity permutation since that is cheap,
41
+ # and much safer since, in the case of isbits types, we can't
42
+ # safely leave the field undefined.
43
+ p = identity_perm (QRp[2 ])
44
+ return QR (QRp[1 ], QRp[2 ], p)
45
+ else # length(QRp) === 3
46
+ return QR (QRp[1 ], QRp[2 ], QRp[3 ])
47
+ end
48
+ end
49
+
50
+ function identity_perm (R:: StaticMatrix{N,M,T} ) where {N,M,T}
51
+ return similar_type (R, Int, Size ((M,)))(ntuple (x -> x, Val {M} ()))
38
52
end
39
53
40
54
_qreltype (:: Type{T} ) where T = typeof (zero (T)/ sqrt (abs2 (one (T))))
@@ -45,12 +59,12 @@ _qreltype(::Type{T}) where T = typeof(zero(T)/sqrt(abs2(one(T))))
45
59
SizeQ = Size ( sA[1 ], diagsize (Size (A)) )
46
60
SizeR = Size ( diagsize (Size (A)), sA[2 ] )
47
61
48
- if pivot == Val ( true )
62
+ if pivot === Val{ true }
49
63
return quote
50
64
@_inline_meta
51
65
Q0, R0, p0 = qr (Matrix (A), pivot)
52
66
T = _qreltype (TA)
53
- return similar_type (A, T, $ (SizeQ))(Q0 ),
67
+ return similar_type (A, T, $ (SizeQ))(Matrix (Q0) ),
54
68
similar_type (A, T, $ (SizeR))(R0),
55
69
similar_type (A, Int, $ (Size (sA[2 ])))(p0)
56
70
end
0 commit comments