@@ -38,14 +38,17 @@ where `S`, `ξ` and `dy` are the normal equations system's
38
38
left- and right-hand side, and solution vector, respectively.
39
39
`S` may take the form of a matrix, or of a suitable linear operator.
40
40
"""
41
- mutable struct KrylovSPD{T, F, Tv, Ta} <: AbstractKrylovSolver{T}
41
+ mutable struct KrylovSPD{T, F, Tv, Ta, Tp } <: AbstractKrylovSolver{T}
42
42
m:: Int
43
43
n:: Int
44
44
45
45
f:: F # Krylov function
46
46
atol:: T # absolute tolerance
47
47
rtol:: T # relative tolerance
48
48
49
+ P:: Tp # Preconditioner
50
+ nitertot:: Int # Total number of Krylov iterations
51
+
49
52
# Problem data
50
53
A:: Ta # Constraint matrix
51
54
θ:: Tv # scaling
@@ -54,14 +57,26 @@ mutable struct KrylovSPD{T, F, Tv, Ta} <: AbstractKrylovSolver{T}
54
57
55
58
function KrylovSPD (f:: Function , A:: Ta ;
56
59
atol:: T = eps (T)^ (3 // 4 ),
57
- rtol:: T = eps (T)^ (3 // 4 )
60
+ rtol:: T = eps (T)^ (3 // 4 ),
61
+ preconditioner:: Symbol = :Identity
58
62
) where {T, Ta <: AbstractMatrix{T} }
59
63
F = typeof (f)
60
64
m, n = size (A)
61
65
62
- return new {T, F, Vector{T}, Ta} (
66
+ if preconditioner == :Jacobi
67
+ P = JacobiPreconditioner (ones (T, m))
68
+ elseif preconditioner == :Identity
69
+ P = IdentityPreconditioner ()
70
+ else
71
+ @error " Unknown preconditioner: $preconditioner , using identity instead"
72
+ P = IdentityPreconditioner ()
73
+ end
74
+
75
+ return new {T, F, Vector{T}, Ta, typeof(P)} (
63
76
m, n,
64
77
f, atol, rtol,
78
+ P,
79
+ 0 ,
65
80
A, ones (T, n), ones (T, n), ones (T, m)
66
81
)
67
82
end
@@ -101,6 +116,9 @@ function update!(
101
116
kkt. regP .= regP
102
117
kkt. regD .= regD
103
118
119
+ # Update Jacobi preconditioner
120
+ update_preconditioner (kkt)
121
+
104
122
return nothing
105
123
end
106
124
@@ -137,17 +155,22 @@ function solve!(
137
155
end
138
156
)
139
157
158
+ opM = op (kkt. P)
159
+ # @info typeof(opM) extrema(kkt.P.d)
160
+
140
161
# Solve normal equations
141
- _dy, stats = kkt. f (opS, ξ_, atol= kkt. atol, rtol= kkt. rtol)
142
- dy .= _dy
162
+ _dy, stats = kkt. f (opS, ξ_, M = opM, atol= kkt. atol, rtol= kkt. rtol)
143
163
144
- # Recover dx
164
+ # Book-keeping
165
+ kkt. nitertot += length (stats. residuals) - 1
166
+
167
+ # Recover dy, dx
168
+ dy .= _dy
145
169
dx .= D * (kkt. A' * dy - ξd)
146
170
147
171
return nothing
148
172
end
149
173
150
-
151
174
# ==============================================================================
152
175
# KrylovSID:
153
176
# ==============================================================================
@@ -424,4 +447,7 @@ function solve!(
424
447
dy .= _dy
425
448
426
449
return nothing
427
- end
450
+ end
451
+
452
+ # Code for pre-conditioners
453
+ include (" preconditioners.jl" )
0 commit comments