Finding all roots of an equation in Python
Question: I have a function that I want to find its roots. I could write a program to
figure out its roots but the point is, each time that I want to find the other
root I should give it an initial value manually which I do not want to do
that. I want to have all the roots in a list since I want to do some
operations on the roots after finding them. This is my code:

    
    
    import math
    import scipy
    import scipy.optimize
    c = 5
    alambda = 1
    rho = 0.8
    b = rho * c / alambda
    def f(zeta):
        y = ((zeta**c)*(math.exp((alambda*b)*(1-zeta)))) - 1
        return y
    
    print scipy.optimize.newton(f,  -1)
    


Answer: For integer `c`, the roots of the function are given by the Lambert W
function, <https://en.wikipedia.org/wiki/Lambert_W_function>

    
    
    from numpy import exp, pi
    from scipy.special import lambertw
    c = 3
    alambda = 1.234
    rho = 0.8
    b = rho * c / alambda
    def f(zeta):
        y = ((zeta**c)*(exp((alambda*b)*(1-zeta)))) - 1
        return y
    def zeta_root(k, n):
        a = alambda
        return -c/(a*b) * lambertw(-a*b/c * exp(-(a*b+2j*pi*n)/c), k=k)
    for k in range(-20, 20):
        # also n can be any integer; probably reproduces the same root set
        # as varying k
        zeta = zeta_root(k, 3)
        print("k={0}, zeta={1}, error={2}".format(k, zeta, abs(f(zeta))))
    

The equation has an infinite number of complex-valued roots. The `k=0` and
`k=-1` roots which correspond to real branches of the Lambert W function may
be real-valued.

For non-integer `c` the situation seems a bit more complicated due to the
extra branch cut, although at least the real-valued positive roots should be
captured.

