Repository navigation
Add DefaultState and DefaultStoppingCriterionState implementations - #32
Conversation
|
@mtfishman, @jack-dunham - linking you both here in case you would like to have a look/share opinions |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #32 +/- ##
==========================================
+ Coverage 99.60% 99.62% +0.02%
==========================================
Files 6 7 +1
Lines 255 270 +15
==========================================
+ Hits 254 269 +15
Misses 1 1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
I like the idea, though until now I mainly used a slightly different approach (in Manifolds.jl and Manopt.jl that is): the I am not saying my approach is per se better. I do see the danger of “overwrapping” in your case though. Somewhen you might end up with “DefaultData” and therein continue with some further default... What do you think? Another note, since we are discussing states, in Manopt.jl we introduced callbacks a while back, see JuliaManifolds/Manopt.jl#626 or https://manoptjl.org/stable/tutorials/HowToCallback/ for the new tutorial. Since we do talk about a default state, we could add that here as well, indeed. The field is just a dictionary of functions (of an agreed-upon-signature), the actual callback code is quite short https://github.com/JuliaManifolds/Manopt.jl/blob/master/src/base/state/callback.jl and the actually “hooks” (places where the callbacks are called) are also just one line each, see for example the generic ones at https://github.com/JuliaManifolds/Manopt.jl/blob/5e362ee0f07fb656dfdf1a40a616a94c3ba27260/src/solvers/solver.jl#L164-L177 |
I definitely feel like I agree with you here, I think this was what I was getting at with the question about replacing the abstract Let me try that out just to see how it would look, the only annoying part being that it is breaking but that's what 0.x versions are for I guess. |
|
I still think the |
|
Alright, second attempt: I took the What I like the most about this approach is that we no longer rely on correctly defining the right fields for compliance with this package, and in the meantime get to hide a lot of the boilerplate that is related to that. What I like a little less, although I think it might be acceptable, is that because we are defining the structs, it is a little less transparent what is going on and which data is put where. Ultimately, I think I quite like this approach. |
|
I like the idea of having a |
|
In the last commit the abstract |
|
This last commit was the idea to get rid of the abstract state, so the default path is without as much friction, and then have explicit implementations add a |
|
The state.iterate # returns the iterate (the data that gets passed around)
state.iteration # returns the iteration. Then one can define concrete |
|
I was maybe too much still in The “dynamic structure with names tuple” sounds a bit like a hack. For me it then depends a lot on how “safe” that is, whether I like that. I am not yet sure. If we always one have one state, then sure we do not need a default one. |
Following the review on #32, the abstract `State` and `StoppingCriterionState` stay, and `DefaultState` is the convenience path rather than the only one. The same over-wrapping concern raised about `DefaultState.data` applies to the criterion state, and criteria that need to remember something already define a state type of their own, so `DefaultStoppingCriterionState` goes back to only recording `at_iteration`. This drops the `stopping_state_data` argument from the default `initialize_state` and `initialize_state!`, whose positional form becomes `(problem, algorithm, iterate, state_data)`. The docs now point algorithms with a state of their own at the keyword form, since the positional one shares its arity with the stopping-criterion variant, and steer anyone outgrowing `data` towards subtyping `State` instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Found some more time for this one: From the discussion before (at least what I remember from them), I think I went more or less back to the first commit and kept the abstract we then still have:
I removed the |
|
Ehm, the commit message is AI slurp – the docs now also tend to that, is that intended? |
| println("Approximate sqrt: ", heron_sqrt(16.0)) | ||
| ``` | ||
|
|
||
| The `iterate` keyword is where the default initialization gets its starting point from, and it is required: there is no sensible guess this package could make on an algorithm's behalf. |
There was a problem hiding this comment.
also very long and slurp. No need to write that there is no good default.
|
Fair point(s), I squashed the commits now, and went through to make the language a bit better (hopefully). Re the individual commit messages, I don't care too much about that, since they end up squashed in the main repository anyway, and I'm not that convinced we're gaining much by me investing time in cleaning that up... Hopefully this now looks clean and acceptable to everyone :) |
|
Let me then start with a bit of a polemic answer quote
I have given up discussing LLMs in e.g. Julia Discourse, there is too many evangelist and vibe coders around. This package has turned into something I will probably never use in practice. I still think it is nice, but I would estimate a full year of work to base Manopt on this. And I will never have such a year. No, I do not want that. This does not mean you have to stop using it. It does also not mean, you have to stop using it here. Just if you want to use it here, I am no longer available as reviewer or for discussions. This is nothing against you personally – I think we had absolutely great discussions. I am just too overly tired of LLMs and being “slopped all around”. |
Add `DefaultState`, a `State` with the expected `iterate`, `iteration` and `stopping_criterion_state` fields and a `data` field for any additional data, together with default `initialize_state` and `initialize_state!` methods using it. Also add default initialization for stopping criteria, using a `DefaultStoppingCriterionState`.
Welcome to Codecov 🎉Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests. ℹ️ You can also turn on project coverage checks and project coverage reporting on Pull Request comment Thanks for integrating Codecov - We've got you covered ☂️ |
This PR reduces the boilerplate needed to implement an algorithm.
DefaultState <: Statestores the expectediterate,iterationandstopping_criterion_state, plus adatafield for any additional data.initialize_stateandinitialize_state!methods construct and reset aDefaultState, taking the initial point as theiteratekeyword (or positionally as(problem, algorithm, iterate, state_data)).initialize_stateandinitialize_state!for anyStoppingCriterion, using aDefaultStoppingCriterionState.StopAfterIterationnow relies on these.With this, an algorithm only has to provide a
Problem, anAlgorithmand astep!.The abstract
Statestays, so algorithms that need more can still define their own state, as before. This change is non-breaking.The docs now use
DefaultStatefor the Heron example, and show a customHeronStateat the end of the interface page.