Skip to content

Commit 9b6427f

Browse files
committed
LU-based solve for matrix sizes 4:14
1 parent 5f7ef30 commit 9b6427f

File tree

2 files changed

+33
-5
lines changed

2 files changed

+33
-5
lines changed

src/solve.jl

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
@inline (\)(a::StaticMatrix, b::StaticVector) = solve(Size(a), Size(b), a, b)
2-
3-
# TODO: Ineffecient but requires some infrastructure (e.g. LU or QR) to make efficient so we fall back on inv for now
4-
@inline solve(::Size, ::Size, a, b) = inv(a) * b
1+
@inline (\)(a::StaticMatrix, b::StaticVecOrMat) = solve(Size(a), Size(b), a, b)
52

63
@inline function solve(::Size{(1,1)}, ::Size{(1,)}, a::StaticMatrix{<:Any, <:Any, Ta}, b::StaticVector{<:Any, Tb}) where {Ta, Tb}
74
@inbounds return similar_type(b, typeof(a[1] \ b[1]))(a[1] \ b[1])
@@ -28,3 +25,23 @@ end
2825
(a[1,2]*a[3,1] - a[1,1]*a[3,2])*b[2] +
2926
(a[1,1]*a[2,2] - a[1,2]*a[2,1])*b[3]) / d )
3027
end
28+
29+
@generated function solve(::Size{Sa}, ::Size{Sb}, a::StaticMatrix{<:Any, <:Any, Ta}, b::StaticVecOrMat{Tb}) where {Sa, Sb, Ta, Tb}
30+
if Sa[end] != Sb[1]
31+
throw(DimensionMismatch("right hand side B needs first dimension of size $(Sa[end]), has size $Sb"))
32+
end
33+
LinearAlgebra.checksquare(a)
34+
if prod(Sa) 14*14
35+
quote
36+
@_inline_meta
37+
L, U, p = lu(a)
38+
U \ (L \ $(length(Sb) > 1 ? :(b[p,:]) : :(b[p])))
39+
end
40+
else
41+
quote
42+
@_inline_meta
43+
T = typeof((one(Ta)*zero(Tb) + one(Ta)*zero(Tb))/one(Ta))
44+
similar_type(b, T)(Matrix(a) \ b)
45+
end
46+
end
47+
end

test/solve.jl

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using StaticArrays, Compat.Test
22

33
@testset "Solving linear system" begin
4-
@testset "Problem size: $n x $n. Matrix type: $m. Element type: $elty" for n in (1,2,3,4),
4+
@testset "Problem size: $n x $n. Matrix type: $m. Element type: $elty" for n in (1,2,3,4,5,14,15,50),
55
(m, v) in ((SMatrix{n,n}, SVector{n}), (MMatrix{n,n}, MVector{n})),
66
elty in (Float64, Int)
77

@@ -16,3 +16,14 @@ using StaticArrays, Compat.Test
1616
@test_throws DimensionMismatch m1\v
1717
@test_throws DimensionMismatch m1\m2
1818
end
19+
20+
@testset "Solving linear system (multiple RHS)" begin
21+
@testset "Problem size: $n x $n. Matrix type: $m1. Element type: $elty" for n in (1,2,3,4,5,14,15,50),
22+
(m1, m2) in ((SMatrix{n,n}, SMatrix{n,2}), (MMatrix{n,n}, MMatrix{n,2})),
23+
elty in (Float64, Int)
24+
25+
A = elty.(rand(-99:2:99, n, n))
26+
b = A * elty.(rand(2:5, n, 2))
27+
@test m1(A)\m2(b) A\b
28+
end
29+
end

0 commit comments

Comments
 (0)