Search code examples
pythonnumpynumerictranscendental-equation

Find root of a transcendental equation with python


I have to solve the following transcendental equation

cos(x)/x=c

for given constant c.

For example I did a short code in Mathematica, where I generated a list of random values for constant c

const = Table[RandomReal[{0, 5}], {i, 1, 10}]

(*{1.67826, 0.616656, 0.290878, 1.10592, 0.0645222, 0.333932, 3.59584, \
2.70337, 3.91535, 2.78268}*)

Than I defined the function

f[x_, i_] := Cos[x]/x - const[[i]]

and started looking for the roots:

Table[FindRoot[f[x, i] == 0, {x, 0.1}][[1, 2]], {i, 1, Length[const]}]
(*{0.517757, 0.947103, 1.21086, 0.694679, 1.47545, 1.16956, 0.26816, \
0.347764, 0.247615, 0.338922}*)

Now I would love to programme something similar in python (probably using numpy?) but I can't really find any good existing answer to a problem like that. Could somebody help?


Solution

  • One way that I have achieved this in the past is to use scipy.optimize.minimize to find the minima of the squared function.

    from scipy.optimize import minimize
    from numpy import cos
    
    def opt_fun(x, c):
        return (cos(x)/x - c)**2
    
    const = 1.2
    res = minimize(lambda x: opt_fun(x, const), x0=0.001)
    
    # Check if the optimization was successful
    print(res.success)
    # >> True
    
    # Extract the root from the minimization result
    print(res.x[0])
    # >> 0.65889256782472172
    

    This is by no means fool-proof, but it can be quick and accurate. If there are multiple roots, for instance, minimize will find the one in the 'downhill direction' from the initial point you select which is why I've chosen a small positive value above.

    One other issue to keep an eye out for, which is always true with minimization problems, is numbers with dramatically different orders of magnitude. In your equation, as c gets very large, the first positive root gets very small. If you wind up trying to find roots in that circumstance, you may need to scale both x to be near to 1 in order to get accurate results (an example here).