Preconditioners overview

This page illustrates some of the method(s) in the Julia package Preconditioners.jl.

This page was generated from a single Julia file: 1-overview.jl.

In any such Julia documentation, you can access the source code using the "Edit on GitHub" link in the top right.

The corresponding notebook can be viewed in nbviewer here: 1-overview.ipynb, and opened in binder here: 1-overview.ipynb.

Setup

Packages needed here.

using Preconditioners: DiagonalPreconditioner, CholeskyPreconditioner
using InteractiveUtils: versioninfo
using SparseArrays: sprand
using LinearAlgebra: I, cond

Overview

Preconditioning is useful for accelerating solutions to systems of equations and optimization problems.

Examples

n = 1000
A = sprand(n, n, 0.01)
A = A + A' + 10I
1000×1000 SparseArrays.SparseMatrixCSC{Float64, Int64} with 20458 stored entries:
⎡⢵⣷⣶⣟⣟⣿⣿⡟⣾⣿⣿⣾⣻⣶⣿⢷⣿⣵⣽⣿⣏⣾⣷⣿⣿⣿⣭⣾⣿⣷⢿⡿⢵⣿⣻⣿⣷⣿⣟⣽⎤
⎢⣼⢿⣿⣿⣿⣿⣿⣏⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢿⣿⣷⣿⣿⣿⣿⣿⣿⣿⣿⣷⣿⣿⣷⣿⣿⣿⣿⣿⣿⎥
⎢⣿⣽⣿⣿⣿⣿⣾⣿⣯⣽⣿⢿⣯⣿⣿⡽⣿⣿⣿⣿⣯⣿⣿⣿⣿⣿⣯⣻⣿⣿⡿⡯⣿⣽⣿⡿⣟⣿⣿⣷⎥
⎢⣿⠿⡿⢿⣾⣿⣻⣾⢿⣿⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣻⣿⣿⣿⣾⣿⣽⣿⣿⣿⢯⣿⣿⣿⣻⣿⣿⣿⣿⡿⎥
⎢⣾⣿⣿⣾⣏⣿⣿⣷⡿⣯⣿⣿⣿⣿⣿⣺⣿⣻⣿⡿⣿⣞⣻⡿⣿⣿⣽⣿⣿⣿⣿⡿⣿⣿⣿⣿⣟⣿⣾⠷⎥
⎢⣻⣿⣿⣿⣿⣟⣿⣧⣿⣿⣿⣿⣟⣿⣗⣿⣿⣿⣯⣿⣻⣿⣿⣷⣿⣷⣻⣿⣿⢿⣿⣿⣽⣻⣿⣿⣿⣿⣿⣿⎥
⎢⢻⣾⣿⣿⣯⣿⣿⣿⣿⣿⣿⣽⣿⣿⣿⣿⣷⣾⣿⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⣿⣿⣿⢿⣿⣿⣿⣻⣿⣿⎥
⎢⢿⣟⣿⣿⣟⡿⣿⣿⣻⣻⣽⣽⣿⣿⣿⣿⣿⣽⡿⣿⣿⣿⣿⡿⡿⡿⣿⣟⣻⢯⣿⣿⣿⣟⣻⣿⣿⣿⣿⡯⎥
⎢⢟⣿⣿⣿⣿⣿⣿⣿⣿⣻⣿⣿⣹⣿⣟⣿⣿⣿⣿⣿⣿⣿⣟⣿⣿⣿⣿⣿⡿⢿⣾⡯⣾⢾⣿⣿⣟⡿⣿⣿⎥
⎢⣷⣿⣿⣟⣿⣿⣿⣿⣿⡿⣯⣿⣻⣿⣿⣯⣿⣿⣿⣿⣿⣿⣿⣿⣽⣿⣿⣿⣯⣾⣿⣟⣿⣿⣿⣿⣿⣟⣹⣟⎥
⎢⣫⣽⢿⣿⣯⣿⣿⣾⣻⢿⣿⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣯⣿⣿⣿⣷⣿⣿⣿⣿⣿⣿⡿⣮⣯⣟⎥
⎢⣽⣿⣿⣿⣿⣿⣿⣿⣿⡾⢿⣿⣿⣿⣿⡿⣿⣽⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡽⣿⣷⣿⣿⡿⣿⣿⣿⣿⎥
⎢⣿⣿⣿⣿⣿⣿⣾⣿⣿⣿⢿⣿⣿⣿⣿⡯⣿⣿⣷⣿⡿⣿⣿⣿⣿⣿⣿⣯⣿⣿⣿⣿⡽⣿⣯⣿⡟⣾⣿⣯⎥
⎢⣣⣿⣿⣿⣯⣻⣷⣿⣷⣿⣿⣾⣿⣿⣿⢿⣿⣿⣿⣿⣿⣿⣿⣿⡿⣿⣿⣿⣽⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⎥
⎢⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣟⣿⡟⡿⣞⣿⣏⣫⣿⢿⣿⣿⣿⣿⣿⣷⣿⣿⢟⣿⣿⢿⣻⣿⣿⣿⣿⣿⢿⎥
⎢⣿⡷⣽⣿⡿⡯⣯⣷⣿⡿⣿⣿⣿⣿⣿⣿⡾⡿⣿⢿⣿⣿⣷⣯⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣫⣯⣾⣷⣿⣿⎥
⎢⣵⣷⢿⣿⣟⣿⣿⣿⣿⣿⣷⣻⣿⣟⣿⢿⣺⣟⣿⣿⣿⣿⣽⣿⣷⣯⣿⣿⣿⣳⢿⣿⣿⣿⣿⣷⣿⢽⣿⣿⎥
⎢⣿⣾⣿⣿⣿⡿⣿⣾⣿⣿⣿⣿⣿⣿⣿⣾⣿⣿⣿⣿⣿⣿⣿⡿⣯⣿⣿⣿⣿⣿⡯⣾⢿⣿⡿⣯⣿⣽⣿⡿⎥
⎢⣽⣿⣿⣿⣿⣽⣿⣿⣿⣽⣿⣿⣿⣻⣿⣿⣿⡽⣿⢿⡻⣯⣿⣿⣻⣭⣿⣿⣿⣿⢾⣿⣟⣟⣟⣿⣿⣿⣾⣷⎥
⎣⣟⣽⣿⣿⢿⣿⣿⡿⢾⡟⣿⣿⣿⣿⡿⡿⣿⣿⣷⢾⣯⢿⣿⣿⡿⣿⣿⣿⣿⣟⣿⣿⣿⣿⣿⡿⢾⣿⣿⣿⎦

