numpy.roll函数的Fortran等效函数

ibps3vxo  于 2023-06-23  发布在  其他
关注(0)|答案(2)|浏览(101)

Python的numpy.roll函数沿着轴滚动数组。示例:

from numpy import roll, array
x = array([[1,0,2],[2,1,9],[5,5,1]])
print(roll(x, 1, axis=0))

将矩阵x变换为

array([[5, 5, 1],
       [1, 0, 2],
       [2, 1, 9]])

我尝试在Fortran中通过切片矩阵行并将其附加到现有矩阵来实现这一点:

program myfun

implicit none
integer, parameter :: N=3
real, dimension(N,N) :: m
integer :: i, j

m = 0
do i = 1, N
    m(i, i) = 1.0
enddo
m(3,1) = 2
m(3,2) = 9
m(1,3) = 5
m(1,2) = 2
m(2,3) = 5

print *, '', [m(:,N), m]

end program myfun

这产生矩阵

[5, 5, 1]
[1, 0, 2]
[2, 1, 9]
[5, 5, 1]  <- need to remove this row (how?)

这是在Fortran中执行numpy.roll的最佳方式吗?如果是,我如何删除矩阵的最后一行?

izkcnapc

izkcnapc1#

如果我明白你在问什么cshift是你想要的。下面是一个示例,您可以找到更多详细信息here
项目:

Program test_cshift

  Use iso_fortran_env, Only : stdout => output_unit
  
  Implicit None

  Integer, Dimension( 1:3, 1:3 ) :: m = Reshape( [ 1, 0, 2,   &
                                                   2, 1, 9,   &
                                                   5, 5, 1 ], &
                                                   Shape( m ) )

  Write( stdout, * ) 'Original'
  Write( stdout, '( 3( 3( i1, 1x ), / ) )' ) m
  Write( stdout, * ) 'After cshift'
  Write( stdout, '( 3( 3( i1, 1x ), / ) )' ) Cshift( m, -1, 2 )

End Program test_cshift

汇编和链接:

ijb@ijb-Latitude-5410:~/work/stack$ gfortran --version
GNU Fortran (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

ijb@ijb-Latitude-5410:~/work/stack$ gfortran -Wall -Wextra -pedantic -fcheck=all -std=f2018 -O -g cshift.f90

测试:

ijb@ijb-Latitude-5410:~/work/stack$ ./a.out
 Original
1 0 2
2 1 9
5 5 1

 After cshift
5 5 1
1 0 2
2 1 9

ijb@ijb-Latitude-5410:~/work/stack$
vh0rcniy

vh0rcniy2#

Python numpy.roll函数沿着指定的轴移动数组中的元素,首先重新引入滚动到最后一个位置之外的元素。
在Fortran中,没有与numpy.roll等效的内置函数。但是,您可以使用数组切片和串联来实现相同的功能。
Fortran代码中的问题是,您将最后一行附加到矩阵的末尾,但没有将其从原始位置删除。
这里有一个方法:

program myfun

    implicit none
    integer, parameter :: N=3
    real, dimension(N,N) :: m, m_new
    integer :: i, j

    m = 0
    do i = 1, N
        m(i, i) = 1.0
    enddo
    m(3,1) = 2
    m(3,2) = 9
    m(1,3) = 5
    m(1,2) = 2
    m(2,3) = 5

    m_new = m(2:N, :)  ! Slice from the second row to the end
    m_new(N, :) = m(1, :)  ! Put the first row at the end.

    print *, m_new

end program myfun

在这段代码中,m(2:N, :)从第二行到末尾对矩阵m进行切片,m_new(N, :) = m(1, :)m的第一行放在m_new的末尾。这有效地将矩阵行向上“滚动”一行,类似于numpy.roll(m, 1, axis=0)

相关问题