Частная производная в Python

Я медленно перехожу с C на Python. На этот раз мне нужно численно рассчитать частные производные по заданной сетке. Я знаю, как это сделать на C, поэтому на данный момент я просто использую встроенный адаптер, т.е.

def dz(x,X,Y,Z,dx):
    y = numpy.zeros((X,Y,Z), dtype='double');
    code = """
            int i, j, k;
            for (i=0; i<X-1; i++){
                for(k=0; k<Y; k++){
                    for (j=0; j<Z; j++){
                        y[i,k,j] = (x[i+1, k, j] - x[i, k, j])/dx;
                        }
                    }
                }
            for (j=0; j<Z; j++){
                for(k=0; k<Y; k++){
                    y[X-1,k,j] = - x[X-1, k, j]/dx;
                    }
                }
        """
    weave.inline(code, ['x', 'y', 'dx', 'X', 'Y', 'Z'], \
                type_converters=converters.blitz, compiler = 'gcc');
    return y;

где x и y — это трехмерные массивы numpy, как вы можете видеть, а второй цикл обозначает граничные условия. Конечно, я могу реализовать ту же логику и на чистом Python, но код будет неэффективным. Интересно, однако, можно ли вычислить частную производную, используя чистый numpy? Буду признателен за любую помощь, которую может предоставить любой.


person Eugene B    schedule 22.07.2014    source источник
comment
Почему вы беспокоитесь о переходе с C на Python, если вы просто собираетесь написать C и заставить Python выполнять его (неэффективно)?   -  person ydaetskcoR    schedule 22.07.2014
comment
Если вы имеете дело с PDE, FEniCS (fenicsproject.org/documentation/tutorial/index.html) может быть вам интересно   -  person Dietrich    schedule 22.07.2014
comment
X, Y, Z в смысле? форма x?   -  person emeth    schedule 22.07.2014
comment
Вот и все: я хотел бы перейти на чистый Python, хитрость в том, что текущая реализация, которую я имею, является самой быстрой, которую я могу сделать, хотя я уверен, что существует чистое решение numpy. Впрочем, вы правы: с тем решением, которое у меня есть на данный момент, нет смысла переходить на Python.   -  person Eugene B    schedule 22.07.2014
comment
Да, только размеры.   -  person Eugene B    schedule 22.07.2014
comment
Возможно, stackoverflow.com/questions/16078818/ может помочь. Я нашел другие интересные возможности поиска в Интернете с помощью numpy partial derivative   -  person wwii    schedule 22.07.2014
comment
Я много искал, но не нашел этой ссылки. Я посмотрю! Благодарю вас!   -  person Eugene B    schedule 22.07.2014


Ответы (3)


np.diff может быть самым идиоматичным numpy способ сделать это:

y = np.empty_like(x)
y[:-1] = np.diff(x, axis=0) / dx
y[-1] = -x[-1] / dx

Вас также может заинтересовать np.gradient, хотя эта функция принимает градиент по всем измерениям входного массива, а не по одному.

person ali_m    schedule 22.07.2014

Если вы используете numpy, это должно делать то же самое, что и ваш код выше:

y = np.empty_like(x)
y[:-1] = (x[1:] - x[:-1]) / dx
y[-1] = -x[-1] / dx

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

y = np.empty_like(x)
y[:, :-1] = (x[:, 1:] - x[:, :-1]) / dx
y[:, -1] = -x[:, -1] / dx
person Jaime    schedule 22.07.2014

numpy.gradient теперь поддерживает оценку производных также в одном направлении.

a = np.array([[1,2,3],[2,3,5]])
np.gradient(a, axis=0)

что дает единственную частную производную по оси 0:

array([[1., 1., 2.],
       [1., 1., 2.]])

Аргумент axis задает набор направлений для оценки производной.

person ASJ    schedule 04.01.2020