I have a function that draws a line based on input values (which are all floats) and finds a numerical value for B_slv using the sympy function 'nsolve'. The value it finds is correct, but the calculation time is too high as the number of function calls is also high. Is there a way to improve the speed of this calculation? Sacrificing precision for speed is not an issue in many cases.
def cord_line_function(x1,y1,x2,y2, H, w, accuracy, B_old):
from sympy import symbols, nsolve, cosh, solve
from numpy import linspace, sinh
from numpy import cosh as npcosh
# Solve for B . Start with the initial estimation B_old in the iterative process:
if not(isnan(B_old)):
B_estimate = B_old
else:
B_estimate = -0.5*(x2-x1)
B = symbols('B')
B_slv = float(nsolve((H/w * (cosh(w*(x1+B)/H)-1) - y1) - (H/w *
(cosh(w*(x2+B)/H)-1) - y2), B, B_estimate, quick = True))
# return a function based on the found values:
x = linspace(float(x1), float(x2), int((x2-x1)*accuracy))
y = H/w * (npcosh(w*(x+B_slv)/H)-1)
# since the first point of the graph is set as 0, we know that y_real = y - y[0]
y = y - y[0]
# The cord length would be given by L:
# L = Σ sqrt(dx^2 + dy^2) = ∫sqrt(1 + (dy/dx)^2)dx
# Since y = H/w * (cosh(w*(x+B)/H)-1) - A
# dy/dx = sinh(w*(x+B)/H)
# gives: L = ∫sqrt(1+(sinh(w*(x+B)/H))^2) dx
# = ∫sqrt(1+(sinh(w*u /H))^2) du with u = B+x ; du = dx
# = H/w ∫sqrt(1+(sinh(s) )^2) ds with s=w*u/H ; ds = w/H * du
# = H/w ∫sqrt( cosh(s) ^2) ds
# = H/w ∫ cosh(s) ds
# = H/w * sinh(s) + Constant
s1 = w*(x1+B_slv)/H
s2 = w*(x2+B_slv)/H
length = H/w * sinh(s2) - H/w * sinh(s1)
return [x, y, length, B_slv]