Hi Matt.
I hadn't noticed that the intention was to show that one can pass an array of uncertainty values.
Maybe I am missing something, but what I find strange of using eps_data both as noise and as uncertainty is:
Well, those are the same thing, at least to my way of thinking. We want to weight the difference between the model and data by the noise in the data.
a) The uncertainty values are random. Every measuring device I know has a well defined (I do not mean constant) uncertainty.
Uh, well, there will be fluctuations and many measurements have noise that scales with intensity ("square root of intensity" is fairly common for pulse counting measurements), or may scale with measurement time or other external factors. So, there can be some variation in the uncertainty for a set of measurements. Granted, most of the time you will know an "uncertainty scale" well before you know individual uncertainties, but ometimes, people know those uncertainties pretty well.
b) Some uncertainty values are negative (eps_data is distributed around 0)
That is a problem! and should be fixed.
c) For each point, the values of the noise and uncertainty are *exactly* the same
Yeah, we're making up a case where we know what the uncertainties are. It seems completely reasonable to have a different array for the uncertainties so that it is not exactly the same as the noise we add.
I'd expect the residuals to be normally distributed around zero, but the output from this snippet is a uniform array of ones :
# Initialize the parameters with the values used to generate the simulated data
params = Parameters()
params.add('amp', value=7.5)
params.add('decay', value=0.01)
params.add('phase', value=2.5)
params.add('frequency', value=0.22)
res = residual(params, x, data, eps_data)
print("Sum of residuals ", res.sum())
print(res)
Supposing the data would have been obtained from an instrument that has a constant-uncertainty, the change I propose would be to replace these two lines:
eps_data = random.normal(size=x.size, scale=0.2)
data = 7.5 * sin(x*0.22 + 2.5) * exp(-x*x*0.01) + eps_data
by these three lines:
uncertainty = 0.2
noise = random.normal(size=x.size, scale=uncertainty)
data = 7.5 * sin(x*0.22 + 2.5) * exp(-x*x*0.01) + noise
And the line:
out = minimize(residual, params, args=(x, data, eps_data))
by:
out = minimize(residual, params, args=(x, data, uncertainty))
I'd have to think of a better example in order to show that one can pass an array of uncertainty values.
It could be something like (or better suggestions welcome):
from numpy import random
noise = random.normal(size=x.size, scale=0.2)
uncertainty = abs(0.16 + random.normal(size=x.size, scale=0.05))
and use `noise` to add to data and `uncertainty` for the weighting?
I think that would help the explanation and still allow that `uncertainty` can be an array with different values per measurement. If you are up for making a PR that improves that more, and for adding some explanation to the doc, that would be great!
Best regards,
Andrés