修复函数的奇点

发布于 2024-10-30 10:54:05 字数 927 浏览 2 评论 0原文

假设您有一个像

F = lambda x: sin(x)/x

评估 F(0.0) 这样的函数会导致除以零警告,并且不会给出 1.0 的预期结果。是否可以编写另一个函数 fix_singularity ,该函数在应用于上述函数时会给出所需的结果,以便

fix_singularity(F)(0.0) == 1.0

或正式 fix_singularity 应通过以下测试:

import numpy as np

def test_fix_singularity():

    F = lambda x: np.sin(x)/x

    x = np.array((0.0, pi))

    np.testing.assert_array_almost_equal( F(x), [nan, 0] )

    np.testing.assert_array_almost_equal( fix_singularity(F)(x), [1, 0] )

一种可能的实现是

def fix_singularity(F):
    """ Fix the singularity of function F(x) """

    def L(x):
        f = F(x)
        i = np.isnan(f)
        f[i] = F(x[i] + 1e-16)
        return f

    return L

有更好的方法吗?

编辑: 另外我怎样才能抑制警告:

Warning: invalid value encountered in divide

Assume you have a function like

F = lambda x: sin(x)/x

Evaluating F(0.0) would result in a divide by zero warning, and would not give the expected result of 1.0. Is it possible to write another function fix_singularity that would give the desired result when applied to the above function, so that

fix_singularity(F)(0.0) == 1.0

Or formally fix_singularity should pass the following tests:

import numpy as np

def test_fix_singularity():

    F = lambda x: np.sin(x)/x

    x = np.array((0.0, pi))

    np.testing.assert_array_almost_equal( F(x), [nan, 0] )

    np.testing.assert_array_almost_equal( fix_singularity(F)(x), [1, 0] )

One possible implementation is

def fix_singularity(F):
    """ Fix the singularity of function F(x) """

    def L(x):
        f = F(x)
        i = np.isnan(f)
        f[i] = F(x[i] + 1e-16)
        return f

    return L

Are there better ways of doing this?

EDIT:
Also how can I suppress the warning:

Warning: invalid value encountered in divide

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

同尘 2024-11-06 10:54:05

numpy 有一个 sinc() 函数,它是函数的规范化形式,即

F = lambda x: sin(pi*x) / (pi*x)

它正确处理 x == 0.0 的情况,

In [16]: x = numpy.linspace(-1,1,11)

In [17]: print x
[-1.  -0.8 -0.6 -0.4 -0.2  0.   0.2  0.4  0.6  0.8  1. ]

为了“非正常化”,

In [22]: s = numpy.sinc(x/numpy.pi)

In [23]: print s.round(2)
[ 0.84  0.9   0.94  0.97  0.99  1.    0.99  0.97  0.94  0.9   0.84]

numpy has a sinc() function, which is the normalised form of your function, i.e.

F = lambda x: sin(pi*x) / (pi*x)

It handles the case for x == 0.0 correctly,

In [16]: x = numpy.linspace(-1,1,11)

In [17]: print x
[-1.  -0.8 -0.6 -0.4 -0.2  0.   0.2  0.4  0.6  0.8  1. ]

To "unnormalize" do,

In [22]: s = numpy.sinc(x/numpy.pi)

In [23]: print s.round(2)
[ 0.84  0.9   0.94  0.97  0.99  1.    0.99  0.97  0.94  0.9   0.84]
一笑百媚生 2024-11-06 10:54:05

如果您已经在使用 numpy,则:

a = np.linspace(0.0,2*np.pi,100)
b = np.sin(a)/a

将计算而不会出错,并在 b[0] 中留下 NaN 值。如果您想这样处理的话,您可以将其替换为以下内容:

b[np.isnan(b)] = 1.0

更新 要抑制警告,请尝试:

np.seterr(divide='ignore') # Or possibly np.seterr(invalid='ignore')

If you are already using numpy then:

a = np.linspace(0.0,2*np.pi,100)
b = np.sin(a)/a

Will calculate without error leaving a NaN value in b[0]. You could then just replace it by the following if that's how you want to handle it:

b[np.isnan(b)] = 1.0

Update To suppress the warning, try:

np.seterr(divide='ignore') # Or possibly np.seterr(invalid='ignore')
Spring初心 2024-11-06 10:54:05

一般来说,您不能像您想象的那样编写一个简单的 fix 装饰器。例如,一般函数不需要像这个特定示例那样在奇点处具有有限极限值。

通常的做法是根据具体情况实施特殊处理。

In general you can't write a simple fix decorator as you might imagine. For example, a general function need not have a finite limiting value at a singularity as this particular example does.

Normal practice is to implement special handling on a case by case basis.

君勿笑 2024-11-06 10:54:05

我会尝试这个

>>> def fix_singularity(F):
...     def L(x):
...         x1 = max(x,1e-16) if x >=0 else min(x,-1e-16)
...         return F(x1)
...     return L
...
>>> FS = fix_singularity(F)
>>> FS(0.0)
1.0
>>> FS(-1e-17)
1.0

I'll try this

>>> def fix_singularity(F):
...     def L(x):
...         x1 = max(x,1e-16) if x >=0 else min(x,-1e-16)
...         return F(x1)
...     return L
...
>>> FS = fix_singularity(F)
>>> FS(0.0)
1.0
>>> FS(-1e-17)
1.0
权谋诡计 2024-11-06 10:54:05

我不知道这是否适合您的确切目的,但是有一个名为 sage 的 python 库 可以处理相当多的微积分类型的情况。

I don't know if this would work for your exact purposes, but there's a python library called sage that can handle quite a bit of Calculus-type situations.

拧巴小姐 2024-11-06 10:54:05

我相信 sympy (符号 python)可以做限制,这就是你真正要问的(该解决方案仅作为限制)。无论如何,你应该检查一下。

I believe sympy (symbolic python) can do limits, which is what you are really asking (that solution is only true as a limit). Regardless, you should check it out.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文