【问题标题】:Partial derivative in PythonPython中的偏导数
【发布时间】:2014-07-22 11:33:41
【问题描述】:

我正在慢慢地从 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;

如您所见,xy 是 3D numpy 数组,第二个循环代表边界条件。当然,我可以在纯 Python 中实现相同的逻辑,但是代码会效率低下。不过,我想知道是否可以使用纯 numpy 计算偏导数?任何人都可以提供任何帮助,我将不胜感激。

【问题讨论】:

  • 如果您只是要编写 C 并让 Python 执行它(效率低下),为什么还要费心从 C 迁移到 Python?
  • 如果您正在处理 PDE,FEniCS (fenicsproject.org/documentation/tutorial/index.html) 可能对您很感兴趣
  • X, Y, Z 是什么意思? x的形状?
  • 就是这样:我想转向纯 Python,诀窍是,我目前的实现是我能做出的最快的,尽管我确信存在一个纯 numpy 解决方案。不过,您是对的:根据我目前的解决方案,转向 Python 是没有意义的。
  • 是的,只是尺寸。

标签: python numpy derivative


【解决方案1】:

np.diff 可能是最惯用的 numpy 方式:

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

您可能还对np.gradient 感兴趣,尽管此函数在输入数组的所有维度上而不是单个维度上获取梯度。

【讨论】:

    【解决方案2】:

    如果你使用的是 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
    

    【讨论】:

      【解决方案3】:
      def dz(x,dx):
          y = numpy.zeros(x.shape, dtype='double')
          y[:-1] = (x[1:] - x[:-1]) / dx
          y[-1]  = -x[-1] / dx
          return y
      

      【讨论】:

        【解决方案4】:

        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 指定了一组计算导数的方向。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-10-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多