qinqinxiaoguai
qinqinxiaoguai

Reputation: 13

Is there any function in python similar to fzero in matlab?

I want to solve the following equation in python.

equation

It can be implemented in Matlab by fzero function as follows:

    K=5;
    H=6;
    u=100;
    fun=@(x) -(K*(-H+log(1+H/x)*(x+H)))/(log(2)*x^2*(log2((x+H)/x))^2*(x+H))+u;
    xx=fzero(fun,[1e-3,1])

However, I can't find a suitable function in python. scipy.optimize.fsolve needs the initial value. Moreover, it is always with unexplained errors. Could you please tell me how to implement it in python?

The python code is as follows:

import math
from scipy.optimize import fsolve
K=5
H=6
u=100
def func(x,K,H,u):
    return (-(K*(-H+math.log(1+H/x)*(x+H)))/(math.log(2)*(x**2)*(math.log((x+H)/x,2))**2*(x+H))+u)
print(fsolve(func,0.5,args=(K,H,u)))

The error is as follows: return (-(K*(-H+math.log(1+H/x)(x+H)))/(math.log(2)(x**2)*(math.log((x+H)/x,2))*2(x+H))+u) ValueError: math domain error

Upvotes: 1

Views: 8360

Answers (1)

Patol75
Patol75

Reputation: 4547

The problem you have is linked to the initial guess of your root and how it affects the stability of the implementation of the algortihm. For example, if you swap 0.5 by 1e-3, fsolve converges. I propose below an alternative script which makes use of a bracket algorithm and which converges without problems, provided that the root lies within the bracket and that the images of each end of the bracket are of opposite sign. If any of the latter conditions are not enforced, then the algorithm will let you know about it.

from numpy import log, log2
from scipy.optimize import root_scalar


def func(x, K, H, u):
    return (u - K * (log(1 + H / x) * (x + H) - H)
            / log(2) / x ** 2 / log2((x + H) / x) ** 2 / (x + H))


sol = root_scalar(func, args=(5, 6, 100), method='toms748', bracket=[1e-3, 1])
print(sol.root, func(sol.root, 5, 6, 100))
# 0.0784837307625566 4.263256414560601e-14

Upvotes: 4

Related Questions