Examine conditioning:

cA = cond(Matrix(A), 2)
4.3154195835398514

Diagonal preconditioner

Dp = DiagonalPreconditioner(A)
DiagonalPreconditioner{Float64, Vector{Float64}}([10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0  …  10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0])

Apply preconditioner

DA = Dp \ A
1000×1000 SparseArrays.SparseMatrixCSC{Float64, Int64} with 20458 stored entries:
⎡⢵⣷⣶⣟⣟⣿⣿⡟⣾⣿⣿⣾⣻⣶⣿⢷⣿⣵⣽⣿⣏⣾⣷⣿⣿⣿⣭⣾⣿⣷⢿⡿⢵⣿⣻⣿⣷⣿⣟⣽⎤
⎢⣼⢿⣿⣿⣿⣿⣿⣏⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢿⣿⣷⣿⣿⣿⣿⣿⣿⣿⣿⣷⣿⣿⣷⣿⣿⣿⣿⣿⣿⎥
⎢⣿⣽⣿⣿⣿⣿⣾⣿⣯⣽⣿⢿⣯⣿⣿⡽⣿⣿⣿⣿⣯⣿⣿⣿⣿⣿⣯⣻⣿⣿⡿⡯⣿⣽⣿⡿⣟⣿⣿⣷⎥
⎢⣿⠿⡿⢿⣾⣿⣻⣾⢿⣿⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣻⣿⣿⣿⣾⣿⣽⣿⣿⣿⢯⣿⣿⣿⣻⣿⣿⣿⣿⡿⎥
⎢⣾⣿⣿⣾⣏⣿⣿⣷⡿⣯⣿⣿⣿⣿⣿⣺⣿⣻⣿⡿⣿⣞⣻⡿⣿⣿⣽⣿⣿⣿⣿⡿⣿⣿⣿⣿⣟⣿⣾⠷⎥
⎢⣻⣿⣿⣿⣿⣟⣿⣧⣿⣿⣿⣿⣟⣿⣗⣿⣿⣿⣯⣿⣻⣿⣿⣷⣿⣷⣻⣿⣿⢿⣿⣿⣽⣻⣿⣿⣿⣿⣿⣿⎥
⎢⢻⣾⣿⣿⣯⣿⣿⣿⣿⣿⣿⣽⣿⣿⣿⣿⣷⣾⣿⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⣿⣿⣿⢿⣿⣿⣿⣻⣿⣿⎥
⎢⢿⣟⣿⣿⣟⡿⣿⣿⣻⣻⣽⣽⣿⣿⣿⣿⣿⣽⡿⣿⣿⣿⣿⡿⡿⡿⣿⣟⣻⢯⣿⣿⣿⣟⣻⣿⣿⣿⣿⡯⎥
⎢⢟⣿⣿⣿⣿⣿⣿⣿⣿⣻⣿⣿⣹⣿⣟⣿⣿⣿⣿⣿⣿⣿⣟⣿⣿⣿⣿⣿⡿⢿⣾⡯⣾⢾⣿⣿⣟⡿⣿⣿⎥
⎢⣷⣿⣿⣟⣿⣿⣿⣿⣿⡿⣯⣿⣻⣿⣿⣯⣿⣿⣿⣿⣿⣿⣿⣿⣽⣿⣿⣿⣯⣾⣿⣟⣿⣿⣿⣿⣿⣟⣹⣟⎥
⎢⣫⣽⢿⣿⣯⣿⣿⣾⣻⢿⣿⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣯⣿⣿⣿⣷⣿⣿⣿⣿⣿⣿⡿⣮⣯⣟⎥
⎢⣽⣿⣿⣿⣿⣿⣿⣿⣿⡾⢿⣿⣿⣿⣿⡿⣿⣽⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡽⣿⣷⣿⣿⡿⣿⣿⣿⣿⎥
⎢⣿⣿⣿⣿⣿⣿⣾⣿⣿⣿⢿⣿⣿⣿⣿⡯⣿⣿⣷⣿⡿⣿⣿⣿⣿⣿⣿⣯⣿⣿⣿⣿⡽⣿⣯⣿⡟⣾⣿⣯⎥
⎢⣣⣿⣿⣿⣯⣻⣷⣿⣷⣿⣿⣾⣿⣿⣿⢿⣿⣿⣿⣿⣿⣿⣿⣿⡿⣿⣿⣿⣽⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⎥
⎢⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣟⣿⡟⡿⣞⣿⣏⣫⣿⢿⣿⣿⣿⣿⣿⣷⣿⣿⢟⣿⣿⢿⣻⣿⣿⣿⣿⣿⢿⎥
⎢⣿⡷⣽⣿⡿⡯⣯⣷⣿⡿⣿⣿⣿⣿⣿⣿⡾⡿⣿⢿⣿⣿⣷⣯⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣫⣯⣾⣷⣿⣿⎥
⎢⣵⣷⢿⣿⣟⣿⣿⣿⣿⣿⣷⣻⣿⣟⣿⢿⣺⣟⣿⣿⣿⣿⣽⣿⣷⣯⣿⣿⣿⣳⢿⣿⣿⣿⣿⣷⣿⢽⣿⣿⎥
⎢⣿⣾⣿⣿⣿⡿⣿⣾⣿⣿⣿⣿⣿⣿⣿⣾⣿⣿⣿⣿⣿⣿⣿⡿⣯⣿⣿⣿⣿⣿⡯⣾⢿⣿⡿⣯⣿⣽⣿⡿⎥
⎢⣽⣿⣿⣿⣿⣽⣿⣿⣿⣽⣿⣿⣿⣻⣿⣿⣿⡽⣿⢿⡻⣯⣿⣿⣻⣭⣿⣿⣿⣿⢾⣿⣟⣟⣟⣿⣿⣿⣾⣷⎥
⎣⣟⣽⣿⣿⢿⣿⣿⡿⢾⡟⣿⣿⣿⣿⡿⡿⣿⣿⣷⢾⣯⢿⣿⣿⡿⣿⣿⣿⣿⣟⣿⣿⣿⣿⣿⡿⢾⣿⣿⣿⎦

