![]() |
Using curve_fit to optimize function (TypeError) - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: Using curve_fit to optimize function (TypeError) (/thread-34758.html) |
Using curve_fit to optimize function (TypeError) - Laplace12 - Aug-29-2021 Hey! I have some experimental data that I know follows a certain function. My aim is to fit a function (dy) to the data points and get Python to return the offset values. import math import numpy as np import matplotlib.pyplot as plt from scipy.optimize import curve_fit from sympy import Symbol,expand R = 500 angle = [30, 25, 20, 15, 10, 5] anglea = np.array(angle) anglep = np.radians(anglea) mx = [-63.9995, -46.8970, -30.1635, -17.0550, -7.5885, -1.9195] mxp = [ -i for i in mx] rotm = [-22.9025, -17.8256, -12.5980, -7.4375, -2.3605, 2.6498] rotmp = [ -i for i in rotm] detx = [236.3400, 181.8725, 129.9995, 84.7125, 49.6145, 27.5625] dety = [291.7675, 264.1505, 219.0905, 158.4570, 85.4725, 3.4855] rotd = [45.5153, 35.4343, 25.0553, 14.8258, 4.8003, -5.1288] #Theoretical & data plots: #y1 = [500-2*(R/2)*math.cos(x) for x in anglep] #plt.plot(angle, y1, label='Mx') #plt.scatter(angle, mxp, label='Mx data') y2 = [2*R*math.sin(x)*math.cos(x)*math.cos(x) for x in anglep] #plt.plot(angle, y2, label='Dy') plt.scatter(angle, dety, label='Dy data') y3 = [2*R*math.sin(x)*math.sin(x)*math.cos(x) for x in anglep] #plt.plot(angle, y3, label='Dx') plt.scatter(angle, detx, label='Dx data') def dy(x, a, b): y = 2*R*math.sin(x+a)*math.cos(x+a)*math.cos(x+a)+b return y popt1, pcov1 = curve_fit(dy, angle, y2) plt.plot(angle, dy(angle, *popt1), label='Dy: a=%5.3f, b=%5.3f' % tuple(popt1)) plt.xlabel('Alpha') plt.ylabel('Distance (mm)') plt.legend() plt.show()This returns a TypeError: y = 2*R*math.sin(x+a)*math.cos(x+a)*math.cos(x+a)+b TypeError: only length-1 arrays can be converted to Python scalarsSo defining the function this way seems to not work. I wish to get the a & b values returned by the code. x-data is the angle (I'm unsure whether to use 'anglep' which is in radians, or 'angle'), and the experimental y-data is given by y2 (x is the angle). How do I fix the TypeError and get curve_fit to work? Thanks to everyone in advance! RE: Using curve_fit to optimize function (TypeError) - Larz60+ - Aug-29-2021 you haven't passed any arguments to function dy RE: Using curve_fit to optimize function (TypeError) - Laplace12 - Aug-30-2021 (Aug-29-2021, 07:38 PM)Larz60+ Wrote: you haven't passed any arguments to function dy You mean x, a, b? a and b I wish to get optimized by *popt1, do I still need to make some guess about the values then before using curve_fit? I suppose popt1, pcov1 = curve_fit(dy, angle, y2)is incorrect. RE: Using curve_fit to optimize function (TypeError) - Laplace12 - Aug-30-2021 (Aug-30-2021, 05:11 AM)Laplace12 Wrote:(Aug-29-2021, 07:38 PM)Larz60+ Wrote: you haven't passed any arguments to function dy Fixed the TypeError by changing math.sin/math.cos to np.sin/np.cos, apparently it vectorizes the results automatically and there is no error. I have now defined two functions: def dy(x, a, b): y = 2*R*np.sin(x+a)*np.cos(x+a)*np.cos(x+a)+b return y def dx(x, a, c): y = 2*R*np.sin(x+a)*np.sin(x+a)*np.cos(x+a)+c return y popt1, pcov1 = curve_fit(dy, angle, y2) popt2, pcov2 = curve_fit(dx, angle, y3) print(popt1) print(popt2) plt.plot(angle, dy(angle, *popt1), label='Dy: a=%5.3f, b=%5.3f' % tuple(popt1)) plt.plot(angle, dx(angle, *popt2), label='Dx: a=%5.3f, c=%5.3f' % tuple(popt2))but I wish for the 'a' parameter to be the same for both functions (we assume that the offset is the same for both directions). How can this be done using curve_fit? Now the code returns optimized values for a for both functions, but I wish to get just one value that's the same for both. RE: Using curve_fit to optimize function (TypeError) - Larz60+ - Aug-30-2021 Thank you for the info |