<jupyter_start><jupyter_text>UncertaintiesUncertainties in the MinKit package are computed using the Hessian matrix. A more accurate uncertainty can be obtained by minimizing a PDF for several fixed values of a parameter(s). In Minuit, this is done using MINOS. However, MinKit provides a dedicated function to evaluate asymmetric uncertainties. The result is identical to that of MINOS, as can be see in the following example:<jupyter_code>%matplotlib inline
import matplotlib.pyplot as plt
import minkit
import numpy as np

from scipy.interpolate import make_interp_spline

m = minkit.Parameter('m', bounds=(10, 30))
c = minkit.Parameter('c', 20, bounds=(15, 25))
s = minkit.Parameter('s', 5, bounds=(3, 10))
g = minkit.Gaussian('g', m, c, s)

data = g.generate(200)

# Calculate the profile and the distance to the minimum
values = np.linspace(*s.bounds, 1000)

with minkit.minimizer('uml', g, data) as minimizer:
  
    r = minimizer.minimize()
    
    minimizer.minos('s') # minos must run before so the internal state of the minimum is set
    
    smn = s.copy()
    
    minimizer.minuit.print_level = 0 # reduce the verbosity of Minuit
    profile = minimizer.minimization_profile('s', values)
    minimizer.asymmetric_errors('s')
    
    skt = s.copy()

# Split in left and right parts
distances = profile - r.fcn

cond = (values < s.value)

left_values = values[cond]
left_distances = distances[cond]
right_values = values[~cond]
right_distances = distances[~cond]

# Calculate the position where the FCN varies one unit
left_int = make_interp_spline(left_distances[::-1], left_values[::-1])
right_int = make_interp_spline(right_distances, right_values)

lv, rv = left_int(1), right_int(1)

# Plot the results
fmin, fmax = 0.99 * profile.min(), profile.max()

fig, ax = plt.subplots(1, 1, figsize=(6, 4))
ax.plot(values, profile);
ax.plot([s.value], [r.fcn], marker='o', color='red');
ax.plot((lv, lv), (fmin, fmax), 'r-', )
ax.plot((rv, rv), (fmin, fmax), 'r-', )
ax.set_xlabel('s');
ax.set_ylabel('FCN');
ax.set_xlim(*s.bounds)
ax.set_ylim(fmin, fmax);

# Show the result from the different methods
print(f'Value (profile): {s.value:.4f} + {rv - s.value:.4f} - {s.value - lv:.4f}')
print(f'Value (minkit):  {skt.value:.4f} + {skt.asym_errors[1]:.4f} - {skt.asym_errors[0]:.4f}')
print(f'Value (minos):   {smn.value:.4f} + {smn.asym_errors[1]:.4f} - {smn.asym_errors[0]:.4f}')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.14545454545454545, 'fraction_numerical': 0.019008264462809916, 'mean_word_length': 4.750593824228028, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '456566', 'license': 'MIT-0', 'n_tokens_mistral': 928, 'n_tokens_neox': 891, 'n_words': 245, 'path': 'docs/source/notebooks/uncertainties.ipynb', 'repo_name': 'mramospe/minkit', 'size': '2420'}