fit results save weight; closes #139

This commit is contained in:
Dominik Demuth 2023-11-13 18:46:46 +01:00
parent f04cadf780
commit 8fb17b22fd
3 changed files with 82 additions and 25 deletions

View File

@ -13,7 +13,7 @@ class Data(object):
if self.y.shape[0] != self.x.shape[0]:
raise ValueError(f'x and y have different lengths {self.x.shape[0]} and {self.y.shape[0]}')
self.we = self._calc_weights(we)
self.we, self.we_string = self._calc_weights(we)
self.idx = idx
self.model = None
self.minimizer = None
@ -24,16 +24,16 @@ class Data(object):
def __len__(self):
return self.y.shape[0]
def _calc_weights(self, we):
if we is None:
return 1.
if isinstance(we, str):
if we == 'y2':
we_func = lambda yy: 1. / yy**2
elif we.lower() == 'none':
def _calc_weights(self, we: str | np.ndarray | None) -> tuple[np.ndarray, str]:
if isinstance(we, str) or we is None:
if we is None or we.lower() == 'none':
we_string = 'None'
we_func = lambda yy: np.ones_like(len(yy))
elif we == 'y2':
we_string = we
we_func = lambda yy: 1. / yy**2
else:
we_string = we
we_func = lambda yy: 1. / np.abs(yy)
if np.iscomplexobj(self.y):
@ -42,6 +42,7 @@ class Data(object):
weights = we_func(self.y)
else:
we_string = 'yerr' # This is pure speculation that array equals error
we = 1. / np.asarray(we)
if np.iscomplexobj(self.y):
if np.iscomplexobj(we):
@ -53,7 +54,7 @@ class Data(object):
weights[weights == np.inf] = np.finfo(float).max
return weights
return weights, we_string
def set_model(self, func, *args, **kwargs):
if isinstance(func, Model):

View File

@ -484,9 +484,18 @@ class FitRoutine(object):
idx = self.data.index(data)
model = data.get_model()
self.result[idx] = FitResultCreator.make_with_model(model, data.x, data.y,
actual_parameters, data.fun_kwargs, data.idx,
*shape, corr=actual_corr, pcorr=actual_pcorr)
self.result[idx] = FitResultCreator.make_with_model(
model,
data.x,
data.y,
actual_parameters,
data.fun_kwargs,
data.we_string,
data.idx,
*shape,
corr=actual_corr,
pcorr=actual_pcorr,
)
return self.result

View File

@ -42,7 +42,19 @@ class FitResultCreator:
kwargs['name'], stats, idx)
@staticmethod
def make_with_model(model, x_orig, y_orig, p, fun_kwargs, idx, nobs, nvar, corr, pcorr) -> FitResult:
def make_with_model(
model: 'Model',
x_orig: np.ndarray,
y_orig: np.ndarray,
p: 'Parameters',
fun_kwargs: dict,
we: str,
idx: str | None,
nobs: int,
nvar: int,
corr: np.ndarray,
pcorr: np.ndarray,
) -> FitResult:
if np.all(x_orig > 0) and (np.max(x_orig) > 100 * np.min(x_orig)):
islog = True
else:
@ -104,10 +116,25 @@ class FitResultCreator:
correlation = corr
partial_correlation = pcorr
return FitResult(_x, _y, x_orig, y_orig, parameters, fun_kwargs, resid,
nobs, nvar, model.name, stats,
idx=idx, corr=correlation, pcorr=partial_correlation,
islog=islog, func=model)
return FitResult(
x=_x,
y=_y,
x_data=x_orig,
y_data=y_orig,
params=parameters,
fun_kwargs=fun_kwargs,
resid=resid,
nobs=nobs,
nvar=nvar,
we=we,
name=model.name,
stats=stats,
idx=idx,
corr=correlation,
pcorr=partial_correlation,
islog=islog,
func=model,
)
@staticmethod
def calc_statistics(y, residual, nobs=None, nvar=None):
@ -145,12 +172,27 @@ class FitResultCreator:
class FitResult(Points):
def __init__(self, x: np.ndarray, y: np.ndarray,
x_data: np.ndarray, y_data: np.ndarray,
params: dict, fun_kwargs: dict,
resid: np.ndarray, nobs: int, nvar: int, name: str, stats: dict,
idx=None, corr=None, pcorr=None, islog=False, func=None,
**kwargs):
def __init__(
self: FitResult,
x: np.ndarray,
y: np.ndarray,
x_data: np.ndarray,
y_data: np.ndarray,
params: dict,
fun_kwargs: dict,
resid: np.ndarray,
nobs: int,
nvar: int,
we: str,
name: str,
stats: dict,
idx: int = None,
corr: np.ndarray = None,
pcorr: np.ndarray = None,
islog: bool = False,
func=None,
**kwargs
):
self.parameter, name = self._prepare_names(params, name)
label = kwargs.get('label', name)
@ -161,6 +203,7 @@ class FitResult(Points):
self.statistics = stats
self.nobs = nobs
self.nvar = nvar
self.we = we
self.fun_kwargs = fun_kwargs
self.correlation = corr
self.partial_correlation = pcorr
@ -229,6 +272,7 @@ class FitResult(Points):
s.write(f' model : {self.name}\n')
s.write(f' #data : {self.nobs}\n')
s.write(f' #var : {self.nvar}\n')
s.write(f' #weight: {self.we}\n')
s.write('\nParameter\n')
s.write(self.parameter_string())
@ -322,10 +366,13 @@ class FitResult(Points):
err = 0.
f.write(f'{p.value:.8e}\t{err:.8e}\t')
f.write('# ')
if self.fun_kwargs:
f.write('# ')
for k, v in self.fun_kwargs.items():
f.write(f"{convert(k, old='tex', new='str')}: {convert(str(v), old='tex', new='str')}\t")
f.write(f'weight: {self.we}\t')
f.write('\n')
f.write(f'# line above from: {self.name} (model: {self.model_name})')
f.write('\n')