I have taken a picture of a chain, sampled the position of every single ring of such chain in pixel, in oreder to get the best-fit pars for a catenary of model a*cosh((x-x0)/a) + c, where a, c and x0 are the pars im looking for.
When plotting my sampled points onto the original pictuare they coincide with the chain, but the pars i get are many thousand times what i'd expect.
from matplotlib import pyplot as plt
from scipy.optimize import curve_fit
import numpy as np
import matplotlib
fname="C:/Users/marti/OneDrive/Desktop/Pier/Catenaria.txt" #directory and file name
plt.xlabel("x [pixels]")
plt.ylabel("y [pixels]")
plt.imshow(img)
x,y=np.loadtxt(fname, unpack=True)
sigma_y=3.
plt.errorbar(x, y, sigma_y, fmt=".")
def cat(x, a, c, x0):
return c + a * np.cosh((x - x0) / a)
popt, pcov = curve_fit(cat, x, y, p0=(1800.,500., 2052.))
a_hat, c_hat, x0_hat = popt
sigma_a, sigma_c, sigma_x0 = np.sqrt(pcov.diagonal())
print(a_hat, sigma_a, c_hat, sigma_c, x0_hat, sigma_x0)
plt.plot(x, cat(x, a_hat, c_hat, x0_hat))
plt.show()
This is the code and the following are the sampled points:
396.6 1055.3
409.4 1079.2
418.3 1103.7
432.1 1129.2
439.4 1157.0
453.2 1180.9
466.0 1204.8
478.2 1229.8
489.3 1251.4
501.6 1277.0
512.7 1303.6
527.7 1328.1
538.8 1354.7
552.1 1378.1
563.2 1404.7
573.2 1424.2
590.4 1450.3
605.4 1478.6
627.7 1515.3
638.8 1536.9
654.3 1563.6
668.2 1587.5
680.4 1610.8
696.0 1636.9
711.0 1659.7
724.3 1681.9
739.9 1706.3
754.8 1728.6
769.3 1752.4
784.3 1775.2
798.7 1798.0
814.8 1819.6
828.2 1842.4
844.8 1862.4
862.6 1885.7
878.2 1908.5
892.0 1930.2
910.9 1953.0
927.6 1973.0
943.1 1996.3
959.8 2016.3
976.5 2036.3
995.9 2057.9
1012.0 2077.4
1029.2 2095.7
1045.3 2115.7
1067.6 2140.7
1088.7 2160.7
1106.4 2181.3
1126.4 2201.8
1149.2 2222.4
1165.3 2239.0
1187.0 2257.3
1204.8 2272.9
1227.0 2290.7
1247.0 2310.7
1270.9 2327.3
1286.4 2340.7
1305.8 2357.3
1329.7 2375.1
1353.6 2394.0
1379.7 2410.7
1398.1 2421.8
1420.3 2435.1
1442.5 2448.4
1466.9 2463.4
1488.6 2475.6
1513.0 2488.4
1537.5 2501.8
1553.6 2510.1
1578.6 2519.5
1606.9 2533.4
1630.8 2544.0
1658.0 2554.5
1680.2 2562.3
1709.1 2574.0
1740.2 2581.7
1766.9 2590.6
1794.6 2596.2
1819.6 2601.7
1844.6 2608.4
1873.0 2611.2
1901.3 2615.1
1925.7 2617.9
1954.1 2620.6
1982.4 2622.9
2006.3 2623.4
2036.8 2624.0
2061.3 2623.4
2086.8 2620.6
2117.4 2620.1
2141.2 2617.3
2167.9 2612.3
2194.6 2609.0
2221.2 2604.0
2250.1 2599.5
2276.8 2594.5
2301.2 2587.3
2333.4 2577.3
2371.2 2565.7
2399.5 2554.6
2422.3 2547.9
2447.8 2539.0
2474.5 2527.9
2497.8 2515.1
2522.8 2504.6
2548.9 2494.0
2573.4 2483.5
2593.9 2467.9
2620.0 2452.9
2647.2 2434.6
2671.1 2419.6
2688.9 2406.3
2710.0 2390.7
2734.4 2377.9
2755.6 2357.9
2777.2 2341.8
2800.5 2323.5
2822.8 2308.5
2844.4 2288.5
2866.6 2269.6
2886.6 2253.0
2908.9 2232.4
2930.5 2212.4
2950.0 2189.7
2969.4 2173.0
2989.4 2154.1
3004.4 2134.7
3023.8 2114.7
3043.3 2093.0
3059.4 2072.5
3076.6 2051.9
3093.8 2033.0
3111.0 2011.9
3128.8 1991.9
3146.0 1968.0
3166.6 1945.8
3182.7 1923.6
3197.1 1903.6
3219.3 1873.6
3239.9 1847.0
3255.5 1823.6
3272.7 1798.1
3291.0 1775.9
3303.2 1750.9
3320.4 1728.1
3334.3 1707.0
3350.4 1683.1
3366.5 1658.7
3378.2 1637.0
3394.3 1612.0
3406.0 1589.2
3420.4 1565.4
3433.2 1541.5
3448.2 1520.9
3462.1 1493.7
3476.0 1469.3
3490.4 1445.9
3505.4 1419.3
3514.3 1397.1
3529.3 1370.4
3541.5 1349.8
3555.4 1321.5
3566.5 1299.3
3578.2 1277.6
3591.5 1254.3
3607.0 1223.2
3617.0 1198.8
3630.4 1172.7
3643.2 1146.6
3654.3 1121.0
3663.1 1098.2
3674.3 1074.3
3687.6 1051.0
I tried to decrease the number of points and the initial values, but nothing changed.
I tried with my own regression software. The fitting is very good.
I cannot say why your calculus failed. I suspect that the "guessed" initial values of the parameters are too far from the correct values. Especially the parameter
a
should be negative.IN ADDITION :
An even better fit would be obtained with the more general cosh function (below four parameters instead of three).
In order to avoid the problems of "guessed" initial values and of convergence of iterative method the results below are obtained with a non-iterative method which doesn't require initial values.
The general principle of this method is explained in https://fr.scribd.com/doc/14674814/Regressions-et-equations-integrales . Since the application to the cosh function isn't treated in the paper the missing algorithm is shown below (Very simple to code in any math software).
Note : The calculus involves numerical integrations for Sk and SSk. This introduces additional deviation depending on the distribution of the points and on the scatter. In the present case the number of points is large and the scatter low. So the deviation due to numerical integration is negligable. Nevertheless if an even better accurate fitting is wanted one can use any non-linear regression software starting the iteration process from the very good values obtained above.