我似乎失去了很多的精度浮点数。
例如,我需要解决一个矩阵:
4.0x -2.0y 1.0z =11.0
1.0x +5.0y -3.0z =-6.0
2.0x +2.0y +5.0z =7.0
这是我使用从文本文件导入矩阵的代码:
f = open('gauss.dat')
lines = f.readlines()
f.close()
j=0
for line in lines:
bits = string.split(line, ',')
s=[]
for i in range(len(bits)):
if (i!= len(bits)-1):
s.append(float(bits[i]))
#print s[i]
b.append(s)
y.append(float(bits[len(bits)-1]))
我需要用高斯 - 塞德尔所以我需要重新安排的x,y和z的方程组的求解:
x=(11+2y-1z)/4
y=(-6-x+3z)/5
z=(7-2x-2y)/7
下面是我用它来重新排列方程中的代码。 b
是系数矩阵和y
是答案向量:
def equations(b,y):
i=0
eqn=[]
row=[]
while(i<len(b)):
j=0
row=[]
while(j<len(b)):
if(i==j):
row.append(y[i]/b[i][i])
else:
row.append(-b[i][j]/b[i][i])
j=j+1
eqn.append(row)
i=i+1
return eqn
不过我找回答案并不精确到小数点后一位。
例如,在重新安排从上面的第二个方程,我应该得到:
y=-1.2-.2x+.6z
我得到的是:
y=-1.2-0.20000000000000001x+0.59999999999999998z
这看起来可能不是一个大问题,但是当你提高的数量非常高的功率误差是相当大的。 有没有解决的办法? 我试过Decimal
类,但它不与权力很好地工作(即Decimal(x)**2
)。
有任何想法吗?
Answer 1:
我不是小数类足够的熟悉来帮助你,但你的问题是由于小数往往不准确表示二进制,所以你看到的是最接近的可能近似的事实; 有没有办法避免这个问题,而无需使用特殊类(如十进制,可能)。
EDIT:
关于小数点类什么是不适合你正常工作? 只要我开始一个字符串,而不是浮动,权力,似乎工作的罚款。
>>> import decimal
>>> print(decimal.Decimal("1.2") ** 2)
1.44
该模块文档说明了的和使用的需要decimal.Decimal
很清楚,你应该检查出来,如果你还没有。
Answer 2:
IEEE浮点是二进制的,不是小数。 没有固定长度的二进制分数,这正是0.1,或它们的任何倍数。 是重复分数,像在十进制1/3。
请阅读什么每台计算机科学家应该知道关于浮点运算
除了一个小数类的其它选项
Answer 3:
首先,你的输入可以简化很多。 你并不需要阅读和分析的文件。 你可以只申报在Python符号的对象。 EVAL文件。
b = [
[4.0, -2.0, 1.0],
[1.0, +5.0, -3.0],
[2.0, +2.0, +5.0],
]
y = [ 11.0, -6.0, 7.0 ]
其次,Y = -1.2-0.20000000000000001x + 0.59999999999999998z是不寻常的。 还有用二进制表示没有确切表示为0.2或0.6。 因此,所显示的值是原来不准确表示的十进制近似值。 这些是几乎所有种类的浮点处理器存在的事实。
您可以尝试的Python 2.6 分数模块。 这里有一个旧的理性包,可能的帮助。
是的,提高浮点数到权力增加了错误。 因此,你必须确保避免使用浮点数的最右边的位置,因为这些位大多噪音。
当显示浮点数,你必须适当轮他们以避免看到噪音位。
>>> a
0.20000000000000001
>>> "%.4f" % (a,)
'0.2000'
Answer 4:
我想告诫像这样的任务十进制模块。 其目的是真是越来越处理现实世界的十进制数(如配套人类簿记惯例),具有有限的精度,不执行准确精度数学。 有正如有二进制数小数不能准确地表示,以10进制执行算术也比替代品慢得多。
相反,如果你想确切的结果,你应该使用合理的算术。 这些将代表数字作为计数器/ denomentator对,因此可以完全代表所有的有理数。 如果你只使用乘法和除法(而不是像平方根,可导致无理数的行动),你永远不会丢失精度。
正如其他人所说,蟒蛇2.6将有一个内置的理性型,但注意,这不是一个真正的高性能的实现-为您更好地使用图书馆般的速度gmpy 。 只需更换您的来电浮动()来gmpy.mpq()和你的代码现在应该给予确切的结果(尽管你可能要格式化的结果彩车用于显示目的)。
这里是你的代码稍微收拾版本加载,将使用gmpy有理数,而不是一个矩阵:
def read_matrix(f):
b,y = [], []
for line in f:
bits = line.split(",")
b.append( map(gmpy.mpq, bits[:-1]) )
y.append(gmpy.mpq(bits[-1]))
return b,y
Answer 5:
这不是一个回答你的问题,但相关的:
#!/usr/bin/env python
from numpy import abs, dot, loadtxt, max
from numpy.linalg import solve
data = loadtxt('gauss.dat', delimiter=',')
a, b = data[:,:-1], data[:,-1:]
x = solve(a, b) # here you may use any method you like instead of `solve`
print(x)
print(max(abs((dot(a, x) - b) / b))) # check solution
例:
$ cat gauss.dat
4.0, 2.0, 1.0, 11.0
1.0, 5.0, 3.0, 6.0
2.0, 2.0, 5.0, 7.0
$ python loadtxt_example.py
[[ 2.4]
[ 0.6]
[ 0.2]]
0.0
Answer 6:
另请参阅什么是浮点错误的一个简单的例子 ,在这里左右,其中有一些答案。 一个我给实际使用Python作为例子语言...
文章来源: Decimal place issues with floats and decimal.Decimal