我编写了以下代码,在打印了大约10个输出后会出现错误
return 1/sqrt(Om*(1+z)**3+omg0*(1+z)**6+(1-Om-omg0))
ValueError: math domain error
三个第一个函数是正确的并且在其他程序中运行良好请不要对它们的结构敏感,我认为问题出在for-loop
并选择了一些不能满足要求的值sqrt
的条件。我可以添加一些行来告诉Python避免导致math domain error
的数字吗?如果是的话,我该怎么做?我的意思是通过导致sqrt
下的负值的步骤
Cov
是31*31
mtrix,xx[n]
是31个数字的列表。
def ant(z,Om,w):
return 1/sqrt(Om*(1+z)**3+w*(1+z)**6+(1-Om-w))
def dl(n,Om,w,M):
q=quad(ant,0,xx[n],args=(Om,w))[0]
h=5*log10((1+xx[n])*q)
fn=(yy[n]-M-h)
return fn
def c(Om,w,M):
f_list = []
for i in range(31): # the value '2' reflects matrix size
f_list.append(dl(i,Om,w,M))
A=[f_list]
B=[[f] for f in f_list]
C=np.dot(A,Cov)
D=np.dot(C,B)
F=np.linalg.det(D)*0.000001
return F
N=100
for i in range (1,N):
R3=np.random.uniform(0,1)
Omn[i]=Omo[i-1]+0.05*np.random.normal()
wn[i]=wo[i-1]+0.05*np.random.normal()
Mn[i]=Mo[i-1]+0.1*np.random.normal()
L=exp(-0.5*(c(Omn[i],wn[i],Mn[i])-c(Omo[i-1],wo[i-1],Mo[i-1])))
if L>R3:
wo[i]=wn[i]
else:
wo[i]=wo[i-1]
print(wo[i])
输出结果为:
0.12059556415714912
0.16292726528216397
0.16644447885609648
0.1067588804671105
0.0321446951572128
0.0321446951572128
0.013169965429457382
Traceback (most recent call last):
......
return 1/sqrt(Om*(1+z)**3+omg0*(1+z)**6+(1-Om-omg0))
ValueError: math domain error
答案 0 :(得分:1)
以下是一些选项:
将sqrt(...)
替换为(...)**0.5
。这将产生复杂的数字,这可能是也可能是不可接受的。例如(-1)**0.5
生成i
,它在Python中显示为1j
(忽略浮点错误)。
抓住错误并继续前进。由于您可能希望更高地捕获错误,因此我建议将ValueError
从sqrt
转换为自定义错误:
class SqrtError(ValueError):
pass
def ant(z, Om, w):
val = Om * (1 + z) ** 3 + w * (1 + z) ** 6 + (1 - Om - w)
try:
sq = sqrt(val)
except ValueError:
raise SqrtError
return 1 / sq
然后听起来你想继续尝试新的随机数,直到你得到一个有效的,这可以这样做:
for i in range(1, N):
R3 = np.random.uniform(0, 1)
while True:
Omn[i] = Omo[i - 1] + 0.05 * np.random.normal()
wn[i] = wo[i - 1] + 0.05 * np.random.normal()
Mn[i] = Mo[i - 1] + 0.1 * np.random.normal()
try:
L = exp(-0.5 * (c(Omn[i], wn[i], Mn[i]) - c(Omo[i - 1], wo[i - 1], Mo[i - 1])))
except SqrtError:
continue
else:
break
if L > R3:
wo[i] = wn[i]
else:
wo[i] = wo[i - 1]
答案 1 :(得分:0)
您的代码正在尝试查找负数的平方根。
实值数字不允许这样做(出于明显的数学原因),所以最好的办法是使用try / except块:
def ant(z,Om,w):
try:
return 1/sqrt(Om*(1+z)**3+omg0*(1+z)**6+(1-Om-omg0))
except ValueError:
return None