Есть ли в Python функция heaviside, аналогичная функции MATLAB heaviside
?
Я изо всех сил пытаюсь найти его.
Есть ли в Python функция heaviside, аналогичная функции MATLAB heaviside
?
Я изо всех сил пытаюсь найти его.
Если вы используете numpy версию 1.13.0 или более позднюю, вы можете использовать numpy.heaviside
:
In [61]: x
Out[61]: array([-2. , -1.5, -1. , -0.5, 0. , 0.5, 1. , 1.5, 2. ])
In [62]: np.heaviside(x, 0.5)
Out[62]: array([ 0. , 0. , 0. , 0. , 0.5, 1. , 1. , 1. , 1. ])
В старых версиях numpy вы можете реализовать его как 0.5 * (numpy.sign(x) + 1)
In [65]: 0.5 * (numpy.sign(x) + 1)
Out[65]: array([ 0. , 0. , 0. , 0. , 0.5, 1. , 1. , 1. , 1. ])
Вероятно, самый простой метод - это просто
def step(x):
return 1 * (x > 0)
Это работает как для одиночных чисел, так и для массивов numpy, возвращает целые числа и равно нулю для x = 0. Последние критерии могут быть предпочтительными в step(0) => 0.5
при определенных обстоятельствах.
Это часть sympy, которую вы можете установить с помощью pip install sympy
Из документов:
class sympy.functions.special.delta_functions.Heaviside
Heaviside Piecewise function. Heaviside function has the following properties:
1) diff(Heaviside(x),x) = DiracDelta(x) ( 0, if x<0 )
2) Heaviside(x) = < [*] 1/2 if x==0 ( 1, if x>0 )
Вы бы использовали его следующим образом:
In [1]: from sympy.functions.special.delta_functions import Heaviside
In [2]: Heaviside(1)
Out[2]: 1
In [3]: Heaviside(0)
Out[3]: 1/2
In [4]: Heaviside(-1)
Out[4]: 0
Вы также можете написать свой собственный:
heaviside = lambda x: 0.5 if x == 0 else 0 if x < 0 else 1
Хотя это может не соответствовать вашим потребностям, если вам нужна символическая переменная.
Я не уверен, есть ли он из коробки, но вы всегда можете написать один:
def heaviside(x):
if x == 0:
return 0.5
return 0 if x < 0 else 1
Как и для numpy 1.13, это numpy.heaviside
.
Не уверен, что лучший способ добиться успеха... но вот функция, которую я взломал.
def u(t):
unit_step = numpy.arange(t.shape[0])
lcv = numpy.arange(t.shape[0])
for place in lcv:
if t[place] == 0:
unit_step[place] = .5
elif t[place] > 0:
unit_step[place] = 1
elif t[place] < 0:
unit_step[place] = 0
return unit_step
def heaviside(xx):
return numpy.where(xx <= 0, 0.0, 1.0) + numpy.where(xx == 0.0, 0.5, 0.0)
Или, если numpy.where
слишком медленно:
def heaviside(xx):
yy = numpy.ones_like(xx)
yy[xx < 0.0] = 0.0
yy[xx == 0.0] = 0.5
return yy
Ниже приведены тайминги с numpy 1.8.2; некоторые оптимизации были сделаны в numpy 1.9.0, поэтому попробуйте сами:
>>> import timeit
>>> import numpy
>>> array = numpy.arange(10) - 5
>>> def one():
... return numpy.where(array <= 0, 0.0, 1.0) + numpy.where(array == 0.0, 0.5, 0.0)
...
>>> def two():
... yy = numpy.ones_like(array)
... yy[array < 0] = 0.0
... yy[array == 0] = 0.5
... return yy
...
>>> timeit.timeit(one, number=100000)
3.026144027709961
>>> timeit.timeit(two, number=100000)
1.5265140533447266
>>> numpy.__version__
'1.8.2'
На другой машине с другим numpy:
>>> timeit.timeit(one, number=100000)
0.5119631290435791
>>> timeit.timeit(two, number=100000)
0.5458788871765137
>>> numpy.__version__
'1.11.1'
>>> def three():
... return 0.5*(numpy.sign(array) + 1)
...
>>> timeit.timeit(three, number=100000)
0.313539981842041
Простое решение:
import numpy as np
amplitudes = np.array([1*(x >= 0) for x in range(-5,6)])