How to ues fsolve to find the root of function with multiple returns in python?

293 views Asked by At

I have a function as below:

def fun_root(x, *pars):
    a, b, fsolve = pars
    exp1 = x**a - b*x + 2
    exp2 = np.exp(a*x) + x**b 
    if fsolve == 1:
        return exp1-exp2
    elif fsolve == 0:
        return exp2

And I use the following code to find the value of exp2 with fsolve given root.:


tuple1 = (2, 3)
tuple2 = tuple1 + (1,)
tuple3 = tuple1 + (0,)
result_x = scipy.optimize.fsolve(fun_root, np.array((1)), tuple2)
print(result_x)
result_exp2 = fun_root(result_x, tuple3)
print(result_exp2)

I can get one root, which is 0.189. However, I get an error message regarding the line before the last:

a, b, fsolve = pars
ValueError: not enough values to unpack (expected 3, got 1)

What is the problem in the code above?

Ps. I use optional returns in the function since in my real case the function is complicated and I cannot get an explicit expression of exp2.

1

There are 1 answers

0
Warren Weckesser On

In this line

result_x = scipy.optimize.fsolve(fun_root, np.array((1)), tuple2)

you are passing tuple2 as the args parameter of fsolve. The function fsolve will unpack that tuple for you when it calls fun_root.

In this line

result_exp2 = fun_root(result_x, tuple3)

you are passing tuple3 (a single python object that happens to be a tuple) to fun_root. In this case, args will be ((2, 3, 0),). That is, it will be tuple of length 1, containing the tuple that you passed in. Based on the line that causes the error, it is clear that what you want to do is unpack tuple3 in the call of fun_root, so the line should be

result_exp2 = fun_root(result_x, *tuple3)

A less elegant way to accomplish the same result is

result_exp2 = fun_root(result_x, tuple3[0], tuple3[1], tuple3[2])