|
1 | | -@inline transpose(A::LinearAlgebra.LowerTriangular{<:Any,<:StaticMatrix}) = |
2 | | - LinearAlgebra.UpperTriangular(transpose(A.data)) |
3 | | -@inline adjoint(A::LinearAlgebra.LowerTriangular{<:Any,<:StaticMatrix}) = |
4 | | - LinearAlgebra.UpperTriangular(adjoint(A.data)) |
5 | | -@inline transpose(A::LinearAlgebra.UpperTriangular{<:Any,<:StaticMatrix}) = |
6 | | - LinearAlgebra.LowerTriangular(transpose(A.data)) |
7 | | -@inline adjoint(A::LinearAlgebra.UpperTriangular{<:Any,<:StaticMatrix}) = |
8 | | - LinearAlgebra.LowerTriangular(adjoint(A.data)) |
| 1 | +@inline transpose(A::LowerTriangular{<:Any,<:StaticMatrix}) = |
| 2 | + UpperTriangular(transpose(A.data)) |
| 3 | +@inline adjoint(A::LowerTriangular{<:Any,<:StaticMatrix}) = |
| 4 | + UpperTriangular(adjoint(A.data)) |
| 5 | +@inline transpose(A::UnitLowerTriangular{<:Any,<:StaticMatrix}) = |
| 6 | + UnitUpperTriangular(transpose(A.data)) |
| 7 | +@inline adjoint(A::UnitLowerTriangular{<:Any,<:StaticMatrix}) = |
| 8 | + UnitUpperTriangular(adjoint(A.data)) |
| 9 | +@inline transpose(A::UpperTriangular{<:Any,<:StaticMatrix}) = |
| 10 | + LowerTriangular(transpose(A.data)) |
| 11 | +@inline adjoint(A::UpperTriangular{<:Any,<:StaticMatrix}) = |
| 12 | + LowerTriangular(adjoint(A.data)) |
| 13 | +@inline transpose(A::UnitUpperTriangular{<:Any,<:StaticMatrix}) = |
| 14 | + UnitLowerTriangular(transpose(A.data)) |
| 15 | +@inline adjoint(A::UnitUpperTriangular{<:Any,<:StaticMatrix}) = |
| 16 | + UnitLowerTriangular(adjoint(A.data)) |
9 | 17 | @inline Base.:*(A::Adjoint{<:Any,<:StaticVector}, B::LinearAlgebra.AbstractTriangular{<:Any,<:StaticMatrix}) = |
10 | 18 | adjoint(adjoint(B) * adjoint(A)) |
11 | 19 | @inline Base.:*(A::Transpose{<:Any,<:StaticVector}, B::LinearAlgebra.AbstractTriangular{<:Any,<:StaticMatrix}) = |
|
15 | 23 | @inline Base.:*(A::LinearAlgebra.AbstractTriangular{<:Any,<:StaticMatrix}, B::Transpose{<:Any,<:StaticVector}) = |
16 | 24 | transpose(transpose(B) * transpose(A)) |
17 | 25 |
|
18 | | -const StaticULT = Union{UpperTriangular{<:Any,<:StaticMatrix},LowerTriangular{<:Any,<:StaticMatrix}} |
| 26 | +const StaticULT{TA} = Union{UpperTriangular{TA,<:StaticMatrix},LowerTriangular{TA,<:StaticMatrix},UnitUpperTriangular{TA,<:StaticMatrix},UnitLowerTriangular{TA,<:StaticMatrix}} |
19 | 27 |
|
20 | | -@inline Base.:\(A::StaticULT, B::StaticVecOrMat) = _A_ldiv_B(Size(A), Size(B), A, B) |
| 28 | +@inline Base.:\(A::StaticULT, B::StaticVecOrMatLike) = _A_ldiv_B(Size(A), Size(B), A, B) |
| 29 | +@inline Base.:/(A::StaticVecOrMatLike, B::StaticULT) = transpose(transpose(B) \ transpose(A)) |
21 | 30 |
|
22 | | -@generated function _A_ldiv_B(::Size{sa}, ::Size{sb}, A::UpperTriangular{<:TA,<:StaticMatrix}, B::StaticVecOrMat{TB}) where {sa,sb,TA,TB} |
| 31 | +@generated function _A_ldiv_B(::Size{sa}, ::Size{sb}, A::StaticULT{TA}, B::StaticVecOrMatLike{TB}) where {sa,sb,TA,TB} |
23 | 32 | m = sb[1] |
24 | 33 | n = length(sb) > 1 ? sb[2] : 1 |
25 | 34 | if m != sa[1] |
26 | 35 | throw(DimensionMismatch("right hand side B needs first dimension of size $(sa[1]), has size $m")) |
27 | 36 | end |
28 | 37 |
|
29 | 38 | X = [Symbol("X_$(i)_$(j)") for i = 1:m, j = 1:n] |
30 | | - init = [:($(X[i,j]) = B[$(LinearIndices(sb)[i, j])]) for i = 1:m, j = 1:n] |
31 | 39 |
|
32 | | - code = Expr(:block) |
33 | | - for k = 1:n |
34 | | - for j = m:-1:1 |
35 | | - if k == 1 |
36 | | - push!(code.args, :(A.data[$(LinearIndices(sa)[j, j])] == zero(A.data[$(LinearIndices(sa)[j, j])]) && throw(LinearAlgebra.SingularException($j)))) |
| 40 | + isunitdiag = A <: Union{UnitUpperTriangular, UnitLowerTriangular} |
| 41 | + isupper = A <: Union{UnitUpperTriangular, UpperTriangular} |
| 42 | + |
| 43 | + j_range = isupper ? (m:-1:1) : (1:m) |
| 44 | + |
| 45 | + init = gen_by_access(B, :B) do access_b |
| 46 | + init_exprs = [:($(X[i,j]) = $(uplo_access(sb, :b, i, j, access_b))) for i = 1:m, j = 1:n] |
| 47 | + code = Expr(:block, init_exprs...) |
| 48 | + for k = 1:n |
| 49 | + for j = j_range |
| 50 | + if !isunitdiag && k == 1 |
| 51 | + push!(code.args, :(A.data[$(LinearIndices(sa)[j, j])] == zero(A.data[$(LinearIndices(sa)[j, j])]) && throw(LinearAlgebra.SingularException($j)))) |
| 52 | + end |
| 53 | + if isunitdiag |
| 54 | + push!(code.args, :($(X[j,k]) = oneunit(TA) \ $(X[j,k]))) |
| 55 | + else |
| 56 | + push!(code.args, :($(X[j,k]) = A.data[$(LinearIndices(sa)[j, j])] \ $(X[j,k]))) |
| 57 | + end |
| 58 | + i_range = isupper ? (j-1:-1:1) : (j+1:m) |
| 59 | + for i = i_range |
| 60 | + push!(code.args, :($(X[i,k]) -= A.data[$(LinearIndices(sa)[i, j])]*$(X[j,k]))) |
| 61 | + end |
37 | 62 | end |
38 | | - push!(code.args, :($(X[j,k]) = A.data[$(LinearIndices(sa)[j, j])] \ $(X[j,k]))) |
39 | | - for i = j-1:-1:1 |
40 | | - push!(code.args, :($(X[i,k]) -= A.data[$(LinearIndices(sa)[i, j])]*$(X[j,k]))) |
41 | | - end |
42 | | - end |
43 | | - end |
44 | | - |
45 | | - return quote |
46 | | - @_inline_meta |
47 | | - @inbounds $(Expr(:block, init...)) |
48 | | - @inbounds $code |
49 | | - TAB = typeof((zero(TA)*zero(TB) + zero(TA)*zero(TB))/one(TA)) |
50 | | - @inbounds return similar_type(B, TAB)(tuple($(X...))) |
51 | | - end |
52 | | -end |
53 | | - |
54 | | -@generated function _A_ldiv_B(::Size{sa}, ::Size{sb}, A::LowerTriangular{<:TA,<:StaticMatrix}, B::StaticVecOrMat{TB}) where {sa,sb,TA,TB} |
55 | | - m = sb[1] |
56 | | - n = length(sb) > 1 ? sb[2] : 1 |
57 | | - if m != sa[1] |
58 | | - throw(DimensionMismatch("right hand side B needs first dimension of size $(sa[1]), has size $m")) |
59 | | - end |
60 | | - |
61 | | - X = [Symbol("X_$(i)_$(j)") for i = 1:m, j = 1:n] |
62 | | - init = [:($(X[i,j]) = B[$(LinearIndices(sb)[i, j])]) for i = 1:m, j = 1:n] |
63 | | - |
64 | | - code = Expr(:block) |
65 | | - for k = 1:n |
66 | | - for j = 1:m |
67 | | - if k == 1 |
68 | | - push!(code.args, :(A.data[$(LinearIndices(sa)[j, j])] == zero(A.data[$(LinearIndices(sa)[j, j])]) && throw(LinearAlgebra.SingularException($j)))) |
69 | | - end |
70 | | - push!(code.args, :($(X[j,k]) = A.data[$(LinearIndices(sa)[j, j])] \ $(X[j,k]))) |
71 | | - for i = j+1:m |
72 | | - push!(code.args, :($(X[i,k]) -= A.data[$(LinearIndices(sa)[i, j])]*$(X[j,k]))) |
73 | | - end |
74 | | - end |
75 | | - end |
76 | | - |
77 | | - return quote |
78 | | - @_inline_meta |
79 | | - @inbounds $(Expr(:block, init...)) |
80 | | - @inbounds $code |
81 | | - TAB = typeof((zero(TA)*zero(TB) + zero(TA)*zero(TB))/one(TA)) |
82 | | - @inbounds return similar_type(B, TAB)(tuple($(X...))) |
83 | | - end |
84 | | -end |
85 | | - |
86 | | -@generated function _Ac_ldiv_B(::Size{sa}, ::Size{sb}, A::UpperTriangular{<:TA,<:StaticMatrix}, B::StaticVecOrMat{TB}) where {sa,sb,TA,TB} |
87 | | - m = sb[1] |
88 | | - n = length(sb) > 1 ? sb[2] : 1 |
89 | | - if m != sa[1] |
90 | | - throw(DimensionMismatch("right hand side B needs first dimension of size $(sa[1]), has size $m")) |
91 | | - end |
92 | | - |
93 | | - X = [Symbol("X_$(i)_$(j)") for i = 1:m, j = 1:n] |
94 | | - |
95 | | - code = Expr(:block) |
96 | | - for k = 1:n |
97 | | - for j = 1:m |
98 | | - ex = :(B[$(LinearIndices(sb)[j, k])]) |
99 | | - for i = 1:j-1 |
100 | | - ex = :($ex - A.data[$(LinearIndices(sa)[i, j])]'*$(X[i,k])) |
101 | | - end |
102 | | - if k == 1 |
103 | | - push!(code.args, :(A.data[$(LinearIndices(sa)[j, j])] == zero(A.data[$(LinearIndices(sa)[j, j])]) && throw(LinearAlgebra.SingularException($j)))) |
104 | | - end |
105 | | - push!(code.args, :($(X[j,k]) = A.data[$(LinearIndices(sa)[j, j])]' \ $ex)) |
106 | | - end |
107 | | - end |
108 | | - |
109 | | - return quote |
110 | | - @_inline_meta |
111 | | - @inbounds $code |
112 | | - TAB = typeof((zero(TA)*zero(TB) + zero(TA)*zero(TB))/one(TA)) |
113 | | - @inbounds return similar_type(B, TAB)(tuple($(X...))) |
114 | | - end |
115 | | -end |
116 | | - |
117 | | -@generated function _At_ldiv_B(::Size{sa}, ::Size{sb}, A::UpperTriangular{<:TA,<:StaticMatrix}, B::StaticVecOrMat{TB}) where {sa,sb,TA,TB} |
118 | | - m = sb[1] |
119 | | - n = length(sb) > 1 ? sb[2] : 1 |
120 | | - if m != sa[1] |
121 | | - throw(DimensionMismatch("right hand side B needs first dimension of size $(sa[1]), has size $m")) |
122 | | - end |
123 | | - |
124 | | - X = [Symbol("X_$(i)_$(j)") for i = 1:m, j = 1:n] |
125 | | - |
126 | | - code = Expr(:block) |
127 | | - for k = 1:n |
128 | | - for j = 1:m |
129 | | - ex = :(B[$(LinearIndices(sb)[j, k])]) |
130 | | - for i = 1:j-1 |
131 | | - ex = :($ex - A.data[$(LinearIndices(sa)[i, j])]*$(X[i,k])) |
132 | | - end |
133 | | - if k == 1 |
134 | | - push!(code.args, :(A.data[$(LinearIndices(sa)[j, j])] == zero(A.data[$(LinearIndices(sa)[j, j])]) && throw(LinearAlgebra.SingularException($j)))) |
135 | | - end |
136 | | - push!(code.args, :($(X[j,k]) = A.data[$(LinearIndices(sa)[j, j])] \ $ex)) |
137 | | - end |
138 | | - end |
139 | | - |
140 | | - return quote |
141 | | - @_inline_meta |
142 | | - @inbounds $code |
143 | | - TAB = typeof((zero(TA)*zero(TB) + zero(TA)*zero(TB))/one(TA)) |
144 | | - @inbounds return similar_type(B, TAB)(tuple($(X...))) |
145 | | - end |
146 | | -end |
147 | | - |
148 | | -@generated function _Ac_ldiv_B(::Size{sa}, ::Size{sb}, A::LowerTriangular{<:TA,<:StaticMatrix}, B::StaticVecOrMat{TB}) where {sa,sb,TA,TB} |
149 | | - m = sb[1] |
150 | | - n = length(sb) > 1 ? sb[2] : 1 |
151 | | - if m != sa[1] |
152 | | - throw(DimensionMismatch("right hand side B needs first dimension of size $(sa[1]), has size $m")) |
153 | | - end |
154 | | - |
155 | | - X = [Symbol("X_$(i)_$(j)") for i = 1:m, j = 1:n] |
156 | | - |
157 | | - code = Expr(:block) |
158 | | - for k = 1:n |
159 | | - for j = m:-1:1 |
160 | | - ex = :(B[$(LinearIndices(sb)[j, k])]) |
161 | | - for i = m:-1:j+1 |
162 | | - ex = :($ex - A.data[$(LinearIndices(sa)[i, j])]'*$(X[i,k])) |
163 | | - end |
164 | | - if k == 1 |
165 | | - push!(code.args, :(A.data[$(LinearIndices(sa)[j, j])] == zero(A.data[$(LinearIndices(sa)[j, j])]) && throw(LinearAlgebra.SingularException($j)))) |
166 | | - end |
167 | | - push!(code.args, :($(X[j,k]) = A.data[$(LinearIndices(sa)[j, j])]' \ $ex)) |
168 | | - end |
169 | | - end |
170 | | - |
171 | | - return quote |
172 | | - @_inline_meta |
173 | | - @inbounds $code |
174 | | - TAB = typeof((zero(TA)*zero(TB) + zero(TA)*zero(TB))/one(TA)) |
175 | | - @inbounds return similar_type(B, TAB)(tuple($(X...))) |
176 | | - end |
177 | | -end |
178 | | - |
179 | | -@generated function _At_ldiv_B(::Size{sa}, ::Size{sb}, A::LowerTriangular{<:TA,<:StaticMatrix}, B::StaticVecOrMat{TB}) where {sa,sb,TA,TB} |
180 | | - m = sb[1] |
181 | | - n = length(sb) > 1 ? sb[2] : 1 |
182 | | - if m != sa[1] |
183 | | - throw(DimensionMismatch("right hand side B needs first dimension of size $(sa[1]), has size $m")) |
184 | | - end |
185 | | - |
186 | | - X = [Symbol("X_$(i)_$(j)") for i = 1:m, j = 1:n] |
187 | | - |
188 | | - code = Expr(:block) |
189 | | - for k = 1:n |
190 | | - for j = m:-1:1 |
191 | | - ex = :(B[$(LinearIndices(sb)[j, k])]) |
192 | | - for i = m:-1:j+1 |
193 | | - ex = :($ex - A.data[$(LinearIndices(sa)[i, j])]*$(X[i,k])) |
194 | | - end |
195 | | - if k == 1 |
196 | | - push!(code.args, :(A.data[$(LinearIndices(sa)[j, j])] == zero(A.data[$(LinearIndices(sa)[j, j])]) && throw(LinearAlgebra.SingularException($j)))) |
197 | | - end |
198 | | - push!(code.args, :($(X[j,k]) = A.data[$(LinearIndices(sa)[j, j])] \ $ex)) |
199 | 63 | end |
| 64 | + return code |
200 | 65 | end |
201 | 66 |
|
202 | 67 | return quote |
203 | 68 | @_inline_meta |
204 | | - @inbounds $code |
| 69 | + b = mul_parent(B) |
| 70 | + Tb = TB |
| 71 | + @inbounds $init |
205 | 72 | TAB = typeof((zero(TA)*zero(TB) + zero(TA)*zero(TB))/one(TA)) |
206 | 73 | @inbounds return similar_type(B, TAB)(tuple($(X...))) |
207 | 74 | end |
|
0 commit comments