Skip to content

Commit 592b73f

Browse files
authored
Fix mat * vec with non-commutative numbers (#413)
* Fix mat * vec with non-commutative numbers * Update banded * diagonal * Change some lmul to rmul
1 parent ce4519d commit 592b73f

File tree

5 files changed

+40
-19
lines changed

5 files changed

+40
-19
lines changed

Project.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "BandedMatrices"
22
uuid = "aae01518-5342-5314-be14-df237901396f"
3-
version = "1.3"
3+
version = "1.3.1"
44

55
[deps]
66
ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a"
@@ -24,6 +24,7 @@ GenericLinearAlgebra = "0.3"
2424
InfiniteArrays = "0.12, 0.13"
2525
LinearAlgebra = "1.6"
2626
PrecompileTools = "1"
27+
Quaternions = "0.7"
2728
Random = "1.6"
2829
SparseArrays = "1.6"
2930
Test = "1.6"
@@ -34,9 +35,10 @@ Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
3435
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
3536
GenericLinearAlgebra = "14197337-ba66-59df-a3e3-ca00e7dcff7a"
3637
InfiniteArrays = "4858937d-0d70-526a-a4dd-2d5cb5dd786c"
38+
Quaternions = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0"
3739
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
3840
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
3941
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
4042

4143
[targets]
42-
test = ["Aqua", "Documenter", "GenericLinearAlgebra", "InfiniteArrays", "Random", "SparseArrays", "Test"]
44+
test = ["Aqua", "Documenter", "GenericLinearAlgebra", "InfiniteArrays", "Random", "SparseArrays", "Test", "Quaternions"]

src/BandedMatrices.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import ArrayLayouts: MemoryLayout, transposelayout, triangulardata,
2929
triangularlayout, MatLdivVec, hermitianlayout, hermitiandata,
3030
materialize, materialize!, BlasMatMulMatAdd, BlasMatMulVecAdd, BlasMatLmulVec, BlasMatLdivVec,
3131
colsupport, rowsupport, symmetricuplo, MatMulMatAdd, MatMulVecAdd,
32-
sublayout, sub_materialize, _fill_lmul!, _copy_oftype,
32+
sublayout, sub_materialize, _copy_oftype, zero!,
3333
reflector!, reflectorApply!, _copyto!, checkdimensions,
3434
_qr!, _qr, _lu!, _lu, _factorize, AbstractTridiagonalLayout, TridiagonalLayout,
3535
BidiagonalLayout, bidiagonaluplo, diagonaldata, supdiagonaldata, subdiagonaldata, copymutable_oftype_layout, dualadjoint

src/generic/matmul.jl

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ banded_gbmv!(tA, α, A, x, β, y) =
3030
=#
3131
length(y) == 0 && return y
3232
if length(x) == 0
33-
_fill_lmul!(β, y)
33+
_fill_rmul!(y, β)
3434
else
3535
xc = Base.unalias(y, x)
3636
banded_gbmv!(tA, α, A, xc, β, y)
@@ -42,15 +42,15 @@ function _banded_muladd!(α, A, x::AbstractVector, β, y)
4242
m, n = size(A)
4343
l, u = bandwidths(A)
4444
if -l > u # no bands
45-
_fill_lmul!(β, y)
45+
_fill_rmul!(y, β)
4646
elseif l < 0 # with u >= -l > 0, that is, all bands lie above the diagonal
4747
# E.g. (l,u) = (-1,2)
4848
# set lview = 0 and uview = u + l >= 0
4949
_banded_gbmv!('N', α, view(A, :, 1-l:n), view(x, 1-l:n), β, y)
5050
elseif u < 0 # with -l <= u < 0, that is, all bands lie below the diagnoal.
5151
# E.g. (l,u) = (2,-1)
5252
# set lview = l + u >= 0 and uview = 0
53-
_fill_lmul!(β, @view(y[1:-u]))
53+
_fill_rmul!(@view(y[1:-u]), β)
5454
_banded_gbmv!('N', α, view(A, 1-u:m, :), x, β, view(y, 1-u:m))
5555
y
5656
else
@@ -67,11 +67,11 @@ function _banded_muladd_row!(tA, α, At, x, β, y)
6767
n, m = size(At)
6868
u, l = bandwidths(At)
6969
if -l > u # no bands
70-
_fill_lmul!(β, y)
70+
_fill_rmul!(y, β)
7171
elseif l < 0
7272
_banded_gbmv!(tA, α, view(At, 1-l:n, :,), view(x, 1-l:n), β, y)
7373
elseif u < 0
74-
_fill_lmul!(β, @view(y[1:-u]))
74+
_fill_rmul!(@view(y[1:-u]), β)
7575
_banded_gbmv!(tA, α, view(At, :, 1-u:m), x, β, view(y, 1-u:m))
7676
y
7777
else
@@ -100,10 +100,10 @@ end
100100
@inline function materialize!(M::MatMulVecAdd{<:AbstractBandedLayout})
101101
checkdimensions(M)
102102
α,A,B,β,C = M.α,M.A,M.B,M.β,M.C
103-
_fill_lmul!(β, C)
103+
_fill_rmul!(C, β)
104104
@inbounds for j = intersect(rowsupport(A), colsupport(B))
105105
for k = colrange(A,j)
106-
C[k] += α*inbands_getindex(A,k,j)*B[j]
106+
C[k] += inbands_getindex(A,k,j) * B[j] * α
107107
end
108108
end
109109
C
@@ -113,11 +113,11 @@ end
113113
checkdimensions(M)
114114
α,At,B,β,C = M.α,M.A,M.B,M.β,M.C
115115
A = transpose(At)
116-
_fill_lmul!(β, C)
116+
_fill_rmul!(C, β)
117117

118118
@inbounds for j = rowsupport(A)
119119
for k = intersect(colrange(A,j), colsupport(B))
120-
C[j] += α*transpose(inbands_getindex(A,k,j))*B[k]
120+
C[j] += transpose(inbands_getindex(A,k,j)) * B[k] * α
121121
end
122122
end
123123
C
@@ -127,10 +127,10 @@ end
127127
checkdimensions(M)
128128
α,Ac,B,β,C = M.α,M.A,M.B,M.β,M.C
129129
A = Ac'
130-
_fill_lmul!(β, C)
130+
_fill_rmul!(C, β)
131131
@inbounds for j = rowsupport(A)
132132
for k = intersect(colrange(A,j), colsupport(B))
133-
C[j] += α*inbands_getindex(A,k,j)'*B[k]
133+
C[j] += inbands_getindex(A,k,j)' * B[k] * α
134134
end
135135
end
136136
C
@@ -227,13 +227,13 @@ end
227227

228228
function materialize!(M::MatMulMatAdd{<:DiagonalLayout{<:AbstractFillLayout},<:AbstractBandedLayout})
229229
checkdimensions(M)
230-
M.C .= (M.α * getindex_value(M.A.diag)) .* M.B .+ M.β .* M.C
230+
M.C .= getindex_value(M.A.diag) .* M.B .* M.α .+ M.C .* M.β
231231
M.C
232232
end
233233

234234
function materialize!(M::MatMulMatAdd{<:AbstractBandedLayout,<:DiagonalLayout{<:AbstractFillLayout}})
235235
checkdimensions(M)
236-
M.C .= (M.α * getindex_value(M.B.diag)) .* M.A .+ M.β .* M.C
236+
M.C .= M.A .* getindex_value(M.B.diag) .* M.α .+ M.C .* M.β
237237
M.C
238238
end
239239

@@ -244,7 +244,7 @@ function materialize!(M::MatMulMatAdd{<:BandedColumns, <:AbstractStridedLayout,
244244
α, β, A, B, C = M.α, M.β, M.A, M.B, M.C
245245

246246
if iszero(α)
247-
lmul!(β, C)
247+
rmul!(C, β)
248248
else
249249
for (colC, colB) in zip(eachcol(C), eachcol(B))
250250
mul!(colC, A, colB, α, β)
@@ -259,7 +259,7 @@ function materialize!(M::MatMulMatAdd{<:AbstractStridedLayout, <:BandedColumns,
259259
α, β, A, B, C = M.α, M.β, M.A, M.B, M.C
260260

261261
if iszero(α)
262-
lmul!(β, C)
262+
rmul!(C, β)
263263
else
264264
for (rowC, rowA) in zip(eachrow(C), eachrow(A))
265265
mul!(rowC, transpose(B), rowA, α, β)

src/generic/utils.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,7 @@ prodbandwidths(A...) = broadcast(+, bandwidths.(A)...)
2424
function sumbandwidths(A::AbstractMatrix, B::AbstractMatrix)
2525
max(bandwidth(A, 1), bandwidth(B, 1)), max(bandwidth(A, 2), bandwidth(B, 2))
2626
end
27+
28+
29+
_fill_lmul!(β, A::AbstractArray{T}) where T = iszero(β) ? zero!(A) : lmul!(β, A)
30+
_fill_rmul!(A::AbstractArray{T}, β) where T = iszero(β) ? zero!(A) : rmul!(A, β)

test/test_linalg.jl

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
using ArrayLayouts, BandedMatrices, FillArrays, LinearAlgebra, Test
1+
using ArrayLayouts
2+
using BandedMatrices
3+
using FillArrays
4+
using LinearAlgebra
5+
using Quaternions
6+
using Test
27

38
import Base.Broadcast: materialize, broadcasted
49
import BandedMatrices: BandedColumns, _BandedMatrix
@@ -109,6 +114,16 @@ ArrayLayouts.colsupport(::UnknownLayout, A::MyOneElement{<:Any,1}, _) =
109114
@test B*M Matrix(B)*M
110115
@test M*B M*Matrix(B)
111116
end
117+
@testset "non-commutative" begin
118+
B1 = BandedMatrix(0 => [quat(rand(4)...) for i in 1:3])
119+
v = [quat(rand(4)...) for i in 1:3]
120+
α, β = quat(0,1,1,0), quat(1,0,0,1)
121+
@test mul!(zero(v), B1, v, α, β) mul!(zero(v), Array(B1), v, α, β)
122+
123+
D = Diagonal(Fill(quat(rand(4)...), size(B1,2)))
124+
@test mul!(D * B1, D, B1, α, β) mul!(D * Array(B1), D, Array(B1), α, β)
125+
@test mul!(B1 * D, B1, D, α, β) mul!(Array(B1) * D, Array(B1), D, α, β)
126+
end
112127
end
113128

114129
@testset "BandedMatrix * sparse" begin

0 commit comments

Comments
 (0)