Фиксация особенности функции - PullRequest
2 голосов
/ 05 апреля 2011

Предположим, у вас есть такая функция, как

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

Ответы [ 6 ]

7 голосов
/ 05 апреля 2011

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]
3 голосов
/ 05 апреля 2011

Если вы уже используете numpy, тогда:

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

Произведет безошибочный расчет, оставив значение NaN в b[0].Затем вы можете просто заменить его следующим, если вы хотите его обработать:

b[np.isnan(b)] = 1.0

Обновление Чтобы подавить предупреждение, попробуйте:

np.seterr(divide='ignore') # Or possibly np.seterr(invalid='ignore')
2 голосов
/ 05 апреля 2011

В общем, вы не можете написать простой fix декоратор, как вы можете себе представить.Например, общая функция не обязательно должна иметь конечное предельное значение в сингулярности, как в этом конкретном примере.

Обычной практикой является реализация специальной обработки в каждом конкретном случае.

1 голос
/ 05 апреля 2011

Я попробую это

>>> 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
0 голосов
/ 05 апреля 2011

Я полагаю, что sympy (символический питон) может делать ограничения, о чем вы действительно просите (это решение верно только как limit ).В любом случае, вы должны это проверить.

0 голосов
/ 05 апреля 2011

Я не знаю, сработает ли это для ваших точных целей, но есть библиотека python под названием sage , которая может справиться с большинством ситуаций типа Calculus.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...