forked from IPKM/nmreval
fit results save weight; closes #139
This commit is contained in:
parent
f04cadf780
commit
8fb17b22fd
@ -13,7 +13,7 @@ class Data(object):
|
|||||||
if self.y.shape[0] != self.x.shape[0]:
|
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]}')
|
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.idx = idx
|
||||||
self.model = None
|
self.model = None
|
||||||
self.minimizer = None
|
self.minimizer = None
|
||||||
@ -24,16 +24,16 @@ class Data(object):
|
|||||||
def __len__(self):
|
def __len__(self):
|
||||||
return self.y.shape[0]
|
return self.y.shape[0]
|
||||||
|
|
||||||
def _calc_weights(self, we):
|
def _calc_weights(self, we: str | np.ndarray | None) -> tuple[np.ndarray, str]:
|
||||||
if we is None:
|
if isinstance(we, str) or we is None:
|
||||||
return 1.
|
if we is None or we.lower() == 'none':
|
||||||
|
we_string = 'None'
|
||||||
if isinstance(we, str):
|
|
||||||
if we == 'y2':
|
|
||||||
we_func = lambda yy: 1. / yy**2
|
|
||||||
elif we.lower() == 'none':
|
|
||||||
we_func = lambda yy: np.ones_like(len(yy))
|
we_func = lambda yy: np.ones_like(len(yy))
|
||||||
|
elif we == 'y2':
|
||||||
|
we_string = we
|
||||||
|
we_func = lambda yy: 1. / yy**2
|
||||||
else:
|
else:
|
||||||
|
we_string = we
|
||||||
we_func = lambda yy: 1. / np.abs(yy)
|
we_func = lambda yy: 1. / np.abs(yy)
|
||||||
|
|
||||||
if np.iscomplexobj(self.y):
|
if np.iscomplexobj(self.y):
|
||||||
@ -42,6 +42,7 @@ class Data(object):
|
|||||||
weights = we_func(self.y)
|
weights = we_func(self.y)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
we_string = 'yerr' # This is pure speculation that array equals error
|
||||||
we = 1. / np.asarray(we)
|
we = 1. / np.asarray(we)
|
||||||
if np.iscomplexobj(self.y):
|
if np.iscomplexobj(self.y):
|
||||||
if np.iscomplexobj(we):
|
if np.iscomplexobj(we):
|
||||||
@ -53,7 +54,7 @@ class Data(object):
|
|||||||
|
|
||||||
weights[weights == np.inf] = np.finfo(float).max
|
weights[weights == np.inf] = np.finfo(float).max
|
||||||
|
|
||||||
return weights
|
return weights, we_string
|
||||||
|
|
||||||
def set_model(self, func, *args, **kwargs):
|
def set_model(self, func, *args, **kwargs):
|
||||||
if isinstance(func, Model):
|
if isinstance(func, Model):
|
||||||
|
@ -484,9 +484,18 @@ class FitRoutine(object):
|
|||||||
idx = self.data.index(data)
|
idx = self.data.index(data)
|
||||||
model = data.get_model()
|
model = data.get_model()
|
||||||
|
|
||||||
self.result[idx] = FitResultCreator.make_with_model(model, data.x, data.y,
|
self.result[idx] = FitResultCreator.make_with_model(
|
||||||
actual_parameters, data.fun_kwargs, data.idx,
|
model,
|
||||||
*shape, corr=actual_corr, pcorr=actual_pcorr)
|
data.x,
|
||||||
|
data.y,
|
||||||
|
actual_parameters,
|
||||||
|
data.fun_kwargs,
|
||||||
|
data.we_string,
|
||||||
|
data.idx,
|
||||||
|
*shape,
|
||||||
|
corr=actual_corr,
|
||||||
|
pcorr=actual_pcorr,
|
||||||
|
)
|
||||||
|
|
||||||
return self.result
|
return self.result
|
||||||
|
|
||||||
|
@ -42,7 +42,19 @@ class FitResultCreator:
|
|||||||
kwargs['name'], stats, idx)
|
kwargs['name'], stats, idx)
|
||||||
|
|
||||||
@staticmethod
|
@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)):
|
if np.all(x_orig > 0) and (np.max(x_orig) > 100 * np.min(x_orig)):
|
||||||
islog = True
|
islog = True
|
||||||
else:
|
else:
|
||||||
@ -104,10 +116,25 @@ class FitResultCreator:
|
|||||||
correlation = corr
|
correlation = corr
|
||||||
partial_correlation = pcorr
|
partial_correlation = pcorr
|
||||||
|
|
||||||
return FitResult(_x, _y, x_orig, y_orig, parameters, fun_kwargs, resid,
|
return FitResult(
|
||||||
nobs, nvar, model.name, stats,
|
x=_x,
|
||||||
idx=idx, corr=correlation, pcorr=partial_correlation,
|
y=_y,
|
||||||
islog=islog, func=model)
|
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
|
@staticmethod
|
||||||
def calc_statistics(y, residual, nobs=None, nvar=None):
|
def calc_statistics(y, residual, nobs=None, nvar=None):
|
||||||
@ -145,12 +172,27 @@ class FitResultCreator:
|
|||||||
|
|
||||||
class FitResult(Points):
|
class FitResult(Points):
|
||||||
|
|
||||||
def __init__(self, x: np.ndarray, y: np.ndarray,
|
def __init__(
|
||||||
x_data: np.ndarray, y_data: np.ndarray,
|
self: FitResult,
|
||||||
params: dict, fun_kwargs: dict,
|
x: np.ndarray,
|
||||||
resid: np.ndarray, nobs: int, nvar: int, name: str, stats: dict,
|
y: np.ndarray,
|
||||||
idx=None, corr=None, pcorr=None, islog=False, func=None,
|
x_data: np.ndarray,
|
||||||
**kwargs):
|
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)
|
self.parameter, name = self._prepare_names(params, name)
|
||||||
label = kwargs.get('label', name)
|
label = kwargs.get('label', name)
|
||||||
@ -161,6 +203,7 @@ class FitResult(Points):
|
|||||||
self.statistics = stats
|
self.statistics = stats
|
||||||
self.nobs = nobs
|
self.nobs = nobs
|
||||||
self.nvar = nvar
|
self.nvar = nvar
|
||||||
|
self.we = we
|
||||||
self.fun_kwargs = fun_kwargs
|
self.fun_kwargs = fun_kwargs
|
||||||
self.correlation = corr
|
self.correlation = corr
|
||||||
self.partial_correlation = pcorr
|
self.partial_correlation = pcorr
|
||||||
@ -229,6 +272,7 @@ class FitResult(Points):
|
|||||||
s.write(f' model : {self.name}\n')
|
s.write(f' model : {self.name}\n')
|
||||||
s.write(f' #data : {self.nobs}\n')
|
s.write(f' #data : {self.nobs}\n')
|
||||||
s.write(f' #var : {self.nvar}\n')
|
s.write(f' #var : {self.nvar}\n')
|
||||||
|
s.write(f' #weight: {self.we}\n')
|
||||||
s.write('\nParameter\n')
|
s.write('\nParameter\n')
|
||||||
s.write(self.parameter_string())
|
s.write(self.parameter_string())
|
||||||
|
|
||||||
@ -322,10 +366,13 @@ class FitResult(Points):
|
|||||||
err = 0.
|
err = 0.
|
||||||
f.write(f'{p.value:.8e}\t{err:.8e}\t')
|
f.write(f'{p.value:.8e}\t{err:.8e}\t')
|
||||||
|
|
||||||
|
f.write('# ')
|
||||||
if self.fun_kwargs:
|
if self.fun_kwargs:
|
||||||
f.write('# ')
|
|
||||||
for k, v in self.fun_kwargs.items():
|
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"{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('\n')
|
||||||
f.write(f'# line above from: {self.name} (model: {self.model_name})')
|
f.write(f'# line above from: {self.name} (model: {self.model_name})')
|
||||||
f.write('\n')
|
f.write('\n')
|
||||||
|
Loading…
Reference in New Issue
Block a user