当前位置: 首页 > 知识库问答 >
问题:

当我们有sqrt时,如何避免数学域错误

谭嘉容
2023-03-14

我写了以下代码,在打印了大约10个输出后,它会出错

return 1/sqrt(Om*(1+z)**3+omg0*(1+z)**6+(1-Om-omg0))
ValueError: math domain error

前三个函数是正确的,在其他程序中工作良好。请不要对它们的结构敏感,我认为问题在于for loop和选择一些不能满足sqrt条件的值。我可以添加一些行来告诉Python避免使用导致数学域错误的数字吗?如果是,我应该怎么做?我的意思是通过sqrt下导致负值的步骤?

Cov是一个31*31mtrix,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

共有2个答案

施飞雨
2023-03-14

您的代码正在尝试查找负数的平方根。

这对于实值数字是不允许的(出于明显的数学原因),所以你最好的选择是使用try/除块:

def ant(z,Om,w):
    try:
        return 1/sqrt(Om*(1+z)**3+omg0*(1+z)**6+(1-Om-omg0))
    except ValueError:
        return None
林元明
2023-03-14

以下是一些选项:

>

  • sqrt(...)替换为(...)**0.5。这将产生复数,这可能是可接受的,也可能是不可接受的。例如(-1)**0.5生成i,在Python中显示为1j(忽略浮点错误)。

    抓住错误,继续前进。由于您可能希望捕获更高级别的错误,我建议将ValueErrorsqrt转换为自定义错误:

    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]
    

  •  类似资料:
    • 我正在将oracle从10升级到12,对于这个特定的项目,我遇到了以下错误: 似乎它没有识别我在DataSource上添加的配置: 我们使用的是Java 8,我们对代码有这些依赖关系: 问题是它正在为另一个项目工作(与这个项目具有相同的结构,但由于某种原因它在这里不起作用) 是否有任何遗漏或我可以找到问题并解决问题的地方?

    • 我正在使用Guava缓存热数据。当缓存中不存在数据时,我必须从数据库中获取数据: 我的问题是当数据不存在于数据库中时,我希望它返回并且不做任何缓存。但Guava保存与缓存中的关键字,并抛出一个异常,当我得到它: com.google.common.cache.CacheLoader$InvalidCacheLoadExcION: CacheLoader为shisoft键返回null。 我们如何避免

    • 问题内容: 我试图写一个近似平方根的函数(我知道有数学模块……我想自己做),但我被浮点运算搞砸了。如何避免这种情况? 使用它会产生以下结果: 我意识到我可以使用,但是我希望能够做到这一点非常准确。我希望能够计算出6或7位数字。如果我四舍五入,那将是不可能的。我想了解如何在Python中正确处理浮点计算。 问题答案: 这实际上与Python无关- 使用硬件的二进制浮点算法,您会在任何语言中看到相同的

    • 问题内容: 我正在尝试使用一些UI按钮将位置移动0.1或-0.1来影响3D模型的转换。 我的模型位置是一个三维浮点数,因此简单地向其中一个值添加0.1f会导致明显的舍入误差。虽然我可以使用BigDecimal之类的东西来保持精度,但我仍然必须将其从浮点数转换为最后的浮点数,并且它始终会产生愚蠢的数字,这使我的UI看起来一团糟。 我可以将显示的值设为漂亮,但是舍入错误只会随着更多的编辑而变得更糟,它

    • 我有一个类,它有一个接口。 另一个类将使用此接口 但在我把界面弄糊涂后,它就不工作了。我的Proguard:

    • Lodash castArray函数没有任何特殊之处。有没有什么方法可以在没有任何外部库的情况下,利用最新的语言功能解决这个问题,但时间很短? 如果您不熟悉该任务: 有没有办法在没有类型检查的情况下做到这一点?请注意,我寻找最短的等效物ES6。