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

Replaced nlopt with scipy in dispersion fitter #457

Merged
merged 5 commits into from
Aug 15, 2022

Conversation

tylerflex
Copy link
Collaborator

In an attempt to remove nlopt from requirements, this PR replaces nlopt with the scipy.optimize.minimize from scipy.

It needs a 2nd pair of eyes on it to make sure I set up the constriaints and various parameters correctly, could you take a look Weiliang?

When running the dispersion fitter tests in test/plugins, I get similar (but slightly worse) final results:

with nlopt

_________________________________ test_dispersion _________________________________
------------------------------ Captured stdout call -------------------------------
best RMS error so far: 3.20e-01 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
-------------------------------- Captured log call --------------------------------
WARNING  rich:fit.py:364 	warning: did not find fit with RMS error under tolerance_rms of 1.00e-02
INFO     rich:fit.py:368 	returning best fit with RMS error 3.20e-01
______________________________ test_dispersion_load _______________________________
------------------------------ Captured stdout call -------------------------------
best RMS error so far: 9.95e-02 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
-------------------------------- Captured log call --------------------------------
WARNING  rich:fit.py:364 	warning: did not find fit with RMS error under tolerance_rms of 1.00e-02
INFO     rich:fit.py:368 	returning best fit with RMS error 9.95e-02
______________________________ test_dispersion_plot _______________________________
------------------------------ Captured stdout call -------------------------------
best RMS error so far: 9.95e-02 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
-------------------------------- Captured log call --------------------------------
WARNING  rich:fit.py:364 	warning: did not find fit with RMS error under tolerance_rms of 1.00e-02
INFO     rich:fit.py:368 	returning best fit with RMS error 9.95e-02
__________________________ test_dispersion_set_wvg_range __________________________
------------------------------ Captured stdout call -------------------------------
best RMS error so far: 2.99e-01 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
-------------------------------- Captured log call --------------------------------
WARNING  rich:fit.py:364 	warning: did not find fit with RMS error under tolerance_rms of 1.00e-02
INFO     rich:fit.py:368 	returning best fit with RMS error 2.99e-01

with scipy:

_________________________________ test_dispersion _________________________________
------------------------------ Captured stdout call -------------------------------
best RMS error so far: 4.05e-01 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
-------------------------------- Captured log call --------------------------------
WARNING  rich:fit.py:364 	warning: did not find fit with RMS error under tolerance_rms of 1.00e-02
INFO     rich:fit.py:368 	returning best fit with RMS error 4.05e-01
______________________________ test_dispersion_load _______________________________
------------------------------ Captured stdout call -------------------------------
best RMS error so far: 9.95e-02 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
-------------------------------- Captured log call --------------------------------
WARNING  rich:fit.py:364 	warning: did not find fit with RMS error under tolerance_rms of 1.00e-02
INFO     rich:fit.py:368 	returning best fit with RMS error 9.95e-02
______________________________ test_dispersion_plot _______________________________
------------------------------ Captured stdout call -------------------------------
best RMS error so far: 9.95e-02 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
-------------------------------- Captured log call --------------------------------
WARNING  rich:fit.py:364 	warning: did not find fit with RMS error under tolerance_rms of 1.00e-02
INFO     rich:fit.py:368 	returning best fit with RMS error 9.95e-02
__________________________ test_dispersion_set_wvg_range __________________________
------------------------------ Captured stdout call -------------------------------
best RMS error so far: 3.31e-01 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
-------------------------------- Captured log call --------------------------------
WARNING  rich:fit.py:364 	warning: did not find fit with RMS error under tolerance_rms of 1.00e-02
INFO     rich:fit.py:368 	returning best fit with RMS error 3.31e-01

@momchil-flex
Copy link
Collaborator

What about having the option to use nlopt if installed, and using that on our webservice?

@weiliangjin2021
Copy link
Collaborator

What about having the option to use nlopt if installed, and using that on our webservice?

Webservice is largely independent of frontend code except for medium. So we can use NLOPT in webservice as long as we add NLOPT as requirement in webservice part independently.

@momchil-flex
Copy link
Collaborator

Well we need to keep the code that uses nlopt in here. I don't think we should have special code for the webservice. So what I'm suggesting is an extra parameter to the fit function, like optimizer = ["scipy", "nlopt"] or something (could be even more specific to which optimize function exactly to use from these packages), and in the webservice we just use the nlopt one. We can remove nlopt as a general dependence and raise an appropriate error prompting the user to try to install it if someone tries to run the fitter locally with nlopt optimizer and nlopt missing.

@tylerflex
Copy link
Collaborator Author

tylerflex commented Aug 5, 2022 via email

@momchil-flex
Copy link
Collaborator

Well, sure, but I'm dubious we'll be able to (there's a reason nlopt exists...)

@tylerflex
Copy link
Collaborator Author

tylerflex commented Aug 5, 2022 via email

@weiliangjin2021
Copy link
Collaborator

One issue I read from scipy doc is that constraints only workfor COBYLA, SLSQP and trust-constr. So we need to check if we switch from Nelder-Mead to any of those algorithm, will the optimization be fast and converge to good result?

@weiliangjin2021
Copy link
Collaborator

weiliangjin2021 commented Aug 8, 2022

Looks good, but we shouldn't change anything in fit_web.py yet. The webserivce will still be using NLOPT for now, and changing it will cause compatibility issue. Other than that, feel free to merge.

@tylerflex
Copy link
Collaborator Author

Thanks @weiliangjin2021 , I guess the remaining question is how we should test how scipy works vs. nlopt. or whether this is even necessary with Momchil's recent changes in #452. I guess the main advantage of removing nlopt is to make it less likely users will have installation problems, like #441 , but if the performance of the fit is much worse, it's probably not worth it. If we test on the notebooks and test_plugins.py is that enough to say for sure that the scipy optimizer is working adequately?

@weiliangjin2021
Copy link
Collaborator

I think the test should be purely on webservice side, so nlopt can be completely removed from the fronted part.

@momchil-flex
Copy link
Collaborator

So can we go ahead and wrap this up?

@weiliangjin2021
Copy link
Collaborator

For the frontend, it should be good to go.

@tylerflex tylerflex merged commit 8bb8505 into develop Aug 15, 2022
@tylerflex tylerflex deleted the feature/scipy_fitter branch August 15, 2022 16:03
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