I have an interesting problem in Python where I have two functions (arbitrary) and I would like to find a common tangent between them and points on the x axis where the common tangent touches each function. Ideally, there would be a function that gives all the coordinates (imagine a very seductive set of functions with several solutions).
So, I have something that works, but it is very rude. What I did puts each function in a matrix, so it M[h,0]contains the values of x, M[h,1]- the values of the function 1 y, M[h,2]- the values of the function 2 y. Then I find the derivative and put it in a new matrix D[h,1]and D[h,2](the interval is one less than M[h,:]. My idea was to essentially "construct" the slopes along the x axis and intercepts by y and find all these points for the nearest pair, then give values.
Two issues here:
the program does not know whether the next pair is a solution or not, and
it is painfully slow (numb_of_points ^ 2 search). I understand that some optimization libraries may help, but I'm worried that they will hone one solution and ignore the others.
Does anyone think of a better way to do this? My "code" is here:
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)
""" 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
der2 = ediff1d(M[:,2])*x_points
D = zeros(((x_points),9) )
for h in range(D.shape[0]):
D[h,0] = (M[h,0]+M[h+1,0])/2
D[h,1] = der1[h]
D[h,2] = der2[h]
D[h,3] = (M[h,1]+M[h+1,1])/2
D[h,4] = (M[h,2]+M[h+1,2])/2
D[h,5] = D[h,3] - D[h,1]*D[h,0]
D[h,6] = D[h,4] - D[h,2]*D[h,0]
monitor_distance = 5000
for h in range(D.shape[0]):
for w in range(D.shape[0]):
distance = sqrt(
(D[w,6] - D[h,5])**2 +
(D[w,2] - D[h,1])**2
)
if distance < monitor_distance:
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)
It has many applications in materials science, in the search for common tangents between several Gibb functions for calculating phase diagrams. It would be nice to get a reliable feature for everyone to use ...