scikit-hep/iminuit

LeastSquares.visualize fails for model functions which accept arrays of parameters

jlabounty opened this issue · 2 comments

Hello,

After the quick bug fix regarding pickling, I was excited to upgrade to the latest version and try the new interactive fitting. However, I noticed that the visualize() method for the LeastSquares cost function only works when each parameter is an individual argument rather than a numpy array

def func1(x,p): #fails
    return x*p[1] + p[0]

def func2(x,p0,p1): #works great
    return x*p1 + p0

The traceback I get when executing this python code

cost1 = LeastSquares(xs,ys,np.ones_like(xs),func1)
m1 = iminuit.Minuit(cost1, [2,2])

m1.migrad()
cost1.visualize([2,2])

is:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/home/jlab/github/g2_analysis/analysis/interactive.ipynb Cell 7 in <cell line: 1>()
----> [1](vscode-notebook-cell://wsl%2Bubuntu-20.04/home/jlab/github/g2_analysis/analysis/interactive.ipynb#ch0000010vscode-remote?line=0) cost1.visualize([2,2])

File ~/miniconda3/envs/gm2/lib/python3.10/site-packages/iminuit/cost.py:1447, in LeastSquares.visualize(self, args, model_points)
   1445     ym = self.model(xm, *args)
   1446 else:
-> 1447     xm, ym = _smart_sampling(lambda x: self.model(x, *args), x[0], x[-1])
   1448 plt.plot(xm, ym)

File ~/miniconda3/envs/gm2/lib/python3.10/site-packages/iminuit/util.py:1453, in _smart_sampling(f, xmin, xmax, start, tol)
   1451 def _smart_sampling(f, xmin, xmax, start=5, tol=5e-3):
   1452     x = np.linspace(xmin, xmax, start)
-> 1453     ynew = f(x)
   1454     ymin = np.min(ynew)
   1455     ymax = np.max(ynew)

File ~/miniconda3/envs/gm2/lib/python3.10/site-packages/iminuit/cost.py:1447, in LeastSquares.visualize.<locals>.<lambda>(x)
   1445     ym = self.model(xm, *args)
   1446 else:
-> 1447     xm, ym = _smart_sampling(lambda x: self.model(x, *args), x[0], x[-1])
   1448 plt.plot(xm, ym)

TypeError: func1() takes 2 positional arguments but 3 were given

Because of this, the visualization in Minuit.interactive() also fails. I've uploaded a notebook here showing the issue in more detail.

Thanks for all the work that goes into maintaining this project!

I should add that I am running iminuit version 2.15.1

Thanks for the report. Yes, visualize currently does not support cost functions that accept an array, but this can and should be implemented. That limitation should have been documented.