Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimizer options interface #52

Open
FHoltorf opened this issue Dec 7, 2023 · 3 comments
Open

Optimizer options interface #52

FHoltorf opened this issue Dec 7, 2023 · 3 comments

Comments

@FHoltorf
Copy link

FHoltorf commented Dec 7, 2023

Hey,

I would like to solve some quantum control problems via GRAPE but I need high precision with regard to stationarity. Unfortunately, I can't use Optim.jl because I have bounds on the control drives and it seems I am also not able to strengthen the convergence criteria in the L-BFGS-B default flexibly enough. I think that is the case at least? The GrapeResult object does not carry gradient information so I assume cannot use that to define my own convergence criterion and the corresponding LBFGSB.jl optionpgtol = 1e-5 appears to be hardcoded (see https://github.com/JuliaQuantumControl/GRAPE.jl/blob/83295ce48621430db739ce2cdee4afba5b9ee41e/src/backend_lbfgsb.jl#L8).

Am I missing a way to set the convergence criterion? If not, what's the better way to address that issue? Support bounds for Optim.jl optimizers, pass gradient information to the result object, or admit kwargs to set options for the default optimizer?

Thanks!
Flemming

@goerz
Copy link
Member

goerz commented Dec 7, 2023

I need high precision with regard to stationarity

I'm not sure what that means. What's "stationarity"?

define my own convergence criterion

There's infohook for that, in principle, which gets the GrapeWrk object which has access to lots of internal data, including gradient information, although not the LBFGSB optimizer, which might be nice to have. These internals need a pretty major overhaul at some point.

the corresponding LBFGSB.jl option pgtol = 1e-5 appears to be hardcoded

There's no particular reason this has to be hardcoded, except that I haven't really looked at what these parameters do or how they might go into a coherent interface for the GRAPE package. If being able to set pgtol (the same way you can set g_tol for Optim) solves your problem, I can just make that an option. Same for the hardcoded factr and m.

Support bounds for Optim.jl optimizers

That would be something on the long-term TODO list

pass gradient information to the result object

Probably not… Stuff like that should generally be in the internal "workplace" object (GrapeWrk). How would having it in the result object help you?

admit kwargs to set options for the default optimizer?

Yes, definitely. I can do that this weekend if that helps you, as an "experimental feature" (subject to change in future versions if I can make the API more coherent)

@FHoltorf
Copy link
Author

FHoltorf commented Dec 7, 2023

Thanks for the quick reply!

I'm not sure what that means. What's "stationarity"?

Stationarity is just jargon for a condition that encodes if a point is a stationary point for the underlying optimization problem (so in the simplest setting: a condition that encodes how close the gradient is to vanishing) which is of course often used as part of convergence criterion. Here, the default L-BFGS-B method declares convergence when the norm of the projected gradient is < pgtol (=1e-5) but I would like for it to keep going to higher precision in this sense. Sorry, I didn't explain well what my problem was in practice :).

If being able to set pgtol (the same way you can set g_tol for Optim) solves your problem, I can just make that an option. Same for the hardcoded factr and m.

I personally only need pgtol right now but I think it could generally be useful to expose all (or at least the common) solver options (since different choices for them can in principle matter a lot). It might not be worth the effort if no-one else uses it, though.

How would having it in the result object help you?
My (possibly incorrect) understanding is that you allow a user to define their own convergence criteria through the check_covergence kwarg by defining a function on result object.

If the gradient was carried by this object I thought I would just be able to define my convergence criterion accordingly. Something along the lines ofres -> norm(res.gradient) < 1e-9. That would only work, however, if this would not be overwritten by the solver internal convergence checks.

There's infohook for that, in principle, which gets the GrapeWrk object which has access to lots of internal data, including gradient information, although not the LBFGSB optimizer, which might be nice to have. These internals need a pretty major overhaul at some point.

Together with what I wrote above, maybe this could already solve my problem? I will look into that.

Thanks!
Flemming

@goerz
Copy link
Member

goerz commented Dec 7, 2023

Stationarity is just jargon for a condition that encodes if a point is a stationary point for the underlying optimization problem (so in the simplest setting: a condition that encodes how close the gradient is to vanishing) which is of course often used as part of convergence criterion. Here, the default L-BFGS-B method declares convergence when the norm of the projected gradient is < pgtol (=1e-5) but I would like for it to keep going to higher precision in this sense. Sorry, I didn't explain well what my problem was in practice :).

Makes sense now!

If being able to set pgtol (the same way you can set g_tol for Optim) solves your problem, I can just make that an option. Same for the hardcoded factr and m.

I personally only need pgtol right now but I think it could generally be useful to expose all (or at least the common) solver options (since different choices for them can in principle matter a lot). It might not be worth the effort if no-one else uses it, though.

GRAPE is still very much at a pre-1.0 stage of development, so there's a very low bar both for ad-hoc changes and for breaking changes later on to clean up those ad-hoc changes. So I'll just push out a minor release that makes those parameters accessible.

How would having it in the result object help you?
My (possibly incorrect) understanding is that you allow a user to define their own convergence criteria through the check_covergence kwarg by defining a function on result object.

You're totally right (and I kinda forgot). That makes total sense, and is a very good argument for including the gradient in the result object. So I'll probably end up doing that (at some point)

There's infohook for that, in principle, which gets the GrapeWrk object which has access to lots of internal data, including gradient information, although not the LBFGSB optimizer, which might be nice to have. These internals need a pretty major overhaul at some point.

You can definitely abuse the infohook to set convergence. You're not officially supposed to mutate stuff in the infohook, but as long as you understand the internals, you can (like, setting wrk.result.converged to true). So it can be a more powerful replacement for the check_convergence function.

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

No branches or pull requests

2 participants