|
1 | | -export DiagonalPSB, DiagonalAndrei, SpectralGradient |
| 1 | +export DiagonalPSB, DiagonalAndrei, SpectralGradient, DiagonalBFGS |
2 | 2 |
|
3 | 3 | """ |
4 | 4 | DiagonalPSB(d) |
@@ -203,3 +203,59 @@ function push!( |
203 | 203 | B.d[1] = dot(s, y) / dot(s, s) |
204 | 204 | return B |
205 | 205 | end |
| 206 | + |
| 207 | +""" |
| 208 | + DiagonalBFGS(d) |
| 209 | +
|
| 210 | +A diagonal approximation of the BFGS update inspired by |
| 211 | +Marnissi, Y., Chouzenoux, E., Benazza-Benyahia, A., & Pesquet, J. C. (2020). |
| 212 | +Majorize–minimize adapted Metropolis–Hastings algorithm. |
| 213 | +https://ieeexplore.ieee.org/abstract/document/9050537. |
| 214 | +
|
| 215 | +# Arguments |
| 216 | +
|
| 217 | +- `d::AbstractVector`: initial diagonal approximation. |
| 218 | +""" |
| 219 | +mutable struct DiagonalBFGS{T <: Real, I <: Integer, V <: AbstractVector{T}, F} <: |
| 220 | + AbstractDiagonalQuasiNewtonOperator{T} |
| 221 | + d::V # Diagonal of the operator |
| 222 | + nrow::I |
| 223 | + ncol::I |
| 224 | + symmetric::Bool |
| 225 | + hermitian::Bool |
| 226 | + prod!::F |
| 227 | + tprod!::F |
| 228 | + ctprod!::F |
| 229 | + nprod::I |
| 230 | + ntprod::I |
| 231 | + nctprod::I |
| 232 | + args5::Bool |
| 233 | + use_prod5!::Bool # true for 5-args mul! and for composite operators created with operators that use the 3-args mul! |
| 234 | + allocated5::Bool # true for 5-args mul!, false for 3-args mul! until the vectors are allocated |
| 235 | +end |
| 236 | + |
| 237 | +@doc (@doc DiagonalBFGS) function DiagonalBFGS(d::AbstractVector{T}) where {T <: Real} |
| 238 | + prod = (res, v, α, β) -> mulSquareOpDiagonal!(res, d, v, α, β) |
| 239 | + n = length(d) |
| 240 | + DiagonalBFGS(d, n, n, true, true, prod, prod, prod, 0, 0, 0, true, true, true) |
| 241 | +end |
| 242 | + |
| 243 | +# update function |
| 244 | +# s = x_{k+1} - x_k |
| 245 | +# y = ∇f(x_{k+1}) - ∇f(x_k) |
| 246 | +function push!( |
| 247 | + B::DiagonalBFGS{T, I, V, F}, |
| 248 | + s0::V, |
| 249 | + y0::V, |
| 250 | +) where {T <: Real, I <: Integer, V <: AbstractVector{T}, F} |
| 251 | + s0Norm = norm(s0, 2) |
| 252 | + if s0Norm == 0 |
| 253 | + error("Cannot update DiagonalQN operator with s=0") |
| 254 | + end |
| 255 | + # sᵀBs = sᵀy can be scaled by ||s||² without changing the update |
| 256 | + s = (si / s0Norm for si ∈ s0) |
| 257 | + y = (yi / s0Norm for yi ∈ y0) |
| 258 | + sT_y = dot(s, y) |
| 259 | + B.d .= sum(abs.(y)) / sT_y .* abs.(y) |
| 260 | + return B |
| 261 | +end |
0 commit comments