Examine effect on condition number

cd = cond(Matrix(DA), 2)
4.31378719089383

Incomplete Cholesky preconditioner with cut-off level 2

Pc = CholeskyPreconditioner(A, 2)
CholeskyPreconditioner{LimitedLDLFactorizations.LimitedLDLFactorization{Float64, Int64, Vector{Int64}, Vector{Int64}}}(LimitedLDLFactorizations.LimitedLDLFactorization{Float64, Int64, Vector{Int64}, Vector{Int64}}(true, 1000, [1, 14, 26, 49, 65, 78, 91, 108, 124, 147  …  11369, 11371, 11373, 11375, 11377, 11380, 11382, 11384, 11385, 11385], [364, 424, 447, 496, 619, 686, 732, 735, 860, 902  …  978, 982, 989, 994, 996, 986, 997, 991, 997, 998], [364, 424, 447, 496, 619, 686, 732, 735, 860, 902  …  997, 999, 998, 999, 1000, 999, 1000, 999, 1000, 1000], [0.08145207572378928, 0.022576744546314753, 0.09277342730650392, 0.010458723248216173, 0.031679754972061644, 0.02587036600292455, 0.04335878235552266, 0.07459074082271318, 0.08408978076759356, 0.037180338830930026  …  0.08709723015885204, 0.01724988997075015, 0.0032730775324621452, 0.04262883221257679, 0.04675043906428165, 0.04304842603455817, 0.08821773189825126, 0.05184138129746444, 0.07369042081296664, 0.031121875454593537], [0.08145207572378928, 0.022576744546314753, 0.09277342730650392, 0.010458723248216173, 0.031679754972061644, 0.02587036600292455, 0.04335878235552266, 0.07459074082271318, 0.08408978076759356, 0.037180338830930026  …  0.0007378294007149772, 0.00014519924729796305, 0.037527367433187374, 0.0016043841424601398, 0.0006855405396114125, -0.008701900059047592, -0.0019233771076085976, -5.7031715699379715e-5, -0.004746313595307601, -0.0024697373578218985], 1000, [10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0  …  10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0], [10.0, 10.0, 10.0, 10.0, 10.646899096275153, 10.0, 9.95719991355067, 10.0, 9.997737351885064, 9.954569666882259  …  9.125353350050286, 9.007285469015125, 9.357089896503172, 9.325777560950996, 9.424280497911475, 8.68859620923524, 9.199715184843182, 9.172540499193774, 8.912105599148044, 9.337446199448433], [175, 616, 82, 409, 681, 640, 789, 282, 863, 324  …  986, 987, 989, 991, 992, 994, 995, 997, 1000, 780], 0.0, 10.0, 0.0, 2, [60, 237, 267, 324, 325, 326, 327, 328, 15, 329  …  994, 995, 182, 996, 997, 21, 998, 270, 253, 999], [10.241615659836441, 10.188037896284532, 10.35495003195262, 10.300418572325137, 10.824104668684136, 10.179941493383378, 10.253002107971279, 10.228978552181221, 10.257351552849512, 10.210213878189748  …  10.411932095924778, 10.479995060170078, 10.301970384661141, 10.315510572094974, 10.27279710482565, 10.602833803256061, 10.388081816754262, 10.396485851683117, 10.51416785750407, 10.31933801824162], [0.31247534990427644, 0.3132959091494852, 0.3107606321584915, 0.3115821454375909, 0.3039513022305564, 0.31342047105182785, 0.312301792310882, 0.3126683098251958, 0.31223557231981514, 0.31295549409716766  …  0.309909105457325, 0.30890110440909146, 0.31155867734320514, 0.3113541335111767, 0.31200075482868417, 0.30710651024379876, 0.3102646658551218, 0.31013923875024807, 0.3083987058289474, 0.3112963874766631], [2.22068753e-316, 1.27319747463e-313, 0.0, 0.0, 0.0, 2.1986111e-316, 0.0651882677668113, 6.9457959201142e-310, 0.015021282811344462, -0.00016011409271051618  …  0.06121191668040354, -0.004892298714246782, 0.0007860829278226408, -0.003353352080691141, -0.0022147362078081593, -0.009505381106072268, 0.0002885254211350073, 0.037897956506327754, -5.671164791584791e-5, -0.0024929427490287207], [1000, 1000, 999, 1000, 999, 1000, 990, 991, 995, 997  …  9729, 9729, 9729, 9729, 9729, 9730, 9730, 9730, 9730, 9730], [12, 24, 47, 63, 76, 89, 106, 122, 145, 159  …  11367, 11369, 11371, 11373, 11375, 11378, 11380, 11382, 0, 0], [754, 0, 794, 202, 384, 727, 445, 831, 708, 706  …  337, 986, 988, 984, 988, 997, 870, 996, 998, 0], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10  …  991, 992, 993, 994, 995, 996, 997, 998, 999, 1000], Int64[], false), 2)

