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
Sigma keyword for hesse #215
Conversation
@HDembinski - What effect does this have? I.e. which properties / results does this change influence? I think the question here is whether this addition makes the overall situation more or less confusing. Probably an argument could be made either way. On the one hand, it's convenient to set I think whether we merge this addition or not, this is one of the points people (including me) struggle with most, and IMO the most important improvement would be docs additions, e.g. a page or section that explains this (or link to the one in Fred James writeup if available), and then to link to that explanation from all methods / properties that depend on this choice or "up" or "errordef" or "sigma". @HDembinski, @piti118, or @jetteodder from #173 or anyone - Do you think we should add this? Any other thoughts on how to make this point easier / clearer for users? |
@cdeil I value consistency very much. Yes, I think this interface change is a good idea. I studied the Zen of Python carefully. I think it is great design advice and one of the reasons why I love Python. Let's go through it and see what speaks for adding the
This is how it is internally implemented for hesse and minos. For hesse but not for minos, we could even further optimize this internally by skipping the explicit re-calculation of hesse and just scale errors and covariance matrix. "There should be one-- and preferably only one --obvious way to do it." Consistency is so important in design, because it allows you to use the software without reading the documentation. Nobody likes to read the documentation. If an interface is consistent, you rarely have to go back to the documentation to figure out what is going on. It is easier to remember how to do things, because patterns emerge that you learn intuitively. Again, consistency is really really important. It is one of the key features of Python that people fall in love with. We want them to fall in love with iminuit, too, don't we? Btw, it is also one of the reasons why I hate using ROOT, because it is not consistent at all. "Now is better than never."
|
@HDembinski - I don't have an opinion on this change yet, I'm about 50:50 on the proposal. I just want to be careful with changes in iminuit, and if we make them, try to get them as "right" as possible, i.e. do as little changes over the years as possible (given that Minuit is 40? years old and iminuit hasn't been changed in a few years). One concern with adding Another concern is that many people just call My strongest concern here is about Just for reference, this is what we have for Given that already a long time ago this point was mentioned as the number 1 error people make when fitting with Minuit (or in general), @HDembinski - Please comment on the concerns I mentioned, especially the one about whether the @piti118 and all - please give your opinion here. |
@cdeil Please find below answers to all the points you raised.
This is not a change in Minuit itself. This is a useful convenience feature of the iminuit Wrapper. Neither the original
No, it can be made as efficient as doing it by hand. Let me quote myself:
Also, performance is secondary to usability in Python. If you want maximum performance, you wouldn't use Python in the first place.
Yes, it is, I already said so above.
It should be affected. The normal covariance matrix is what you use to error propagate 1 sigma errors. The other covariance matrices can be used to propagate 2 or 3 or N sigma errors. People who want to use this feature will know what to do with it. Everyone else will just use the default, which is
The documentation is bad. The true purpose of errordef in http://iminuit.readthedocs.io/en/latest/api.html?highlight=errordef#iminuit.Minuit.set_up This is just a forward, which I do not like at all.
This I can easily believe without even knowing any statistics about how often users make certain errors. |
…nce matrix in test_set_errordef
As a side remark, I know that trust in someone requires some experience and time, but to raise my credibility somewhat, I would like to say that I spend a good amount of my free time thinking about interface design, and I am very aware of the long-term problems caused by bad design decisions. I am the author of the histogram library, which will be reviewed by the Boost community in a few weeks to decide about including it in Boost. Once the library is in Boost, the interface is fixed and cannot be changed, so I am thinking constantly about how to not make decisions which are limiting us later on. I read several books about design patterns in C++ from Stroustrup, Sutter, Alexandrescu, and Meyers, and Gamma. C++ is a different language, but conceptually the challenges of good design are the same in both languages, Python just uses different idioms. |
@HDembinski and I discussed this at lunch yesterday, and now that I understand the implications better, here's what I think: I'm -1 on adding I admit that it can be a nice convenience if someone wants "2 sigma errors" in their script or interactive analysis session. But I think that when collaborating on scripts with others or re-using scripts from others, this addition will cause problems. Currently Minuit.errors and Minuit.covariance are always "1 sigma" errors. With this "sigma" option in "hesse", "errors" and "covariance" will be "1 sigma" errors in many cases (currently all), but "n sigma" errors sometimes if users start to pass "sigma=n" to "hesse". I find this confusing, especially for the covariance matrix. To also quote from the zen of Python: "There should be one-- and preferably only one --obvious way to do it." @HDembinski - I think the drawbacks of this addition would become more obvious if the PR was complete in the sense that you'd try to accurately describe what is returned in the docstrings of Minuit.errors and Minuit.covariance. It would have to be changed to something like "usually these are "1 sigma errors" or "the normal covariance", but if you called "hesse(sigma=n)", then it's scaled by "n" (for error) or "n^2" (for covariance) already.", no? Just to be clear: I think this proposal and discussion was very useful. I'm just -1 on improving iminuit as proposed here, and the counter-proposal is to improve the docs how to scale errors and covariance instead (and to put in the numpy array versions of those, to make it even easier, as discussed in another issue). |
@cdeil I can counter all your arguments.
When you form an opinion, please fairly consider all the arguments, all pros and cons. That's what I do. I have countered your cons, and there are still pros left. So the rational choice is to accept this change. |
@HDembinski - if you really still think this is a good proposal and want it in, please make the pull request complete so that the implications become more clear. At the very least you need to amend the docstring of the
I don't think we should add such complexity (more ways to do the same thing and state tracking than we already have, i.e. triggering hesse or migrad from values or errors property access). If this is your vision for what to do as long-term solution, I would suggest you do that change here, to show what it looks like. I think it's very relevant to this proposal / decision. As it stands, I think this PR and advertising to users to do multiple calls to hesse to get 1, 2, 3 sigma errors is terrible advice, if they can just do this:
@piti118 - Please comment. |
Closing this request, because @cdeil and I could not agree whether this is a useful feature or not. We will add documentation instead to show how to handle this. |
This addresses issue #173, by making
hesse(...)
andminos(...)
accept asigma
keyword. The effect could be obtained in other ways, but most people do not understand howset_errordef(...)
works, and I don't blame them, it is not obvious. I like thesigma
keyword inminos(...)
, because it is pretty clear.People expect similar things to behave similarly, and hesse and minos are pretty similar. It therefore makes sense to have a similar interface.