2016-04-01 4 views
2

Я пытаюсь построить функцию, которая определена условно. В частности: U (x) = (2 ** delta)/((Dd) ** delta) * (D/2 - (x-x0)) ** delta, для abs (x-x0) меньше D/2 и 0 в противном случае.Условное построение с помощью Numpy и Pyplot

Но моя проблема в том, что я хочу иметь x, x0 как массивы numpy, потому что так я использую их в остальной части моего фактического кода.

следующего примера я настройка:

import numpy as np 
import matplotlib.pyplot as plt 
AD = 0.2 
D = 0.4 
delta = 8 

def Parabolic(x, delta, D, AD): 
    x0 = np.round(x) 
    tempx = np.abs(x-x0) 
    tempD = D/2*np.ones(len(x)) 
    if tempx<tempD: 
     return ((2**delta)/(D-AD)**delta)*(D/2 - (x-x0))**delta 
    else: 
     return 0 

figure = plt.figure(figsize=(10,8), dpi=72) 
xmin = -1.0 
xmax = 1.0 
X = np.linspace(xmin,xmax,1000) 
plt.plot(X, Parabolic(X, delta=8, D=0.4, AD=0.2)) 

Очевидно, что этот пример не работает, так как линия tempx<tempD вызывает ошибку, что Истина-значение из списка является неоднозначным.

Я искал документацию numpy и нашел функцию np.less (tempx, tempD). Но если я заменил tempx < tempD на np.less(tempx, tempD), он все равно не работает, так как я снова прошу значение истины для всего списка. Я понимаю, что проблема связана не с numpy, а с моей неспособностью понять, как использовать логические функции, которые предоставляет numpy.

Прошу прощения, если это ответили каким-то образом в другом посте, я искал в этом форуме, но не смог найти что-то еще, кроме метода curve(). Однако я хочу сохранить формат numpy.array для использования в моих действительных кодах. Я бы поспорил, что ответ должен быть очень простым, я просто не могу думать об этом.

+0

На вашей ошибки см Http: // stackoverflow.com/a/30081652/901925 и его боковой панели. – hpaulj

ответ

3

Попробуйте который использует NumPy логические массивы:

import numpy as np 
import matplotlib.pyplot as plt 
AD = 0.2 
D = 0.4 
delta = 8 

def Parabolic(x, delta, D, AD): 
    rtn_arr = np.zeros(len(x)) 
    x0 = np.round(x) 
    tempx = np.abs(x-x0) 
    tempD = D/2*np.ones(len(x)) 
    lgc_arr = tempx<tempD 
    x_cut = x[lgc_arr] 
    x0_cut = x0[lgc_arr] 
    rtn_arr[lgc_arr] = ((2**delta)/(D-AD)**delta)*(D/2 - (x_cut-x0_cut))**delta 
    return rtn_arr 

figure = plt.figure(figsize=(10,8), dpi=72) 
xmin = -1.0 
xmax = 1.0 
X = np.linspace(xmin,xmax,1000) 
plt.plot(X, Parabolic(X, delta=8, D=0.4, AD=0.2)) 
+0

Ну, это именно то, что я искал. Мне удалось решить мою проблему, используя списки python и добавить, но, конечно, это было не так хорошо. Твой был то, что я смотрел. Я не знал, что можно использовать 'x_cut = x [lgc_array]', чтобы получить только те элементы, которые соответствуют true! Последнее: Не могли бы вы объяснить мне, как работает строка 'lgc_arr = tempx

+0

'tempx hpaulj

+0

@GeorgeDatseris Точно, как вы говорите. Массивы numpy переопределяют условные операторы (что может быть сделано для любого настраиваемого класса https://docs.python.org/2/library/stdtypes.html), так что использование '>, <' и т. Д. На массивах numpy возвращает массивы numpy , Затем 'tempx Xirtaminu

2

Parabolic должен быть ufunc, так что вы не можете поставить тест питона в вашем коде.

простое решение является:

def Parabolic(x, delta, D, AD): 
    x0 = np.round(x) 
    tempx = np.abs(x-x0) 
    tempD = D/2*np.ones(len(x)) 
    u=(((2**delta)/(D-AD)**delta)*(D/2 - (x-x0))**delta) 
    u[tempx>=tempD]=0 
    return u 

или избежать ненужных вычислений:

def Parabolic2(x, delta, D, AD): 
    x0 = np.round(x) 
    tempx = np.abs(x-x0) 
    tempD = D/2*np.ones(len(x)) 
    u= zeros_like(x) 
    valid=tempx<tempD 
    u[valid]=(((2**delta)/(D-AD)**delta)*(D/2 - (x-x0)[valid])**delta) 
    return u 

Второй slighty быстрее:

In [141]: %timeit Parabolic(x,8,.4,.2) 
1000 loops, best of 3: 310 µs per loop 

In [142]: %timeit Parabolic2(x,8,.4,.2) 
1000 loops, best of 3: 218 µs per loop 
+0

Это также хороший обходной путь и довольно простой код. Однако это означает, что я должен вычислить функцию для всех значений, малых и больших. И это займет много времени в обычном коде. Я намерен использовать первый ответ для очень высоких и очень малых значений функции 'u', главным образом, чтобы избежать вычислений. –

+0

ok; В этом случае я добавляю другой способ. –

+0

Я не думаю, что вторая версия будет работать, поскольку длина 'u [tempx Xirtaminu

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