Skip to content

StructuredOptimization-related changes + new algorithms - #100

Draft
hakkelt wants to merge 10 commits into
JuliaFirstOrder:masterfrom
hakkelt:master
Draft

StructuredOptimization-related changes + new algorithms#100
hakkelt wants to merge 10 commits into
JuliaFirstOrder:masterfrom
hakkelt:master

Conversation

@hakkelt

@hakkelt hakkelt commented Nov 11, 2025

Copy link
Copy Markdown

This PR is part of the effort to make StructuredOptimization as general as possible (see the PR on OperatorCore: JuliaFirstOrder/ProximalCore.jl#5).

Changes:

  • new get_assumptions function defined for all algorithms that allows querying the requirements for the algorithm's parameters (e.g., f must be is_smooth, g must be is_proximable). The function returns a dict-like object that has the names of the parameters as keys and a tuple of functions that are expected to return true for all allowed inputs as values. The concept is to enable automatic decisions on how to feed functions of the ProximalOperators package and operators of AbstractOperators to the algorithms.
  • Separate default_iteration_summary function from default_display function and allow overriding them separately through the general IterativeAlgorithm interface.
  • Improve the default display functionality by showing the header and automatically figuring out the optimal column width (it implements some of the wishes in Improve verbose mode #70 ).
  • Add override_parameters function that allows overwriting values of fields in IterativeAlgorithm struct by creating a copy with changed values. I use this in a high-level package to inject default maxit and atol values into the user-provided algorithm.
  • Introduce two new algorithms:
    • Alternating Directions of Multipliers Method (ADMM)
    • (Preconditioned) Conjugate Gradient (CG) -- I know that this is not a proximal algorithm, but ADMM uses it internally, so it seemed logical to also implement the full interface of ProximalAlgorithms.
  • Preallocate more in DavisYin, DouglasRachford, and FastForwardBackward
  • Minor fixes in docstrings

This PR contains no breaking changes (as far as I know), only introduces new features.

- separate default_iteration_summary function from default_display function and allow overriding them separately through general IterativeAlgorithm interface
- improve default display function by showing header and automatically figuring out optimal column width
- add override_parameters function
- get_addumptions function return AssumptionGroup instead of a Tuple
- improve ADMM type stability
- fix errors in CG
- introduce CGNR algorithm as a variation of CG algorithm
- preallocate more in DavisYin, DouglasRachford, and FastForwardBackward
- minor fixes in docstrings
@lostella

Copy link
Copy Markdown
Member

@hakkelt I see that you're attempting various changes in different packages, all motivated by StructuredOptimization. I think it might be fine to move some core definitions to ProximalCore, but I would encourage you to:

  • Keep PRs small and focused, since reviewing 3000 line changes is very hard, especially if the changes are not always related
  • Keep the changes that belong to StructuredOptimization, into StructuredOptimization. Not everything needs to be pushed "upstream" from the get go, necessarily. For example, could you not define assumptions for the algorithms in ProximalAlgorithms, directly in StructuredOptimization? This is where the assumptions are needed, so it should be fine to define them there, without introducing inter-package design choices too early. Once things work well, one can think of exposing these interfaces in more "core" packages, and put the definitions next to the types. This way the wider plan is easier to understand & review

@hakkelt

hakkelt commented Nov 13, 2025

Copy link
Copy Markdown
Author

Thanks for the feedback, and sorry for the messy PRs. Would it help if I discard this PR and break the changes included in it into multiple smaller pull requests, submitting them one by one?

Concerning get_assumption: I'm ok with moving it to StructuredOptimization as it might too early have it here, but for maintainability, I would be glad if some machinery that allows querying is incorporated into AbstractAlgorithms.

@hakkelt
hakkelt marked this pull request as draft December 2, 2025 11:09
@hakkelt

hakkelt commented Dec 2, 2025

Copy link
Copy Markdown
Author

Instead of this large PR, I'll make multiple smaller, more focused PRs, starting with #101

@lostella

lostella commented Dec 2, 2025

Copy link
Copy Markdown
Member

Thanks @hakkelt, I’ll take a look at it asap

pjssilva and others added 2 commits September 1, 2026 15:09
…Order#103)

The current compat of the package is

```txt
              julia                    1.6
   [47edcb42] ADTypes                  1.5.3
   [a0c0ee7d] DifferentiationInterface 0.6.2
   [37e2e46d] LinearAlgebra            1.2
   [de0858da] Printf                   1.2
   [dc4f5ac2] ProximalCore             0.1
```

The restriction on DifferentiationInterface.jl precludes using version
0.7.x that is required by other packages (like version 2.x of Optimjl).
I tested ProximalAlgorithms.jl, changing compat to
```txt
              julia                    1.6
   [47edcb42] ADTypes                  1.5.3
   [a0c0ee7d] DifferentiationInterface 0.6.2,0.7
   [37e2e46d] LinearAlgebra            1.2
   [de0858da] Printf                   1.2
   [dc4f5ac2] ProximalCore             0.1
```
All tests passed. Hence, it seems possible to use 0.7.x version of
DifferentiationInterface.jl.
The x-update solves (AᴴA + ∑ᵢ ρᵢ BᵢᴴBᵢ) x = rhs with an inner CG loop. The
system operator was rebuilt from scratch as a sum of operators every time the
adaptive penalty sequence changed a ρᵢ. That rebuilt operator was never
written back into the state, so once ρ stabilised CG silently reverted to
running against the initial ρ; and the rebuild allocated a fresh operator
tree per iteration.

Replace it with ADMMNormalOp, a small struct holding AᴴA, the tuple of BᵢᴴB,
and a reference to penalty_sequence.rho. Its mul! computes the combined action
directly into a single scratch buffer. Because every PenaltySequence mutates
seq.rho in place and never reassigns the field, the operator tracks ρ live
with nothing to rebuild and nothing to write back.

Built once in ADMMState; the per-iteration rebuild branch in Base.iterate is
removed, along with the now-unused rho_changed return value.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants