我正在寻找一个函数的根,我知道根存在。下面的代码详细说明了scipy.optimize.root找不到root的两种情况。我的问题与我能做些什么来找到根(我已经尝试改变起点,方法,maxiter和xtol / ftol,但因为我是python的新手,我可能没有足够高效地完成程序的工作)。
第一种情况:未指定雅可比时找到根,但未指定雅致。雅各比人有什么不对? 此外,虽然根本没有找到根,但算法会返回成功,为什么以及如何解决这个问题?
第二种情况:从未找到根,我该如何解决?
from __future__ import division
import numpy as np
import datetime
import pandas
import scipy
from scipy import optimize
# 1st case
# rap=np.array([.5,12.8,44,10.7,5,12.3])
# 2nd case
rap=np.array([1.2,83,5,41,7,50])
def f2(wc, a1, p0, a1pr, p0pr, atheta, x):
A = (p0/(1-p0))**(1-a1)
Apr = (p0pr/(1-p0pr))**(1-a1pr)
return wc - (((A * x**a1)/(((1-x)**a1) + A * x**a1))* (1-np.exp(-rap*atheta))/atheta) - (((Apr * (1-x)**a1pr)/((x**a1pr) + Apr * (1-x)**a1pr))*((1-np.exp(atheta))/atheta))
# define the derivative of f2 with respect to x (checked with sympy)
def f2p(wc, a1, p0, a1pr, p0pr, atheta, x):
A = (p0/(1-p0))**(1-a1)
Apr = (p0pr/(1-p0pr))**(1-a1pr)
return - (((A*a1 * x**(a1-1) * (1-x)**(a1-1)) / (((1-x)**a1 + A * x**a1)**2)) \
*(1-np.exp(-rap*atheta)/atheta)) \
+ (((Apr * a1pr * (1-x)**(a1pr-1) * x**(a1pr-1) ) / ((x**a1pr + Apr * (1-x)**a1pr)**2)) \
*((1-np.exp(atheta))/atheta))
# f1 defines the function to find the root of
def f1(x, y):
a1, p0, a1pr, p0pr, atheta = y[:5]
tosolve = np.full_like(x, x[1:].sum()-1)
tosolve[:-1] = f2(x[0], a1, p0, a1pr, p0pr, atheta, x[1:])
return tosolve
# define the jacobian of f1
def jac(x, y):
a1, p0, a1pr, p0pr, atheta = y[:5]
partial = f2p(x[0], a1, p0, a1pr, p0pr, atheta, x[1:])
matrix = np.diag(partial)
vector1 = np.full_like(rap,1)
matrix1 = np.vstack((matrix, vector1))
vector = np.full_like(x,1)
vector[-1]=0
matrix2 = np.column_stack((vector, matrix1))
return matrix2
# f is finding the roots of f1
def f(y):
a1, p0, a1pr, p0pr, atheta = y[:5]
x0 = [0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001]
print 'x0', x0
sol = scipy.optimize.root(f1, x0, args=(y), method='lm')
# sol = scipy.optimize.root(f1, x0, args=(y), method='lm', jac=jac,options={'maxiter': 5000})
return sol
# 1st case
# result = f([.8,0.03,0.8,0.3,-0.01])
# 2nd case
result = f([1.99,0.01,1.99,0.989,-0.43])
print result