求解方程时complex128转float64类型错误的解决咨询
解决SciPy fsolve复数转实数类型转换错误
问题场景
使用以下Python代码求解方程时出现类型转换错误:
def fun(z): g = np.zeros(4 * N) for i in range(4 * N): f = np.zeros(4 * N) for j in range(4 * N): f[i] = f[i] + M_kk[i][j] * z[j] * np.arcsinh(w_c / z[j]) g[i] = f[i] - z[i] return(g) z = fsolve(fun, dk)
报错信息
ComplexWarning: Casting complex values to real discards the imaginary part f[i] = f[i] + M_kk[i][j] * z[j] * np.arcsinh(w_c / z[j]) ComplexWarning: Casting complex values to real discards the imaginary part g[i] = f[i] - z[i] Traceback (most recent call last): File "C:\Users\AppData\Local\Programs\Python\Python310\Lib\site-packages\simple test.py", line 112, in <module> z = fsolve(fun, dk) File "C:\Users\AppData\Local\Programs\Python\Python310\Lib\site-packages\scipy\optimize\_minpack_py.py", line 160, in fsolve res = _root_hybr(func, x0, args, jac=fprime, **options) File "C:\Users\AppData\Local\Programs\Python\Python310\Lib\site-packages\scipy\optimize\_minpack_py.py", line 237, in _root_hybr retval = _minpack._hybrd(func, x0, args, 1, xtol, maxfev, TypeError: Cannot cast array data from dtype('complex128') to dtype('float64') according to the rule 'safe'
核心原因
scipy.optimize.fsolve是仅支持实数域求解的根查找函数,要求输入初始值和函数返回值均为实数数组。但计算过程中np.arcsinh(w_c/z[j])可能生成复数,而代码中创建的g、f是默认float64类型的实数数组,赋值时强制丢弃虚部触发警告,最终fsolve拒绝接收复数返回值,抛出类型转换错误。
解决方案
1. 改用支持复数域的求解函数
使用scipy.optimize.root,它支持复数输入和输出,可指定与fsolve底层相同的'hybr'方法,示例代码:
from scipy.optimize import root import numpy as np def fun(z): # 显式创建复数类型数组 g = np.zeros(4 * N, dtype=np.complex128) for i in range(4 * N): f = np.zeros(4 * N, dtype=np.complex128) for j in range(4 * N): f[i] += M_kk[i][j] * z[j] * np.arcsinh(w_c / z[j]) g[i] = f[i] - z[i] return g # 确保初始值为复数类型,若原dk是实数则转换 dk_complex = dk.astype(np.complex128) result = root(fun, dk_complex, method='hybr') z = result.x
2. 显式指定数组类型,避免隐式转换
无论使用哪个求解函数,都要将g、f声明为复数类型(dtype=np.complex128),这样计算过程中会保留虚部,不会触发类型转换警告。
3. 检查输入与模型合理性
如果问题本身应在实数域求解,需检查:
- 初始值
dk是否为合理的实数,是否会导致z[j]出现0或负数 w_c的取值是否会让w_c/z[j]超出实数arcsinh的输入范围
调整初始值或模型,确保计算全程在实数域内,此时可继续使用fsolve,但需修正数组类型避免警告。
内容的提问来源于stack exchange,提问作者karren lim
相关产品推荐
相关产品推荐

