@@ -131,18 +131,18 @@ def func_b(a, x):
131131 Obs (e.g. results from a previous fit) or strings containing a value and an error formatted like
132132 0.548(23), 500(40) or 0.5(0.4)
133133 silent : bool, optional
134- If true all output to the console is omitted (default False).
134+ If True all output to the console is omitted (default False).
135135 initial_guess : list
136136 can provide an initial guess for the input parameters. Relevant for
137137 non-linear fits with many parameters. In case of correlated fits the guess is used to perform
138138 an uncorrelated fit which then serves as guess for the correlated fit.
139139 method : str, optional
140140 can be used to choose an alternative method for the minimization of chisquare.
141141 The possible methods are the ones which can be used for scipy.optimize.minimize and
142- migrad of iminuit. If no method is specified, Levenberg-Marquard is used.
142+ migrad of iminuit. If no method is specified, Levenberg–Marquardt is used.
143143 Reliable alternatives are migrad, Powell and Nelder-Mead.
144144 tol: float, optional
145- can be used (only for combined fits and methods other than Levenberg-Marquard ) to set the tolerance for convergence
145+ can be used (only for combined fits and methods other than Levenberg–Marquardt ) to set the tolerance for convergence
146146 to a different value to either speed up convergence at the cost of a larger error on the fitted parameters (and possibly
147147 invalid estimates for parameter uncertainties) or smaller values to get more accurate parameter values
148148 The stopping criterion depends on the method, e.g. migrad: edm_max = 0.002 * tol * errordef (EDM criterion: edm < edm_max)
@@ -152,7 +152,7 @@ def func_b(a, x):
152152 In practice the correlation matrix is Cholesky decomposed and inverted (instead of the covariance matrix).
153153 This procedure should be numerically more stable as the correlation matrix is typically better conditioned (Jacobi preconditioning).
154154 inv_chol_cov_matrix [array,list], optional
155- array: shape = (no of y values) X (no of y values)
155+ array: shape = (number of y values) X (number of y values)
156156 list: for an uncombined fit: [""]
157157 for a combined fit: list of keys belonging to the corr_matrix saved in the array, must be the same as the keys of the y dict in alphabetical order
158158 If correlated_fit=True is set as well, can provide an inverse covariance matrix (y errors, dy_f included!) of your own choosing for a correlated fit.
@@ -168,6 +168,9 @@ def func_b(a, x):
168168 If True, a quantile-quantile plot of the fit result is generated (default False).
169169 num_grad : bool
170170 Use numerical differentation instead of automatic differentiation to perform the error propagation (default False).
171+ n_parms : int, optional
172+ Number of fit parameters. Overrides automatic detection of parameter count.
173+ Useful when autodetection fails. Must match the length of initial_guess or priors (if provided).
171174
172175 Returns
173176 -------
@@ -269,26 +272,38 @@ def func_b(a, x):
269272 raise Exception ("No y errors available, run the gamma method first." )
270273
271274 # number of fit parameters
272- n_parms_ls = []
273- for key in key_ls :
274- if not callable (funcd [key ]):
275- raise TypeError ('func (key=' + key + ') is not a function.' )
276- if np .asarray (xd [key ]).shape [- 1 ] != len (yd [key ]):
277- raise ValueError ('x and y input (key=' + key + ') do not have the same length' )
278- for n_loc in range (100 ):
279- try :
280- funcd [key ](np .arange (n_loc ), x_all .T [0 ])
281- except TypeError :
282- continue
283- except IndexError :
284- continue
275+ if 'n_parms' in kwargs :
276+ n_parms = kwargs .get ('n_parms' )
277+ if not isinstance (n_parms , int ):
278+ raise TypeError (
279+ f"'n_parms' must be an integer, got { n_parms !r} "
280+ f"of type { type (n_parms ).__name__ } ."
281+ )
282+ if n_parms <= 0 :
283+ raise ValueError (
284+ f"'n_parms' must be a positive integer, got { n_parms } ."
285+ )
286+ else :
287+ n_parms_ls = []
288+ for key in key_ls :
289+ if not callable (funcd [key ]):
290+ raise TypeError ('func (key=' + key + ') is not a function.' )
291+ if np .asarray (xd [key ]).shape [- 1 ] != len (yd [key ]):
292+ raise ValueError ('x and y input (key=' + key + ') do not have the same length' )
293+ for n_loc in range (100 ):
294+ try :
295+ funcd [key ](np .arange (n_loc ), x_all .T [0 ])
296+ except TypeError :
297+ continue
298+ except IndexError :
299+ continue
300+ else :
301+ break
285302 else :
286- break
287- else :
288- raise RuntimeError ("Fit function (key=" + key + ") is not valid." )
289- n_parms_ls .append (n_loc )
303+ raise RuntimeError ("Fit function (key=" + key + ") is not valid." )
304+ n_parms_ls .append (n_loc )
290305
291- n_parms = max (n_parms_ls )
306+ n_parms = max (n_parms_ls )
292307
293308 if len (key_ls ) > 1 :
294309 for key in key_ls :
@@ -535,17 +550,20 @@ def func(a, x):
535550 It is important that all numpy functions refer to autograd.numpy, otherwise the differentiation
536551 will not work.
537552 silent : bool, optional
538- If true all output to the console is omitted (default False).
553+ If True all output to the console is omitted (default False).
539554 initial_guess : list
540555 can provide an initial guess for the input parameters. Relevant for non-linear
541556 fits with many parameters.
542557 expected_chisquare : bool
543- If true prints the expected chisquare which is
558+ If True prints the expected chisquare which is
544559 corrected by effects caused by correlated input data.
545560 This can take a while as the full correlation matrix
546561 has to be calculated (default False).
547562 num_grad : bool
548- Use numerical differentation instead of automatic differentiation to perform the error propagation (default False).
563+ Use numerical differentiation instead of automatic differentiation to perform the error propagation (default False).
564+ n_parms : int, optional
565+ Number of fit parameters. Overrides automatic detection of parameter count.
566+ Useful when autodetection fails. Must match the length of initial_guess (if provided).
549567
550568 Notes
551569 -----
@@ -575,19 +593,32 @@ def func(a, x):
575593 if not callable (func ):
576594 raise TypeError ('func has to be a function.' )
577595
578- for i in range (42 ):
579- try :
580- func (np .arange (i ), x .T [0 ])
581- except TypeError :
582- continue
583- except IndexError :
584- continue
585- else :
586- break
596+ if 'n_parms' in kwargs :
597+ n_parms = kwargs .get ('n_parms' )
598+ if not isinstance (n_parms , int ):
599+ raise TypeError (
600+ f"'n_parms' must be an integer, got { n_parms !r} "
601+ f"of type { type (n_parms ).__name__ } ."
602+ )
603+ if n_parms <= 0 :
604+ raise ValueError (
605+ f"'n_parms' must be a positive integer, got { n_parms } ."
606+ )
587607 else :
588- raise RuntimeError ("Fit function is not valid." )
608+ for i in range (100 ):
609+ try :
610+ func (np .arange (i ), x .T [0 ])
611+ except TypeError :
612+ continue
613+ except IndexError :
614+ continue
615+ else :
616+ break
617+ else :
618+ raise RuntimeError ("Fit function is not valid." )
619+
620+ n_parms = i
589621
590- n_parms = i
591622 if not silent :
592623 print ('Fit with' , n_parms , 'parameter' + 's' * (n_parms > 1 ))
593624
0 commit comments