英文:
Python Error: Could not find root within given tolerance?
问题
我尝试找到方程f
的根,该方程是矩阵行列式的结果。通过以下代码生成了这个方程:
from sympy import *
from math import sqrt
# ...(代码省略)...
f = matrix.det()
我尝试了两种方法找到根:
第一种
我使用了mpmath
函数,将符号方程转化为数值方程,然后猜测了值。参考值为(-0.17792, -0.74734*I)
。
import mpmath as mp
f = lambdify(rho, matrix.det())
mp.findroot(f, -0.17-0.75j)
但是我遇到了以下错误:
ValueError: Could not find root within given tolerance. (2.01839854512653723801e-14 > 2.16840434497100886801e-19) Try another starting point or tweak arguments.
第二种
我使用了solve
函数:
f = matrix.det()
sol = solve(f, rho)
sol = 展开收缩
for s in sol:
print(s)
但是这次,即使在代码开头使用了较低的迭代次数(N=4
),单元格仍然不停地加载,没有生成任何结果或代码。
如何解决这个问题并轻松生成复数根?
英文:
I'm trying to find the roots of an equation f
that is the result of the determinant of a matrix. Arriving at this equation was simple, I generated the following code:
from sympy import *
from math import sqrt
def Rec_Coef(n, l, Q, rho, i):
r1 = (1/2)*(1+sqrt(1-4*Q**2))
r2 = (1/2)*(1-sqrt(1-4*Q**2))
b = (rho*r1**2)/(r1-r2)
if i == 1:
q = (1/2)*(3+sqrt(9+16*Q**2*(l-1)*(l+2)))
if i == 2:
q = (1/2)*(3-sqrt(9+16*Q**2*(l-1)*(l+2)))
A = l*(l+1)
alpha = (n**2 + 2*(b+1)*n + 2*b + 1)*r1
beta = (-2 + r2)*n**2 + (-2 - 2*b*(2-r2) - 4*rho*r1**2 + 6*r2)*n + (q - 2*(rho**2)*(r1**3) - 4*rho*r1**2*(1+b) - 2*b**2*(2-r1**(-1)) - r1*A - (3-2*b)*r2)
gamma = (1+r2)*n**2 + (2*rho*r1*(1+2*r2)+2*b*(1+r2)-10*r2)*n + (rho*r1*(2 -12*r2 + (rho+2*b)*(1+2*r2)) -1 -q -2*b*(1+3*r2) + b**2*(16 + 8*r2 - (15 - 38*r2 + 26*r2**2)*r1**(-3)) + (A+13)*r2)
delta = (-n**2 + 2*(3 - rho -b)*n - (9 + 4*rho*b - 6*b - 6*rho))*r2
return alpha, beta, gamma, delta
N=4
α = []
β = []
γ = []
δ = []
l = 2
Q = 0.2
i = 2
rho = symbols("𝜌")
for j in range(N):
alpha, beta, gamma, delta = simplify(Rec_Coef(j, 2, 0.2, rho, 2))
α.append(alpha)
β.append(beta)
γ.append(gamma)
δ.append(delta)
array = [[0]*(N+1) for row in range(N)]
array[0][0] = β[0]
array[0][1] = α[0]
array[1][0] = γ[1]
array[1][1] = β[1]
array[1][2] = α[1]
for i in range(2,N):
array[i][i-1] = γ[i] - (array[i-1][i-1]/array[i-1][i-2])*δ[i]
array[i][i] = β[i] - (array[i-1][i]/array[i-1][i-2])*δ[i]
array[i][i+1] = α[i]
matrix_aux = simplify(Matrix(array))
M_aux = [[0]*(N) for row in range(N)]
for i in range(N):
for j in range(N):
M_aux[i][j]=(array[i][j])
matrix = Matrix(M_aux)
f = matrix.det()
So I tried to find the roots in a few ways:
First
I used the mpmath
function, turned my symbolic equation into a numerical equation, and then I guessed at the value. The reference value is (-0.17792, -0.74734*I)
.
import mpmath as mp
f = lambdify(rho, matrix.det())
mp.findroot(f, -0.17-0.75j)
However, I got the following error:
ValueError: Could not find root within given tolerance. (2.01839854512653723801e-14 > 2.16840434497100886801e-19) Try another starting point or tweak arguments.
Second
I used the solve function
f = matrix.det()
sol = solve(f, rho)
sol = 展开收缩
for s in sol:
print(s)
But this time, even with a low number of iterations used at the beginning of the code (N=4
), the cell keeps loading without stopping and does not generate any result or code.
How can I solve this problem and generate the complex roots easily?
答案1
得分: 1
首先,让我说一下,我不知道你试图解决什么问题,因此我将假设你的方程 f
被正确构建。此外,我无法解决你的问题,但希望你能对为什么尝试失败有一些了解。
为了更好地理解这个函数,我在复平面上绘制了它的绝对值,使用了 sympy plot backends 模块:
import numpy as np
plot_complex(f, (rho, -2-2j, 2+2j), threed=True, backend=KB,
tz=lambda t: np.log(t)/10, n=500)
请注意,上述命令在 500*500=250000 个点上评估函数。注意内存消耗!在上图中,底部的每个尖峰都是一个零点。
在以下区域更仔细查看,并大大增加绘图的分辨率(3000*3000=9M 个评估点,不要运行此命令,因为它会消耗超过 15GB 的内存):
plot_complex(f, (rho, -0.1-1j, -0.35-0.75j), threed=True, backend=KB,
tz=lambda t: np.log(t)/30, n=3000)
看到那些噪音了吗?让我们进一步放大:
在这个区域,似乎你的函数具有“无穷多个零点”和“无穷多个鞍点”。这是一种噩梦般的情况:无论你的初始条件如何,我认为使用任何数值算法都不可能找到零点,更不用说类似 solve
或 solveset
这样的符号算法。零点之间的距离是如此之小,以至于我看不到算法如何正确解决这种情况…也许 findroot
有一些选项可以指定容差???
顺便说一下,sympy 的 nsolve
是 mpmath 的 findroot
的包装器,因此你可以避免使用 lambdification 步骤!
现在,让我们放大到另一个区域:
plot_complex(log(f), (rho, -0.65-0.95j, -0.6-0.9j), threed=True, backend=KB,
tz=lambda t: np.log(t)/100, n=3000)
看到那些噪音了吗?让我们再放大一点:
似乎这是一个具有无穷多个零点的区域,因此具有无穷多个鞍点…再次是一场噩梦…
英文:
Let me start by saying that I have no idea what problem you are trying to solve, hence I'm going to assume that your equation f
is built correctly.
Also, I'm unable to solve your problem, but hopefully you'll gain some insight about why your attempts failed.
To gain more intuition about the function, I plotted its absolute value in the complex plane using the sympy plot backends module:
import numpy as np
plot_complex(f, (rho, -2-2j, 2+2j), threed=True, backend=KB,
tz=lambda t: np.log(t)/10, n=500)
Note that the above command evaluates the function over 500*500=250000 points. Watch out for memory consumption! In the above picture, every spike towards the bottom is a zero.
Looking closer in the following region, and increasing a lot the resolution of the plot (3000*3000=9M evaluation points, don't run this command as it consumes over 15GB of memory):
plot_complex(f, (rho, -0.1-1j, -0.35-0.75j), threed=True, backend=KB,
tz=lambda t: np.log(t)/30, n=3000)
See that noise? Let's zoom in:
In this region, it appears that your functions has "infinitely many zeros" and "infinitely many saddle points". This is a nightmare situation: no matter your initial condition, I believe it's impossible to find a zero with any numerical algorithm, let alone symbolic algorithms like solve
or solveset
. The distance between zeros is sooo small that I don't see how an algorithm can properly resolve the situation... Maybe findroot
has some option to specify the tolerance???
By the way, sympy's nsolve
is a wrapper to mpmath's findroot
, so you can avoid the lambdification step!
Now, let's zoom into a different region:
plot_complex(log(f), (rho, -0.65-0.95j, -0.6-0.9j), threed=True, backend=KB,
tz=lambda t: np.log(t)/100, n=3000)
See that noise? Let's zoom in a little bit:
It appears that this is a region with infinitely many zeros, hence infinitely many saddle points... Again, a nightmare...
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论