@@ -36,34 +36,30 @@ and `Pr` for right preconditioner, respectively. By default, if no preconditione
36
36
the identity `` I `` .
37
37
38
38
39
- In the following, we will use the ` DiagonalPreconditioner ` to define a two-sided
40
- preconditioned system which first divides by some random numbers and then
41
- multiplies by the same values. This is commonly used in the case where if, instead
42
- of random, ` s ` is an approximation to the eigenvalues of a system.
39
+ In the following, we will use a left sided diagonal (Jacobi) preconditioner.
43
40
44
- ``` @example precon
41
+ ``` @example precon1
45
42
using LinearSolve, LinearAlgebra
46
43
n = 4
47
- s = rand(n)
48
- Pl = Diagonal(s)
49
44
50
45
A = rand(n, n)
51
46
b = rand(n)
52
47
48
+ Pl=Diagonal(A)
49
+
53
50
prob = LinearProblem(A, b)
54
51
sol = solve(prob, KrylovJL_GMRES(), Pl = Pl)
55
52
sol.u
56
53
```
57
54
58
55
Alternatively, preconditioners can be specified via the ` precs ` argument to the constructor of
59
- an iterative solver specification. This argument shall deliver a function mapping ` A ` and a
56
+ an iterative solver specification. This argument shall deliver a factory method mapping ` A ` and a
60
57
parameter ` p ` to a tuple ` (Pl,Pr) ` consisting a left and a right preconditioner.
61
58
62
59
63
60
``` @example precon2
64
61
using LinearSolve, LinearAlgebra
65
62
n = 4
66
- s = rand(n)
67
63
68
64
A = rand(n, n)
69
65
b = rand(n)
@@ -73,26 +69,33 @@ sol = solve(prob, KrylovJL_GMRES(precs = (A,p)->(Diagonal(A),I)) )
73
69
sol.u
74
70
```
75
71
This approach has the advantage that the specification of the preconditioner is possible without
76
- the knowledge of a concrete matrix ` A ` . It also allows to specify the preconditioner via a callable object:
72
+ the knowledge of a concrete matrix ` A ` . It also allows to specify the preconditioner via a callable object
73
+ and to pass parameters to the constructor of the preconditioner instances. The example below also shows how
74
+ to reuse the preconditioner once constructed for the subsequent solution of a modified problem.
77
75
78
- ``` @example precon2
76
+ ``` @example precon3
79
77
using LinearSolve, LinearAlgebra
80
78
81
- struct DiagonalPrecs end
79
+ Base.@kwdef struct WeightedDiagonalBuilder
80
+ w::Float64
81
+ end
82
82
83
- (::DiagonalPrecs )(A,p) = (Diagonal(A),I)
83
+ (builder::WeightedDiagonalBuilder )(A,p) = (builder.w* Diagonal(A),I)
84
84
85
85
n = 4
86
- s = rand(n)
87
-
88
- A = rand(n, n)
86
+ A = n*I-rand(n, n)
89
87
b = rand(n)
90
88
91
89
prob = LinearProblem(A, b)
92
- sol = solve(prob, KrylovJL_GMRES(precs = DiagonalPrecs( )) )
90
+ sol = solve(prob, KrylovJL_GMRES(precs = WeightedDiagonalBuilder(w=0.9 )) )
93
91
sol.u
94
- ```
95
92
93
+ B=A.+0.1
94
+ cache=sol.cache
95
+ reinit!(cache,A=B, reuse_precs=true)
96
+ sol = solve!(cache, KrylovJL_GMRES(precs = WeightedDiagonalBuilder(w=0.9)) )
97
+ sol.u
98
+ ```
96
99
## Preconditioner Interface
97
100
98
101
To define a new preconditioner you define a Julia type which satisfies the
0 commit comments