numpy的浮点精度很差

2024-04-28 22:53:20 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个这样的数学问题的解决方案(很抱歉格式化,这就是PyCharm所做的):

sigma = (wf_s[0] * u ** 4 + wf_s[1] * u ** 3 * v + wf_s[2] * u ** 3 + wf_s[3] * u ** 2 * v ** 2 + wf_s[
                4] * u ** 2 * v + wf_s[5] * u ** 2 + wf_s[6] * u * v ** 3 + wf_s[7] * u * v ** 2 + wf_s[8] * u * v + wf_s[
                         9] * u + wf_s[10] * v ** 4 + wf_s[11] * v ** 3 + wf_s[12] * v ** 2 + wf_s[13] * v + wf_s[14]) / (
                                wf_s[15] * u ** 4 + wf_s[16] * u ** 3 * v + wf_s[17] * u ** 3 + wf_s[18] * u ** 2 * v ** 2 +
                                wf_s[19] * u ** 2 * v + wf_s[20] * u ** 2 + wf_s[21] * u * v ** 3 + wf_s[22] * u * v ** 2 +
                                wf_s[23] * u * v + wf_s[24] * u + wf_s[25] * v ** 4 + wf_s[26] * v ** 3 + wf_s[
                                    27] * v ** 2 + wf_s[28] * v + wf_s[29])

sigma = sqrt(sigma)

x1 = (wf_x1[0] * u ** 2 * sigma + wf_x1[1] * u ** 2 + wf_x1[2] * u * v * sigma + wf_x1[3] * u * v + wf_x1[
                4] * u * sigma + wf_x1[5] * u + wf_x1[6] * v ** 2 * sigma + wf_x1[7] * v ** 2 + wf_x1[8] * v * sigma +
                  wf_x1[9] * v + wf_x1[10] * sigma + wf_x1[11]) / (
                             wf_x1[12] * u ** 2 + wf_x1[13] * u * v + wf_x1[14] * u + wf_x1[15] * v ** 2 + wf_x1[16] * v +
                             wf_x1[17])

x2 = (wf_x2[0] * u ** 2 * sigma + wf_x2[1] * u ** 2 + wf_x2[2] * u * v * sigma + wf_x2[3] * u * v + wf_x2[
                4] * u * sigma + wf_x2[5] * u + wf_x2[6] * v ** 2 * sigma + wf_x2[7] * v ** 2 + wf_x2[8] * v * sigma +
                  wf_x2[9] * v + wf_x2[10] * sigma + wf_x2[11]) / (
                             wf_x2[12] * u ** 2 + wf_x2[13] * u * v + wf_x2[14] * u + wf_x2[15] * v ** 2 + wf_x2[16] * v +
                             wf_x2[17])

y1 = (wf_y1[0] * u ** 2 * sigma + wf_y1[1] * u ** 2 + wf_y1[2] * u * v * sigma + wf_y1[3] * u * v + wf_y1[
                4] * u * sigma + wf_y1[5] * u + wf_y1[6] * v ** 2 * sigma + wf_y1[7] * v ** 2 + wf_y1[8] * v * sigma +
                  wf_y1[9] * v + wf_y1[10] * sigma + wf_y1[11]) / (
                             wf_y1[12] * u ** 2 + wf_y1[13] * u * v + wf_y1[14] * u + wf_y1[15] * v ** 2 + wf_y1[16] * v +
                             wf_y1[17])

y2 = (wf_y2[0] * u ** 2 * sigma + wf_y2[1] * u ** 2 + wf_y2[2] * u * v * sigma + wf_y2[3] * u * v + wf_y2[
                4] * u * sigma + wf_y2[5] * u + wf_y2[6] * v ** 2 * sigma + wf_y2[7] * v ** 2 + wf_y2[8] * v * sigma +
                  wf_y2[9] * v + wf_y2[10] * sigma + wf_y2[11]) / (
                             wf_y2[12] * u ** 2 + wf_y2[13] * u * v + wf_y2[14] * u + wf_y2[15] * v ** 2 + wf_y2[16] * v +
                             wf_y2[17])

这个计算在Python中运行得比较慢,所以我想使用numpy来提高速度。结果如下:

u2 = u ** 2
u3 = u ** 3
u4 = u ** 4
v2 = v ** 2
v3 = v ** 3
v4 = v ** 4

uv_s = np.array((u4, u3 * v, u3, u2 * v2, u2 * v, u2, u * v3, u * v2, u * v, u, v4, v3, v2, v, 1))
sigma = np.dot(wf_s[:15], uv_s) / np.dot(wf_s[15:], uv_s)

sigma = sqrt(sigma)

uv_xy_n = np.array((u2 * sigma, u2, u * v * sigma, u * v, u * sigma, u, v2 * sigma, v2, v * sigma, v, sigma, 1))
uv_xy_d = np.array((u2, u * v, u, v2, v, 1))
x12 = np.dot(wf_x1[:12], uv_xy_n) / np.dot(wf_x1[12:], uv_xy_d)
x22 = np.dot(wf_x2[:12], uv_xy_n) / np.dot(wf_x2[12:], uv_xy_d)
y12 = np.dot(wf_y1[:12], uv_xy_n) / np.dot(wf_y1[12:], uv_xy_d)
y22 = np.dot(wf_y2[:12], uv_xy_n) / np.dot(wf_y2[12:], uv_xy_d)

从理论上讲,这个方法很好,运行速度比我的第一个方法快3倍,但结果的准确性是可怕的。在我的例子中,x和y是成百上千的,第二种方法产生的结果与实际结果相差0.2。这种准确性在我的情况下是没有用的。绘制第一种方法的结果会得到预期的完美绘图。绘制第二种方法的结果会产生一个超噪声图

为什么numpy版本的准确性这么差,我该如何改进它


Tags: 方法npv3uvsigmadotv2x1