Linear Solvers
Objects of type LinearSolver are used to solve LinearSystems, i.e. we want to find $x$ for given $A$ and $y$ such that
\[ Ax = y\]
is satisfied.
A linear system can be called with[1]:
using SimpleSolvers
A = [(0. + 1e-6) 1. 2.; 3. 4. 5.; 6. 7. 8.]
y = [1., 2., 3.]
ls = LinearSystem(A, y)
update!(ls, A, y)Note that we here use the matrix:
\[A = \begin{pmatrix} 0 + \varepsilon & 1 & 2 \\ 3 & 4 & 5 \\ 6 & 7 & 8 \end{pmatrix}.\]
This matrix would be singular if we had $\varepsilon = 0$ because $2\cdot\begin{pmatrix} 3 \\ 4 \\ 5 \end{pmatrix} - \begin{pmatrix} 6 \\ 7 \\ 8 \end{pmatrix} = \begin{pmatrix} 0 \\ 1 \\ 2 \end{pmatrix}.$ So by choosing $\varepsilon = 10^{-6}$ the matrix is ill-conditioned.
We first solve LinearSystem with an lu solver (using LU and solve) in double precision and without pivoting:
lu = LU(; pivot = false)
y¹ = solve(lu, ls)3-element StaticArraysCore.SizedVector{3, Float64, Vector{Float64}} with indices SOneTo(3):
0.0
-0.33333333333333326
0.6666666666666666We check the result:
A * y¹3-element Vector{Float64}:
1.0
2.0
3.0We now do the same in single precision:
Aˢ = Float32.(A)
yˢ = Float32.(y)
lsˢ = LinearSystem(Aˢ, yˢ)
update!(lsˢ, Aˢ, yˢ)
y² = solve(lu, lsˢ)3-element StaticArraysCore.SizedVector{3, Float32, Vector{Float32}} with indices SOneTo(3):
-0.11920929
1.666669f-7
0.5and again check the result:
Aˢ * y²3-element Vector{Float32}:
1.0
2.1423728
3.2847455As we can see the computation of the factorization returns a wrong solution. If we use pivoting however, the problem can also be solved with single precision:
lu = LU(; pivot = true)
y³ = solve(lu, lsˢ)3-element StaticArraysCore.SizedVector{3, Float32, Vector{Float32}} with indices SOneTo(3):
0.33333373
-1.0000004
1.0Aˢ * y³3-element Vector{Float32}:
1.0
1.9999998
3.0Solving the System with Built-In Functionality from the LinearAlgebra Package
We further try to solve the system with the inv operator from the LinearAlgebra package. First in double precision:
inv(A) * y3-element Vector{Float64}:
0.0
-0.33333333395421505
0.6666666669771075And also in single precision
inv(Aˢ) * yˢ3-element Vector{Float32}:
0.25
-0.5
0.75In single precision the result is completely wrong as can also be seen by computing:
inv(Aˢ) * Aˢ3×3 Matrix{Float32}:
1.0 0.5 1.0
0.0 1.0 -2.0
0.0 -0.5 1.0If we however write:
Aˢ \ yˢ3-element Vector{Float32}:
0.08333349
-0.5000001
0.75we again obtain a correct-looking result, as LinearAlgebra.\ uses an algorithm very similar to factorize! in SimpleSolvers.
- 1Here we also have to update the
LinearSystemby callingupdate!. For more information see the page on theinitialize!function.