I would like to perform multivariate fit using iminuit. Everything works fine when I use two dimensions but I get an 'ValueError: too many values to unpack (expected 2)' if I use more than two dimensions.
Below is the working code for 2D fit:
from iminuit import Minuit
from iminuit.cost import LeastSquares
import numpy as np
def model1(xy, a, b, c):
x, y = xy
return a + (x ** b) + (y ** c)
np.random.seed(1)
data_x = np.linspace(0, 1, 10)
data_y = np.linspace(0, 1, 10)
data_terr = 0.1
data_t1 = model1([data_x,data_y], 2, 3, 10) + data_terr * np.random.randn(len(data_x))
least_squares = LeastSquares([data_x,data_y], data_t1, data_terr, model1)
m1 = Minuit(least_squares, a=1.0, b=1.0, c=1.0)
m1.migrad()
The problem occurs for 3D fit as demonstrated below:
from iminuit import Minuit
from iminuit.cost import LeastSquares
import numpy as np
def model2(xyz, a, b, c, d):
x, y, z = xyz
return a + (x ** b) + (y ** c) + (z ** d)
np.random.seed(1)
data_x = np.linspace(0, 1, 10)
data_y = np.linspace(0, 1, 10)
data_z = np.linspace(0, 1, 10)
data_terr = 0.1
data_t2 = model2([data_x,data_y, data_z], 2, 3, 10, 20) + data_terr * np.random.randn(len(data_x))
least_squares = LeastSquares([data_x, data_y, data_z], data_t2, data_terr, model2)
m2 = Minuit(least_squares, a=1.0, b=1.0, c=1.0, d=1.0)
m2.migrad()
With the error output
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[30], line 16
13 least_squares = LeastSquares([data_x, data_y, data_z], data_t2, data_terr, model2)
15 m2 = Minuit(least_squares, a=1.0, b=1.0, c=1.0, d=1.0)
---> 16 m2.migrad()
File ~/anaconda3/envs/minuit_fitting/lib/python3.9/site-packages/iminuit/minuit.py:702, in Minuit.migrad(self, ncall, iterate)
700 if self._precision is not None:
701 migrad.precision = self._precision
--> 702 fm = migrad(ncall, self._tolerance)
703 if fm.is_valid or fm.has_reached_call_limit:
704 break
File ~/anaconda3/envs/minuit_fitting/lib/python3.9/site-packages/iminuit/cost.py:594, in Cost.__call__(self, *args)
579 def __call__(self, *args: float) -> float:
580 """
581 Evaluate the cost function.
582
(...)
592 float
593 """
--> 594 r = self._call(args)
595 if self.verbose >= 1:
596 print(args, "->", r)
File ~/anaconda3/envs/minuit_fitting/lib/python3.9/site-packages/iminuit/cost.py:1721, in LeastSquares._call(self, args)
1719 def _call(self, args: Sequence[float]) -> float:
1720 x = self._masked.T[0] if self._ndim == 1 else self._masked.T[: self._ndim]
-> 1721 y, yerror = self._masked.T[self._ndim :]
1722 ym = self._model(x, *args)
1723 ym = _normalize_model_output(ym)
ValueError: too many values to unpack (expected 2)
Could you please point me out what I am doing wrong ? Any help would be appreciated.