Skip to content

Commit f867714

Browse files
mateuszbaranCopilot
andcommitted
Add customizable subsolver direction to ALM
Co-authored-by: Copilot <copilot@github.com>
1 parent 571b909 commit f867714

4 files changed

Lines changed: 41 additions & 4 deletions

File tree

Changelog.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ The file was started with Version `0.4`.
66
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
77
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
88

9+
## [0.5.37] April 25, 2026
10+
11+
### Added
12+
13+
* Customizable subsolver direction update for augmented Lagrangian method.
14+
915
## [0.5.36] April 24, 2026
1016

1117
### Added

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "Manopt"
22
uuid = "0fc0a36d-df90-57f3-8f93-d78a9fc72bb5"
3-
version = "0.5.36"
3+
version = "0.5.37"
44
authors = [{family-names = "Bergmann", given-names = "Ronny", alias = "kellertuer", city = "Trondheim", affiliation = "Norwegian University of Science and Technology", country = "NO", email = "manopt@ronnybergmann.net", orcid = "https://orcid.org/0000-0001-8342-7218", website = "https://ronnybergmann.net"}]
55

66
[workspace]

src/solvers/augmented_Lagrangian_method.jl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,8 @@ $(_kwargs(:sub_problem; default = "`[`DefaultManoptProblem`](@ref)`(M, sub_objec
325325
$(_kwargs(:sub_state; default = "`[`QuasiNewtonState`](@ref)` ")), where more precisely
326326
as quasi newton method, the [`QuasiNewtonLimitedMemoryDirectionUpdate`](@ref) with [`InverseBFGS`](@ref) is used.
327327
* `sub_stopping_criterion::StoppingCriterion=`[`StopAfterIteration`](@ref)`(300)`$(_sc(:Any))[`StopWhenGradientNormLess`](@ref)`(ϵ)`$(_sc(:Any))[`StopWhenStepsizeLess`](@ref)`(1e-8)`,
328+
* `sub_direction_update::AbstractQuasiNewtonDirectionUpdate=`[`QuasiNewtonLimitedMemoryDirectionUpdate`](@ref)`(M, copy(M, p), InverseBFGS(), min(manifold_dimension(M), 30))`:
329+
the direction update rule for the sub solver, where by default a limited memory quasi-Newton method with inverse BFGS update is used.
328330
329331
330332
For the `range`s of the constraints' gradient, other power manifold tangent space representations,
@@ -452,6 +454,9 @@ function augmented_Lagrangian_method!(
452454
sub_cost = AugmentedLagrangianCost(cmo, ρ, μ, λ),
453455
sub_grad = AugmentedLagrangianGrad(cmo, ρ, μ, λ),
454456
sub_kwargs = (;),
457+
sub_direction_update::AbstractQuasiNewtonDirectionUpdate = QuasiNewtonLimitedMemoryDirectionUpdate(
458+
M, copy(M, p), InverseBFGS(), min(manifold_dimension(M), 30)
459+
),
455460
sub_stopping_criterion::StoppingCriterion = StopAfterIteration(300) |
456461
StopWhenGradientNormLess(ϵ) |
457462
StopWhenStepsizeLess(1.0e-8),
@@ -460,9 +465,7 @@ function augmented_Lagrangian_method!(
460465
M;
461466
p = copy(M, p),
462467
X = zero_vector(M, p),
463-
direction_update = QuasiNewtonLimitedMemoryDirectionUpdate(
464-
M, copy(M, p), InverseBFGS(), min(manifold_dimension(M), 30)
465-
),
468+
direction_update = sub_direction_update,
466469
stopping_criterion = sub_stopping_criterion,
467470
stepsize = default_stepsize(M, QuasiNewtonState),
468471
sub_kwargs...,

test/solvers/test_augmented_lagrangian.jl

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,32 @@ using LinearAlgebra: I, tr
6868
@test q isa Real
6969
@test f(M, q) < f(M, 4)
7070
end
71+
72+
@testset "Customizable subsolver direction update" begin
73+
d = 20
74+
M = Sphere(d - 1)
75+
S = [ones(4)..., zeros(d - 4)...]
76+
v0 = project(M, S)
77+
Z = v0 * v0'
78+
f(M, p) = -tr(transpose(p) * Z * p) / 2
79+
grad_f(M, p) = project(M, p, -transpose.(Z) * p / 2 - Z * p / 2)
80+
g(M, p) = -p # in other words p ≥ 0
81+
mI = -Matrix{Float64}(I, d, d)
82+
grad_g(M, p) = [project(M, p, mI[:, i]) for i in 1:d]
83+
p0 = project(M, ones(d))
84+
s = augmented_Lagrangian_method(
85+
M,
86+
f,
87+
grad_f,
88+
p0;
89+
g = g,
90+
grad_g = grad_g,
91+
sub_direction_update = QuasiNewtonLimitedMemoryDirectionUpdate(
92+
M, copy(M, p0), InverseBFGS(), 5
93+
),
94+
stopping_criterion = StopAfterIteration(20),
95+
return_state = true,
96+
)
97+
@test s.sub_state.direction_update.memory_s.capacity == 5
98+
end
7199
end

0 commit comments

Comments
 (0)