Here is a quick way to handle a matrix argument. This could be done more efficiently eventually; see Issue #33.

import Base.\
\(C::CholeskyPreconditioner, A::AbstractMatrix) = reduce(hcat, [C \ c for c in eachcol(A)])
\ (generic function with 155 methods)

apply preconditioner

CA = Pc \ A
1000×1000 SparseArrays.SparseMatrixCSC{Float64, Int64} with 1000000 stored entries:
⎡⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⎤
⎢⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⎥
⎢⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⎥
⎢⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⎥
⎢⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⎥
⎢⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⎥
⎢⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⎥
⎢⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⎥
⎢⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⎥
⎢⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⎥
⎢⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⎥
⎢⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⎥
⎢⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⎥
⎢⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⎥
⎢⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⎥
⎢⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⎥
⎢⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⎥
⎢⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⎥
⎢⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⎥
⎣⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⎦

examine effect on condition number

cc = cond(Matrix(CA), 2)
1.4140933768664028

Reproducibility

This page was generated with the following version of Julia:

io = IOBuffer(); versioninfo(io); split(String(take!(io)), '\n')
12-element Vector{SubString{String}}:
 "Julia Version 1.9.3"
 "Commit bed2cd540a1 (2023-08-24 14:43 UTC)"
 "Build Info:"
 "  Official https://julialang.org/ release"
 "Platform Info:"
 "  OS: Linux (x86_64-linux-gnu)"
 "  CPU: 2 × Intel(R) Xeon(R) Platinum 8272CL CPU @ 2.60GHz"
 "  WORD_SIZE: 64"
 "  LIBM: libopenlibm"
 "  LLVM: libLLVM-14.0.6 (ORCJIT, skylake-avx512)"
 "  Threads: 1 on 2 virtual cores"
 ""

And with the following package versions

import Pkg; Pkg.status()
Status `~/work/Preconditioners.jl/Preconditioners.jl/docs/Project.toml`
  [e30172f5] Documenter v0.27.25
  [98b081ad] Literate v2.14.2
  [af69fa37] Preconditioners v0.6.1 `~/work/Preconditioners.jl/Preconditioners.jl`
  [2f01184e] SparseArrays

This page was generated using Literate.jl.