首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Fortran中实现numpy样快速插值

在Fortran中实现numpy样快速插值
EN

Stack Overflow用户
提问于 2022-02-06 12:18:21
回答 1查看 175关注 0票数 3

我有一个数值例程,我需要运行它来求解某个方程,其中包含几个嵌套的四个循环。最初,我将这个例程写入Python中,使用numba.jit实现可接受的性能。然而,对于较大的系统规模,这个方法变得非常慢,所以我一直在将例程重写为Fortran,希望能够实现加速。然而,我发现我的Fortran版本比Python中的第一个版本慢得多,比第一个版本慢了2-3倍。

我相信瓶颈是一个线性插值函数,它在每个最里面的循环上被调用。在Python实现中,我使用numpy.interp,它与numba.jit结合起来似乎非常快。在Fortran中,我编写了我自己的插值函数,它是这样的:

代码语言:javascript
复制
  complex*16 function interp(x_dat, y_dat, N_dat, x)
    implicit none
    integer, intent(in) :: N_dat
    real*8, dimension(N_dat), intent(in) :: x_dat
    complex*16, dimension(N_dat), intent(in) :: y_dat
    real*8, intent(in) :: x

    complex*16 :: y, y1, y2
    integer :: i, i1, i2, im

    if(x <= x_dat(1)) then
      y = y_dat(1)
    else if(x >= x_dat(N_dat)) then
      y = y_dat(N_dat)
    else
      im = MINLOC(DABS(x_dat - x), DIM=1)
      if(x_dat(im) >=x ) then
        i1 = im
        i2 = im - 1
      else
        i1 = im + 1
        i2 = im
      end if

      y1 = y_dat(i1)
      y2 = y_dat(i2)

      y = y1 + (x-x_dat(i1))*(y2 - y1)/(x_dat(i2) - x_dat(i1))
    end if
    interp = y
    return
  end function interp

注意,我需要插值复杂的数据。如果我的诊断是正确的,这个函数比numpy.interp慢得多,因为插值必须在每个循环中调用,大大降低了整个程序的速度。

有没有人知道在Fortran中是否有实现像插值速度一样的Numpy的方法?或者,如果我的插值函数,如上面所示,在某种程度上效率很低?我还没有多少编码Fortran的经验。

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-02-06 13:40:02

如果你想让我们做得比猜测更好的话,请看一下@IanBush的评论。

代码语言:javascript
复制
im = MINLOC(DABS(x_dat - x), DIM=1)

这占用了您所有的时间,因为这一行是O(N)大小的x_dat,其他的都是O(1)

如果x_dat是线性行距的,那么您可以用

代码语言:javascript
复制
im = 1 + nint((N_dat-1)*(x-x_dat(1))/(x_dat(N_dat)-x_dat(1)))

或者更好的方法是跳过im,计算i1i2

代码语言:javascript
复制
i1 = 1 + floor((N_dat-1)*(x-x_dat(1))/(x_dat(N_dat)-x_dat(1)))
i2 = i1 + 1

如果x_dat不是线性行距,而是具有其他有用的属性,那么如果可能的话,您希望使用这些属性来计算im

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71007062

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档