微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何调整 fsolve 以避免“日志中遇到无效值”

如何解决如何调整 fsolve 以避免“日志中遇到无效值”

我只想解决 here 中提到的氨溶液的 pH 值。

详细的完整方程在 here 中被提及,这是我的数值求解:

import numpy as np
import scipy.optimize as optimize

C = np.array([0,0.1,0])
N = np.array([
    [1,1,0],[0,-1,1]
])
K = np.array([1E-14,1.77E-5])

def eq1(X):
    return N.transpose() @ np.array(X) + C

def eq2(X):
    return N @ np.log(eq1(X)) - np.log(K)

X = optimize.fsolve(eq2,[1E-14,1E-14])
print("X=",X)
print("Y=",eq1(X))

但我收到了这些警告:

RuntimeWarning: invalid value encountered in log
  return N @ np.log(eq1(X)) - np.log(K)
/usr/local/lib64/python3.6/site-packages/scipy/optimize/minpack.py:175: RuntimeWarning: The iteration is not making good progress,as measured by the
  improvement from the last ten iterations.
  warnings.warn(msg,RuntimeWarning)
X= [2.39338797e-06 2.27841240e-05]
Y= [2.39338797e-06 2.51775120e-05 9.99772159e-02 2.27841240e-05]

这个问题对于 fsolve 来说很棘手,因为在正确的解决方案中,[7.57E-12 1.32E-3] X1 太接近于零。

我尝试了其他初始值 [1E-7,1E-7][1E-1,1E-1] 等,但没有一个可以避免这种情况,直到我尝试了接近正确解的对,例如[1E-12,1E-3]

fsolve 是否有任何参数可以避免此类问题?或者有什么方法可以给出适当的初始值?

解决方法

试试这个安排

import numpy as np
import scipy.optimize as optimize

C = np.array([0,0.1,0])
N = np.array([
    [1,1,0],[0,-1,1]
])

K = np.array([1e-14,1.77e-5])

x1 = 1e-2
x2 = 2e-2
y1 = 3e-2
y2 = 4e-2
y3 = 5e-2
y4 = 6e-2
xmin = 1e-10
xmax = 1e0
XY = np.array([x1,x2,y1,y2,y3,y4])

def eq1(XY):
    X = np.array([XY[0],XY[1]])
    Y = np.array([XY[2],XY[3],XY[4],XY[5]]) 
    return N.transpose() @ np.array(X) + C - Y

def eq2(XY):
    Y = np.array([XY[2],XY[5]])
    return N @ np.log(abs(Y)) - np.log(K)

def obj(XY):
    return np.linalg.norm(eq1(XY),2) + np.linalg.norm(eq2(XY),2)

bounds = ((xmin,xmax),(xmin,xmax))

    
result = optimize.minimize(obj,XY,bounds = bounds,method = 'trust-constr')

print(result.x)

print(obj(result.x))

残差验证

print(eq1(result.x))
print(eq2(result.x))

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。