Skip to content

Commit 4c48025

Browse files
MohamedLaghdafHABIBOULLAHdpo
authored andcommitted
Add Diagonal BFGS
1 parent 5cb74c4 commit 4c48025

File tree

1 file changed

+57
-1
lines changed

1 file changed

+57
-1
lines changed

src/DiagonalHessianApproximation.jl

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export DiagonalPSB, DiagonalAndrei, SpectralGradient
1+
export DiagonalPSB, DiagonalAndrei, SpectralGradient, DiagonalBFGS
22

33
"""
44
DiagonalPSB(d)
@@ -203,3 +203,59 @@ function push!(
203203
B.d[1] = dot(s, y) / dot(s, s)
204204
return B
205205
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

Comments
 (0)