Search code examples
pythonscipymatchcurve

Optimizing curve shifting parameters


I want to shift a master curve upward (or downward) along Y axis to best fit a series of data points. I want to minimize the sum of errors (sum_error) between master curve datapoints and measured datapoints by only the upward (or downward) movement of the master curve and get the movement coefficient (let's say K).

master_curve = np.array([3.920443406036651, 2.7639821779105542,
2.254338877722025,  1.9513837218071342, 1.7450166671832754,
1.5928839897758424, 1.4747653105080576, 1.3796281282142924,
1.3008753435392029, 1.234288351142671,  1.1770273049744642,
1.1271011783216718, 1.0830672127478984, 1.0438509579431305,
1.0086336030441687, 0.9767787536056324, 0.9477833091755259,
0.9212435957417907, 0.8968314534272098, 0.8742769964680429])

data = np.array([12.82398603780653, 8.708265346706627,
6.943916634340093,  5.913441041271008,  5.220678298445037,
4.7153411130496306, 4.326441800656878,  4.015585602454473,
3.7599836807770317, 3.5451576271700658, 3.3614170020938596,
3.2020029881204284, 3.0620410438719667, 2.9379167363509975,
2.8268866460269106, 2.72682649883558,   2.6360628206802112,
2.5532572707864203, 2.477325238639876,  2.4073773335594093])

for i in range(len(data)):    
    error[i] = np.abs(master_curve[i]-data[i])
sum_error = error.sum()

I was thinking of using scipy.optimize.minimize but I dont know how to get the K parameter value when sum_error is minimized. I also have to do this for multiple datasets for one master curve and I have 70 master curves and 270 datasets! and I only can think of two "for" loops inside each other.

Thanks for your help.

see this picture, K is kind of a restriction for minimizing function:

curve shifting


Solution

  • There is no need for using scipy minimisation. This is much easier than that. Your actual answer for k is just: np.mean(master_curve-data) i.e. -2.9244855211176906. This is because of the way you have set up the calculation of the mean.

    k = np.linspace(-5, 5, 100)
    errors = np.array([np.mean((master_curve - data + m)) for m in k])
    plt.plot(k, errors)
    

    You should see something like the following:

    error as a function of <code>k</code>

    Now where is this error minimised?? Fit a poly-line and find the y-intercrpt:

    >>> np.polyfit(k, errors, 2)
    array([ -5.67339604e-16,   1.00000000e+00,  -2.92448552e+00])
    

    As you can see, the y-intercept is -2.92448552e+00. Exactly what you wanted in the first place by taking the mean of the difference ...