Improve error messages when using builtin cost functions
HDembinski opened this issue · 4 comments
There are many ways to make mistakes and use the builtin cost functions incorrectly. The user has to provide the model and it is easy to return an array of incorrect size.
from iminuit import cost, Minuit
from numba_stats import norm
import numpy as np
n = [1, 2, 3]
edges = [0.1, 0.2, 0.3, 0.4]
def model(x, n, a, b):
# oopsi, returned probability per bin instead of scaled cdf
return n * np.diff(norm.cdf(x, a, b))
# return n * norm.cdf(x, a, b) # correct
c = cost.ExtendedBinnedNLL(n, edges, model)
c(1, 2, 3)
This produces a very confusing error message:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
/var/folders/tl/pv6mt7z17tz0stm1fjfg01cc0000gn/T/ipykernel_28667/1963231075.py in <module>
12
13 c = cost.ExtendedBinnedNLL(n, edges, model)
---> 14 c(1, 2, 3)
/usr/local/lib/python3.8/site-packages/iminuit/cost.py in __call__(self, *args)
482 float
483 """
--> 484 r = self._call(args)
485 if self.verbose >= 1:
486 print(args, "->", r)
/usr/local/lib/python3.8/site-packages/iminuit/cost.py in _call(self, args)
1292 else:
1293 n = self._masked
-> 1294 return poisson_chi2(n, mu)
1295
1296
/usr/local/lib/python3.8/site-packages/iminuit/cost.py in poisson_chi2(n, mu)
345 n, mu = np.atleast_1d(n, mu) # type:ignore
346 if mu.dtype in (np.float32, np.float64): # type:ignore
--> 347 return _poisson_chi2_nb(n, mu)
348 # fallback to numpy for float128
349 return _poisson_chi2_np(n, mu)
ValueError: unable to broadcast argument 1 to output array
File "/usr/local/lib/python3.8/site-packages/iminuit/cost.py", line 1,
We need a better error message for this cost function and for others.
Hi @HDembinski,
I would like to work on this issue
Could you please guide me through it?
Thanks
Aman
Ok, first check that you can reproduce this error message with the latest iminuit version. Then you need to setup your computor to develop iminuit, see CONTRIBUTING.md for details.
Once you are ready to develop, try to make sense of src/iminuit/cost.py, which contains all the cost functions. Try to identify the best place where a check can be made that the arrays have the correct expected size and types and if not, raise an informative ValueError at that location.
Note: the cost functions use a deep class hierarchy to avoid duplicating code. Every class that the user interacts with has a chain of base classes. This makes it a bit hard to understand what is happening where. I think that's the greatest challenge here, otherwise this is fairly simple to implement.
It seems this issue did not close automatically after the merge of #863 (as i did not include the prefix "close/fix" in the message).
Yes, indeed, let's close it. Thanks again.