请考虑以下代码段:
# Execute the solver
t1 = tim.default_timer()
x = x0
nfev = 0
maxfev=3
while np.any(err**2>self.options['xtol']):
# Calculate Jacobian
print('Calculating Jacobian...')
sol, inf_dict, ier, mesg = fsolve(_solve_fun_, x,args=(x_shp,),maxfev = 1,full_output = True, **self.options)
self.jac = inf_dict['fjac']
x = sol
print(inf_dict['nfev'])
nfev +=inf_dict['nfev']
# Solve system
print('Calculating solution...')
sol, inf_dict, ier, mesg = fsolve(_solve_fun_, x, args=(x_shp,),fprime=self._jac_, maxfev=maxfev,full_output = True, **self.options)
x = sol
err = inf_dict['fvec']
nfev += inf_dict['nfev']
maxfev = np.min(np.array([13,maxfev+2]))
t2 = tim.default_timer()
我是一名系统工程师,这是应该用于求解非线性方程组的求解器的一部分。问题总是不同的(在_solve_fun_中,我的系统具有不同的组件
即管道,热交换器,泵等)。
现在代码可以正常工作了。我确实将求解过程分为两个过程,第一个例程只给了我jacobian,第二个例程实际求解了一点,直到达到收敛或尝试了太多次,然后重新计算了jacobian。我想避免在每个点上都(昂贵)估计雅各布派。
但是我的代码比仅仅使用一个普通的求解器要慢。我们在MATLAB中有一个类似的程序,使用此“技巧”来极大地影响您。我是否错过了MATLAB fsolve和scipys fsolve之间的关键区别,还是有办法减少每个jacobian估计的函数求值数(无论我对第一个求解器执行nfev = 74还是什么?
我希望我提供的代码和解释足够了。否则,请让我知道我很乐于进一步详细介绍。