好,
我遇到了舍入错误问题。我有一个java程序,读取列表,逐行,一些数字。该程序要求该列表是浮点数(什么类型的浮点数?我怀疑单精度)数字,其和S在.999和1.001之间(即.999 <= S <= 1.001)。这是一个例子:
from numpy import array, linalg
def Normalize(X):
NumpyX = array(X)
Norm = linalg.norm(NumpyX)
Normalize = NumpyX/Norm
return Normalize
def FileMaker(FilePointer,Vector)
for i in Vector:
FilePointer.write('%f\n'%i)
return
#sum(SubstitutionPoints) does not add to 1
SubstitutionPoints =[0.00606508512067950,0.00675296642376962,0.00688999694872917,0.00580692396866418,0.00680583604896024,0.00609061670962565,0.00585881991631447,0.00577148570812953,0.00600882981888663,0.00618499536435559,0.00650767341787896,0.00670521809234427,0.00699374780209504,0.00841141135948587,0.00830145870238677,0.00879477131238090,0.00918627324146331,0.00958946761973615,0.01032404247887830,0.01093417870737930,0.01188202458790520,0.01261860720648550,0.01355451051017660,0.01473818756656830,0.01623978223562570,0.01811682034513980,0.01990010225231130,0.02154250858435480,0.02418185925226890,0.02583490296173980,0.02844212438633430,0.03194935989118780,0.03534228607419560,0.03971366519834600,0.04548573525944540,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660,0.05190994307855660]
NormedSP = Normalize(SubstitutionPoints)
SubFile = open('Sub.txt','w')
FileMaker(SubFile,NormedSP)
SubFile.close()
由于python不使用单精度浮点数,我担心创建的文件会导致java程序出现问题,因为我的java程序(metasim)返回错误:
Simulating files:
[BorreliaBurgdorferiB31_CP32-3.fasta]
java.lang.Exception: Substitution rates don't sum to 1.0.
!!! FAILED !!!
不幸的是,我无法调试java程序,因为它是'java executable'。我唯一的选择是给出正确的输入。
感谢任何建议/帮助。
从尝试float32()的一些建议我修改了我的normalize方法:
def Normalize(self,X):
Total = sum(X)
NumpyX = array([float32(i) for i in X])
Norm = linalg.norm(NumpyX,ord=1)
Normalize = NumpyX/Norm
return Normalize
我开始怀疑它是单精度浮点问题。
我的输出是否被截断并导致错误?
答案 0 :(得分:2)
如果你只需要精确到三位小数,为什么不将这些值乘以1000,用整数进行所有数学计算,只在输出中添加小数点?这样就很容易确保总和是准确的。
答案 1 :(得分:1)
numpy.linalg.norm
要求ord=1
关键字arg执行您期望的操作。使用您当前的数据&amp;定义...
>>> Normalize(substitution_points).sum()
9.0451896403987444
您可能会这样做 - 这也会正确地缩放负值(linalg.norm
对值的abs
求和):
>>> def normalize(x):
... a = numpy.array(x)
... return a / a.sum()
...
>>> normalize(substitution_points).sum()
0.99999999999999789
0.9999999... > 0.999
,根据您提供的规范,应工作。
但......似乎它仍然没有用。尝试使用numpy.float16
- 并注意创建浮点数组的更惯用的方法是这样的:
array([ 0., 1., 2., 3., 4.], dtype=float32)
答案 2 :(得分:0)
您的Normalize方法不强制列表的总和为1:除以norm将 norm 设置为1.要将总数设置为1,您需要除以当前值总:
def normalize(X):
total = sum(X)
return [x/total for x in X]