我在 Python 中有一个有趣的问题,我有两个函数(任意),我想找到它们之间的公切线,以及公切线接触每个函数的 x 轴上的点。理想情况下,会有一个函数给出所有坐标(想象一组非常弯曲的函数,具有多种解决方案)。
所以,我有一些可行的方法,但它非常粗糙。我所做的是将每个函数放入一个矩阵中,因此M[h,0]
包含 x 值,M[h,1]
是 function1 y 值,M[h,2]
是 function2 y 值。然后我找到导数并将其放在一个新矩阵中D[h,1]
并且D[h,2]
(span 比 小一M[h,:]
。我的想法是基本上“绘制”x 轴上的斜率和 y 轴上的截距,并搜索所有这些点对于最接近的对,然后给出值。
这里有两个问题:
程序不知道最接近的对是否是解决方案,并且
它非常缓慢(numb_of_points^2 搜索)。我意识到一些优化库可能会有所帮助,但我担心他们会专注于一种解决方案而忽略其余的解决方案。
任何人都认为最好的方法来做到这一点?我的“代码”在这里:
def common_tangent(T):
x_points = 600
x_start = 0.0001
x_end = 0.9999
M = zeros(((x_points+1),5) )
for h in range(M.shape[0]):
M[h,0] = x_start + ((x_end-x_start)/x_points)*(h) # populate matrix
""" Some function 1 """
M[h,1] = T*M[h,0]**2 + 56 + log(M[h,0])
""" Some function 2 """
M[h,2] = 5*T*M[h,0]**3 + T*M[h,0]**2 - log(M[h,0])
der1 = ediff1d(M[:,1])*x_points # derivative of the first function
der2 = ediff1d(M[:,2])*x_points # derivative of the second function
D = zeros(((x_points),9) )
for h in range(D.shape[0]):
D[h,0] = (M[h,0]+M[h+1,0])/2 # for the der matric, find the point between
D[h,1] = der1[h] # slope m_1 at this point
D[h,2] = der2[h] # slope m_2 at this point
D[h,3] = (M[h,1]+M[h+1,1])/2# average y_1 here
D[h,4] = (M[h,2]+M[h+1,2])/2# average y_2 here
D[h,5] = D[h,3] - D[h,1]*D[h,0] # y-intercept 1
D[h,6] = D[h,4] - D[h,2]*D[h,0] # y-intercept 2
monitor_distance = 5000 # some starting number
for h in range(D.shape[0]):
for w in range(D.shape[0]):
distance = sqrt( #in "slope intercept space" find distance
(D[w,6] - D[h,5])**2 +
(D[w,2] - D[h,1])**2
)
if distance < monitor_distance: # do until the closest is found
monitor_distance = distance
fraction1 = D[h,0]
fraction2 = D[w,0]
slope_02 = D[w,2]
slope_01 = D[h,1]
intercept_01 = D[h,5]
intercept_02 = D[w,6]
return (fraction1, fraction2)
这在材料科学中有很多应用,在寻找多个吉布函数之间的公切线以计算相图。如果能有一个强大的功能供所有人使用,那就太好了……