2011-04-05 2 views
2

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

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 

Есть ли лучшие способы сделать это?

EDIT: Кроме того, как я могу подавить предупреждение:

Warning: invalid value encountered in divide 

ответ

7

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. ] 

К "unnormalize" делать,

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] 
+0

+1: Я на самом деле думаю, что это лучший ответ для конкретного случая OP. Раньше я не встречал этот метод. Хорошая работа. – JoshAdel

3

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

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

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

b[np.isnan(b)] = 1.0 

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

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

Я не понимаю вашу ссылку на заблуждениях. OP ссылается на то, что sin (x)/x -> 1 при x -> 0 –

+0

@ Давид: Да, должен был применить L'Hospital, прежде чем я ответил на это. Исправленный. – JoshAdel

2

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

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

0

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

1

Постараюсь это

>>> 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

Я считаю, SymPy (символический питона) может сделать пределы, что то, что вы действительно просят (это решение справедливо только в качестве предела). Независимо от того, вы должны это проверить.

Смежные вопросы