描述
我需要计算一些满足 10^{-6} 级别精度的结果,但是在计算过程中,发现由于中间变量的精度损失,无法获得满足精度的最终解答。
问题
如代码所示,是一个简单的将紧凑形式应力向量变为一个矩阵的简单操作函数,输入的数据 -0.742128、-1.731632 经过在func内赋值,变成了 -0.742128014565、-1.731631994247,但 -0.000001、0.0 却保持不变。这还是在使用 ti.f64 数据类型下的结果,如果使用默认的 ti.f32 会产生更大的误差(变成 -0.7421280256、-1.7316319232),而直接使用Python就没有这个问题。
计算过程从初始化赋值就开始出现误差,在后续各种运算过程后,最终结果的误差将难以接受(如最终结果应为 0.0,但在 ti.f32 下,只能算到 0.000000029802)。而且我设置了迭代计算来提高精度,但猜测也是由于这个数值精度的问题导致迭代到最后始终是一样的结果,无法再小下去。
因此我了解了一下float的精度范围,似乎按照float32、float64的精度范围,不应该出现这样的问题?
请问这种数值误差应如何避免?
代码
import taichi as ti
ti.init(debug=True)
@ti.func
def get_f_stress3(f_stress):
res = ti.Matrix([[f_stress[0], f_stress[2], 0.0], [f_stress[2], f_stress[1], 0.0], [0.0, 0.0, f_stress[3]]], ti.f64)
return res
@ti.kernel
def foo():
stress = get_f_stress3(f_stress)
print("σ =", stress)
if __name__ == "__main__":
f_stress = ti.Vector([-0.742128, -1.731632, -0.000001, -0.742128], ti.f64)
foo()
Output:
[Taichi] version 1.0.0, llvm 10.0.0, commit 6a15da85, win, python 3.8.1
[Taichi] Starting on arch=x64
蟽 = [[-0.742128014565, -0.000001000000, 0.000000000000], [-0.000001000000, -1.731631994247, 0.000000000000], [0.000000000000, 0.000000000000, -0.742128014565]]
另一个小问题
偶然发现如果想在 ti.kernel
里 print
一个希腊字母,就会出现奇怪的汉字(σ → 蟽,λ → 位)。在Python中 print
则是正常的。都是通过 Windows + . 选择输入的希腊字母。这是为什么呢?