四舍五入小数的精度给出了线性方程求解的nans

Precision of rounded decimals giving nans for linear equation solving

为屠宰的标题道歉,不知道我应该怎么称呼它。

我正在求解线性方程积分的上限,就像这个问题:https://math.stackexchange.com/questions/3878448/solving-for-limit-of-integration-of-a-linear-equation

除了上面的问题要求下限,下面我求解上限为xincrements:

import numpy as np

yvals = np.random.uniform(size=2)
xvals = np.random.uniform(size=2)

slope = np.diff(yvals) / np.diff(xvals)
intercept = yvals[:-1] - (xvals[:-1] * slope)

area = np.trapz(yvals, xvals)

nsplits = 100000
a = np.linspace(0, area, nsplits+1)
m = slope
b = intercept
c = xvals[0]

xincrements = ((-1*b) + np.sqrt((b**2) - (4*(0.5*m)*(-0.5*m*(c**2) - (b*c) - a)))) / m

这在使用随机浮点数和大多数值时非常有效。

但是,在混合使用 truncated/rounded 小数时会出现问题。例如使用这些起点

xvals = np.array([317.16760254, 317.16763306])
yvals = np.array([1570203.5 ,       0.  ])

抛出 RunTimeWarning 因为平方根函数内的值是负数。如果您从较低的 nsplits 开始,例如 10 或 100,则在 xincrements 的最后一个值 nsplits 的任何值都会发生这种情况。如果您将 nsplits 增加到 100000 或所以,您可以看到这个问题不仅限于最后一个值。

它在解决与我的特定示例的 xvals[1] 非常接近的值时遇到问题。我似乎 运行 也遇到了与其他 t运行 小数相同的问题。

为什么会这样,我能做些什么吗?

所以我最终做的是将函数封装在一个 while 循环中,并用一个封闭的 try/except 块捕捉 RuntimeWarningnan 是生产。

我之前记录了xvals的精度,

precision = max([str(i)[::-1].find('.') for i in xvals])

并在每次捕获异常时通过四舍五入将其减 1。

工作相当稳健,在大约 30,000 个样本中只看到精度下降到 0 一次。