Skip to content

Commit 7ba0241

Browse files
committed
export, reformat, add docstrings
1 parent 42b52b1 commit 7ba0241

File tree

1 file changed

+64
-36
lines changed

1 file changed

+64
-36
lines changed

src/DiagonalHessianApproximation.jl

Lines changed: 64 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
export DiagonalQN, SpectralGradient
2+
13
function mulSquareOpDiagonal!(res, d, v, α, β::T) where {T <: Real}
24
if β == zero(T)
35
res .= α .* d .* v
@@ -13,7 +15,8 @@ Andrei, N.
1315
A diagonal quasi-Newton updating method for unconstrained optimization.
1416
https://doi.org/10.1007/s11075-018-0562-7
1517
"""
16-
mutable struct DiagonalQN{T <: Real, I <: Integer, V <: AbstractVector{T}} <: AbstractDiagonalQuasiNewtonOperator{T}
18+
mutable struct DiagonalQN{T <: Real, I <: Integer, V <: AbstractVector{T}} <:
19+
AbstractDiagonalQuasiNewtonOperator{T}
1720
d::V # Diagonal of the operator
1821
nrow::I
1922
ncol::I
@@ -30,43 +33,54 @@ mutable struct DiagonalQN{T <: Real, I <: Integer, V <: AbstractVector{T}} <: Ab
3033
allocated5::Bool # true for 5-args mul!, false for 3-args mul! until the vectors are allocated
3134
end
3235

33-
DiagonalQN(d::AbstractVector{T}) where {T <: Real} =
34-
DiagonalQN(
35-
d,
36-
length(d),
37-
length(d),
38-
true,
39-
true,
40-
(res, v, α, β) -> mulSquareOpDiagonal!(res, d, v, α, β),
41-
(res, v, α, β) -> mulSquareOpDiagonal!(res, d, v, α, β),
42-
(res, v, α, β) -> mulSquareOpDiagonal!(res, d, v, α, β),
43-
0,
44-
0,
45-
0,
46-
true,
47-
true,
48-
true)
36+
"""
37+
DiagonalQN(d)
38+
39+
Construct a linear operator that represents a diagonal quasi-Newton approximation.
40+
The approximation satisfies the weak secant equation and is not guaranteed to be
41+
positive definite.
42+
43+
# Arguments
44+
45+
- `d::AbstractVector`: initial diagonal approximation.
46+
"""
47+
DiagonalQN(d::AbstractVector{T}) where {T <: Real} = DiagonalQN(
48+
d,
49+
length(d),
50+
length(d),
51+
true,
52+
true,
53+
(res, v, α, β) -> mulSquareOpDiagonal!(res, d, v, α, β),
54+
(res, v, α, β) -> mulSquareOpDiagonal!(res, d, v, α, β),
55+
(res, v, α, β) -> mulSquareOpDiagonal!(res, d, v, α, β),
56+
0,
57+
0,
58+
0,
59+
true,
60+
true,
61+
true,
62+
)
4963

5064
# update function
5165
# s = x_{k+1} - x_k
5266
# y = ∇f(x_{k+1}) - ∇f(x_k)
5367
function push!(
54-
B::DiagonalQN{T,I,V},
68+
B::DiagonalQN{T, I, V},
5569
s::V,
56-
y::V
57-
) where {T <: Real, I <: Integer, V <: AbstractVector{T}}
70+
y::V,
71+
) where {T <: Real, I <: Integer, V <: AbstractVector{T}}
5872
trA2 = zero(T)
5973
for i in eachindex(s)
6074
trA2 += s[i]^4
6175
end
62-
sT_s = dot(s,s)
63-
sT_y = dot(s,y)
76+
sT_s = dot(s, s)
77+
sT_y = dot(s, y)
6478
sT_B_s = sum(s[i]^2 * B.d[i] for i eachindex(s))
6579
if trA2 == 0
6680
error("Cannot divide by zero and trA2 = 0")
6781
end
68-
q = (sT_y + sT_s - sT_B_s)/trA2
69-
B.d .+= q .* s.^2 .- 1
82+
q = (sT_y + sT_s - sT_B_s) / trA2
83+
B.d .+= q .* s .^ 2 .- 1
7084
return B
7185
end
7286

@@ -77,7 +91,7 @@ Birgin, E. G., Martínez, J. M., & Raydan, M.
7791
Spectral Projected Gradient Methods: Review and Perspectives.
7892
https://doi.org/10.18637/jss.v060.i03
7993
"""
80-
mutable struct SpectralGradient{T <: Real, I <: Integer} <: AbstractDiagonalQuasiNewtonOperator{T}
94+
mutable struct SpectralGradient{T <: Real, I <: Integer} <: AbstractDiagonalQuasiNewtonOperator{T}
8195
d::T # Diagonal coefficient of the operator (multiple of the identity)
8296
nrow::I
8397
ncol::I
@@ -94,34 +108,48 @@ mutable struct SpectralGradient{T <: Real, I <: Integer} <: AbstractDiagonalQuas
94108
allocated5::Bool # true for 5-args mul!, false for 3-args mul! until the vectors are allocated
95109
end
96110

97-
SpectralGradient(d::T, n::I) where {T <: Real, I <: Integer} =
111+
"""
112+
SpectralGradient(σ, n)
113+
114+
Construct a spectral gradient Hessian approximation.
115+
The approximation is defined as σI.
116+
117+
# Arguments
118+
119+
- `σ::Real`: initial positive multiple of the identity;
120+
- `n::Int`: operator size.
121+
"""
122+
function SpectralGradient(d::T, n::I) where {T <: Real, I <: Integer}
123+
@assert d > 0
98124
SpectralGradient(
99125
d,
100126
n,
101127
n,
102128
true,
103-
true,
104-
(res, v, α, β) -> mulSquareOpDiagonal!(res, d, v, α, β),
105-
(res, v, α, β) -> mulSquareOpDiagonal!(res, d, v, α, β),
106-
(res, v, α, β) -> mulSquareOpDiagonal!(res, d, v, α, β),
129+
true,
130+
(res, v, α, β) -> mulSquareOpDiagonal!(res, d, v, α, β),
131+
(res, v, α, β) -> mulSquareOpDiagonal!(res, d, v, α, β),
132+
(res, v, α, β) -> mulSquareOpDiagonal!(res, d, v, α, β),
107133
0,
108134
0,
109135
0,
110136
true,
111137
true,
112-
true)
138+
true,
139+
)
140+
end
113141

114142
# update function
115143
# s = x_{k+1} - x_k
116144
# y = ∇f(x_{k+1}) - ∇f(x_k)
117145
function push!(
118-
B::SpectralGradient{T,I},
146+
B::SpectralGradient{T, I},
119147
s::V,
120-
y::V
121-
) where {T <: Real, I <: Integer, V <: AbstractVector{T}}
148+
y::V,
149+
) where {T <: Real, I <: Integer, V <: AbstractVector{T}}
122150
if all(s .== 0)
123151
error("Cannot divide by zero and s .= 0")
124152
end
125-
B.d = dot(s,y)/dot(s,s)
153+
B.d = dot(s, y) / dot(s, s)
126154
return B
127-
end
155+
end

0 commit comments

Comments
 (0)