解决多项式乘法和除法“溢出”问题

Addressing polynomial multiplication and division "overflow" issue

提问人:yupbank 提问时间:2/25/2022 最后编辑:yupbank 更新时间:3/26/2023 访问量:184

问:

我有一个 1 次多项式的系数列表,其中a[i][0]*x^1 + a[i][1]

a = np.array([[ 1.        , 77.48514702],
          [ 1.        ,  0.        ],
             [ 1.        ,  2.4239275 ],
           [ 1.        ,  1.21848739],
            [ 1.        ,  0.        ],
            [ 1.        ,  1.18181818],
           [ 1.        ,  1.375     ],
           [ 1.        ,  2.        ],
          [ 1.        ,  2.        ],
          [ 1.        ,  2.        ]])

并在以下操作中遇到问题,

np.polydiv(reduce(np.polymul, a), a[0])[0] != reduce(np.polymul, a[1:])

哪里

In [185]: reduce(np.polymul, a[1:])
Out[185]:
array([  1.        ,  12.19923307,  63.08691612, 179.21045388,
       301.91486027, 301.5756213 , 165.35814595,  38.39582615,
         0.        ,   0.        ])

In [186]: np.polydiv(reduce(np.polymul, a), a[0])[0]
Out[186]:
array([ 1.00000000e+00,  1.21992331e+01,  6.30869161e+01,  1.79210454e+02,
        3.01914860e+02,  3.01575621e+02,  1.65358169e+02,  3.83940472e+01,
        1.37845155e-01, -1.06809521e+01])

首先,确切地说,余数比 0 大得多,其次,商的最后两项应该是 0,但比 0 大得多。.np.polydiv(reduce(np.polymul, a), a[0])827.615142391.37845155e-01, -1.06809521e+01

我想知道我有哪些选择可以提高准确性?

numpy 浮动精度 多项式

评论

0赞 Eric Postpischil 2/25/2022
多项式是如何表示的;在 中,系数是 1 和系数,反之亦然?结果本身是什么?结果本身是什么?你能用一个较小的例子重现这一点吗?例如,如果去掉 中的最后一个多项式,问题是否仍然产生?删除最后两个呢?更多?它是否用更简单的多项式重现,比如用所有小的整数系数?1, 212xreduce(np.polymul, a)reduce(np.polymul, a[1:])a
0赞 yupbank 2/25/2022
感谢您的建议,我已经用更多细节更新了问题,我期待 的准确性,但它开始打破@EricPostpischil1e-5a[:8]
0赞 Eric Postpischil 2/25/2022
点 x = -77.48514702 处的多项式值约为 −8.58•10^16。在这种比例下,浮点格式的低位(假设使用 IEEE-754“双精度”,这很常见)的值为 16。然后,在计算乘积多项式及其商的所有算术中都涉及多个舍入误差,因此出现大误差也就不足为奇了。这只是对问题的第一次分析。我没有解决方案;我没有以这种方式处理过浮点多项式。reduce(np.polymul, a[1:])
0赞 yupbank 2/25/2022
我想知道如果我在所有 100 中添加一个足够大的常数 100,会有所帮助吗?a[i][1]
0赞 Eric Postpischil 2/25/2022
你到底想做什么?

答:

0赞 yupbank 4/19/2022 #1

有一种稍微复杂的方法,可以先保留产品,然后再划分结构。

首先使用积分并评估。na

xs = np.linspace(0, 1., 10) 
ys = np.array([np.prod(list(map(lambda r: np.polyval(r, x), a))) for x in xs])

然后进行除法而不是系数。ys

ys = ys/np.array([np.polyval(a[0], x) for x in xs])

最后使用多项式插值和xsys

from scipy.interpolate import lagrange
lagrange(xs, ys)

找到了第二个解决方案

b = a[:,::-1]
np.polydiv(reduce(np.polymul, b), b[0])[0][::-1]