【发布时间】:2021-08-06 13:02:29
【问题描述】:
我想弄清楚两个椭圆何时第一次相交,因为它们的“半径”增加了。在那一刻,它们应该是外部余切的。我们有两个函数 f 和 g,它们的形式都是 a x^2+b y^2+ c xy +d x+f y+(e-t)。注意常数项中的变量 t。 f, g(x,y) = 0 描述了“半径”t 的第一个、第二个椭圆。正切曲线意味着双根。我的方法:取消 y^2 项,然后将 y 作为 x 的有理函数求解。将其代入 f,并清除分母:这会产生 x 中的四次多项式,其系数涉及 t(其中 x 为零)。现在我应该能够使用判别式计算出该多项式具有双根的 t 值,从而恢复椭圆余切的最小 t。
我在 sympy live shell 中尝试了一个简单的示例,其中 f 和 g 中涉及的 a、b 等是整数。经过一些试验和错误,我得到了以下工作:
f = 2*x**2+y**2-t
g = 3*(1/sqrt(2)*(x-1)+1/sqrt(2)*(y+1))**2+5*(1/sqrt(2)*(x-1)-1/sqrt(2)*(y+1))**2-t
h = expand(g).coeff(y,2)*f - expand(f).coeff(y,2)*g
h = Poly(h)
f2=Poly((f.subs(y, solve(h,y)[0])*h.as_expr().coeff(y,1)**2).simplify(),x)
roots = roots(discriminant(f2),t)
丢弃复杂的根源后,我得到了我想要的。如何让它与非整数输入一起使用?
我的尝试:第一个问题是乘以 h.as_expr().coeff(y,1)**2 无法取消 f.subs(y, solve(h,y)[0]) 中的分母,大概是由于舍入错误。我通过分别提取表达式的分子和分母制作了一个解决方法,用系数运算替换替换:
num = -1*h.as_expr().coeff(y,0)
denom = h.as_expr().coeff(y,1)
noYTerm = f.as_expr().coeff(y,0)
linearYTerm = f.as_expr().coeff(y,1)
ySquareTerm = f.as_expr().coeff(y,2)
f2 = Poly(simplify(ySquareTerm*num**2+linearYTerm*num*denom+noYTerm*denom**2),x)
但是,我只收到一堆 sympy.polys.polyerrors.PolynomialDivisionFailed 错误。如果我打印出 f2 的表达式,我会得到
Poly(10108.448*x**3 + 155858.976*x**2 + (707853.024000001 - 949.184000000001*t)*x + 918397.152000001 - 6870.336*t, x, domain='RR[t]')
.000001尖叫浮点错误...我尝试切换到QQ,但仍然收效甚微。
我也对其他方法持开放态度:也许有一种比我正在做的更容易从这对多项式中提取我想要的信息的方法。
【问题讨论】:
-
在开始时将系数替换为有理近似值或表示。或者使用数值求解器(来自 scipy.optimize)而不使用 sympy。 Afaik 在标准 python 包中没有实现“混合”求解器方法。
-
有没有办法让这个工作与浮动?
-
关于近似结果,请参阅 Kalthofen(和其他人),本质上,这对 Sylvester 矩阵的 SVD 进行了维度分析。这不是在 sympy 中实现的东西。
-
另外:我看不出数值求解器有什么帮助。我正在求解 t 值,使得 (x,y) 系统具有双根。直到我有一些表达“这些是具有双根的 t 值”(判别式 0)我不明白数值求解器是如何适用的
-
应该首先用变量作为系数来解决这个问题,然后将结果中的变量替换为它们的浮点值。