从 Python 的 Fortran 中获取两个值?
Getting two values from fortran for Python?
是否可以从 Fortran 中获取两个值?
例如,我想从矩阵
中获得最大分数和这个坐标
# python code
import numpy as np
matrix = np.array([[1, 10, 3, 4, 9],
[2, 1, 0, 9, 13],
[3, 5, 10, 18, 3]])
max_score= 0
column_coord = 0
row_coord = 0
for i in range(len(matrix[:,0])):
for j in range(len(matrix[0,:])):
if matrix[i, j] >= max_score:
# getting max_score, column, row coordinate
max_score= matrix[i, j]
column_coord = i
row_coord = j
print(max_score, column_coord, row_coord)
这段代码工作正常,但如果矩阵变大,将花费很多时间
找到我想要的值。
所以,我决定使用 f2py 来加快计算速度,这就是 fortran 代码。
cc 是列长,rr 是行长。
subroutine findthemax(cc, rr, matrix, max_score, col_coord, row_coord)
integer, intent(in) :: cc, rr
integer, intent(in) :: matrix(0:cc, 0:rr)
integer, intent(out) :: max_score, col_coord, row_coord
max_score = 0
col_coord = 0
row_coord = 0
do i = 1, cc
do j = 1, rr
if (matrix(i, j).GE.max_score) then
max_score = matrix(i, j)
col_coord = i
row_coord = j
end if
end do
end do
return
end subroutine
我想获取max_score、col_coord、row_coord,所以导入了findthemax模块
(名为findthemax.f90)我用f2py改造的。
import numpy as np
matrix = np.array([[1, 10, 3, 4, 9],
[2, 1, 0, 9, 13],
[3, 5, 10, 18, 3]])
cc = len(matrix[:,0])
rr = len(matrix[0,:])
max_score, column_coord, row_coord = findthemax.findthemax(cc, rr, matrix)
我不知道为什么这行不通,那是因为我实际上不知道
如何使用 fortran 和 f2py return 两个以上的值。有人可以告诉我如何
从 Fortran 获取多个值?
您对最大值及其索引的实现是慢,因为它使用python的循环标准。
Numpy 有大量 fast/optimized 的内置函数,大多数甚至在底层使用 Fortran 代码。
对于您的问题,您应该查看 numpy.argmax。
示例代码
import numpy as np
matrix = np.array([[1, 10, 3, 4, 9],
[2, 1, 0, 9, 13],
[3, 5, 10, 18, 3]])
# get flat index of maximum
flat = np.argmax(matrix)
# flat index to row/col indices
(row, col) = np.unravel_index(flat, matrix.shape)
# max value
mymax = matrix[row,col]
在 fortran 方面你有
subroutine findthemax(cc, rr, matrix, max_score, col_coord, row_coord)
integer, intent(in) :: cc, rr
integer, intent(in) :: matrix(0:cc, 0:rr)
integer, intent(out) :: max_score, col_coord, row_coord
max_score = 0
col_coord = 0
row_coord = 0
do i = 1, cc !Does this need a 0, cc ??
do j = 1, rr !Does this need a 0, rr ??
if (matrix(i, j).GE.max_score) then
max_score = matrix(i, j)
col_coord = i
row_coord = j
end if
end do
end do
return
end subroutine
你可能想要这样的东西:
subroutine findthemax(cc, rr, matrix, max_score, col_coord, row_coord)
integer, intent(in) :: cc, rr
integer, intent(in) :: matrix(cc+1, rr+1) ! not zero ??
integer, intent(out) :: max_score, col_coord, row_coord
max_score = 0
col_coord = 0
row_coord = 0
Outter_Loop: do j = 1, UBOUND(MATRIX, DIM=2)
Inner_Loop: do i = 1, UBOUND(MATRIX, DIM=1)
if (matrix(i, j) >= max_score) then
max_score = matrix(i, j)
col_coord = i
row_coord = j
end if
end do Inner_Loop
end do Outter_Loop
return
end subroutine
使用 fortran 中的内部函数会更优雅一些:
subroutine findthemax(cc, rr, matrix, threeple)
IMPLICIT NONE
integer, intent(in) :: cc, rr
integer, intent(in) :: matrix(cc+1,rr+1) ! not 0:rr, or its it 1:rr+1 ???
integer, intent(OUT) :: Threeple(3)
integer, DIMENSION(2) :: At_Min
! YOU MAY NEED TRANSPOSE - but just intentionally reverse rows and columns if python is row major??
Threeple(1) = MAXVAL(matrix)
At_Min = MAXLOC(Matrix)
Threeple(2) = At_Min(2) ! Or is it (1)??
Threeple(3) = At_Min(1) ! Or is it (2)??
return
end subroutine findthemax
您可以通过以下方式使用具有 多个 return 值 的 Fortran 子例程。
Fortran 代码findthemax.f90
subroutine findthemax(matrix, max_score, row, col)
integer, intent(in) :: matrix(:,:)
integer, intent(out) :: max_score, row, col
integer :: ind(2)
ind = maxloc(matrix)
row = ind(1)
col = ind(2)
max_score = matrix(row,col)
end subroutine
通过f2py编译
$ f2py -c findthemax.f90 -m findthemax
将其导入您的 python 代码
import findthemax
import numpy as np
matrix = np.array([[1, 10, 3, 4, 9],
[2, 1, 0, 9, 13],
[3, 5, 10, 18, 3]])
(max_score, row, col) = findthemax.findthemax(matrix)
print(max_score) # 18
print(row) # 3
print(col) # 4
是否可以从 Fortran 中获取两个值? 例如,我想从矩阵
中获得最大分数和这个坐标# python code
import numpy as np
matrix = np.array([[1, 10, 3, 4, 9],
[2, 1, 0, 9, 13],
[3, 5, 10, 18, 3]])
max_score= 0
column_coord = 0
row_coord = 0
for i in range(len(matrix[:,0])):
for j in range(len(matrix[0,:])):
if matrix[i, j] >= max_score:
# getting max_score, column, row coordinate
max_score= matrix[i, j]
column_coord = i
row_coord = j
print(max_score, column_coord, row_coord)
这段代码工作正常,但如果矩阵变大,将花费很多时间
找到我想要的值。
所以,我决定使用 f2py 来加快计算速度,这就是 fortran 代码。
cc 是列长,rr 是行长。
subroutine findthemax(cc, rr, matrix, max_score, col_coord, row_coord)
integer, intent(in) :: cc, rr
integer, intent(in) :: matrix(0:cc, 0:rr)
integer, intent(out) :: max_score, col_coord, row_coord
max_score = 0
col_coord = 0
row_coord = 0
do i = 1, cc
do j = 1, rr
if (matrix(i, j).GE.max_score) then
max_score = matrix(i, j)
col_coord = i
row_coord = j
end if
end do
end do
return
end subroutine
我想获取max_score、col_coord、row_coord,所以导入了findthemax模块
(名为findthemax.f90)我用f2py改造的。
import numpy as np
matrix = np.array([[1, 10, 3, 4, 9],
[2, 1, 0, 9, 13],
[3, 5, 10, 18, 3]])
cc = len(matrix[:,0])
rr = len(matrix[0,:])
max_score, column_coord, row_coord = findthemax.findthemax(cc, rr, matrix)
我不知道为什么这行不通,那是因为我实际上不知道
如何使用 fortran 和 f2py return 两个以上的值。有人可以告诉我如何
从 Fortran 获取多个值?
您对最大值及其索引的实现是慢,因为它使用python的循环标准。 Numpy 有大量 fast/optimized 的内置函数,大多数甚至在底层使用 Fortran 代码。
对于您的问题,您应该查看 numpy.argmax。
示例代码
import numpy as np
matrix = np.array([[1, 10, 3, 4, 9],
[2, 1, 0, 9, 13],
[3, 5, 10, 18, 3]])
# get flat index of maximum
flat = np.argmax(matrix)
# flat index to row/col indices
(row, col) = np.unravel_index(flat, matrix.shape)
# max value
mymax = matrix[row,col]
在 fortran 方面你有
subroutine findthemax(cc, rr, matrix, max_score, col_coord, row_coord)
integer, intent(in) :: cc, rr
integer, intent(in) :: matrix(0:cc, 0:rr)
integer, intent(out) :: max_score, col_coord, row_coord
max_score = 0
col_coord = 0
row_coord = 0
do i = 1, cc !Does this need a 0, cc ??
do j = 1, rr !Does this need a 0, rr ??
if (matrix(i, j).GE.max_score) then
max_score = matrix(i, j)
col_coord = i
row_coord = j
end if
end do
end do
return
end subroutine
你可能想要这样的东西:
subroutine findthemax(cc, rr, matrix, max_score, col_coord, row_coord)
integer, intent(in) :: cc, rr
integer, intent(in) :: matrix(cc+1, rr+1) ! not zero ??
integer, intent(out) :: max_score, col_coord, row_coord
max_score = 0
col_coord = 0
row_coord = 0
Outter_Loop: do j = 1, UBOUND(MATRIX, DIM=2)
Inner_Loop: do i = 1, UBOUND(MATRIX, DIM=1)
if (matrix(i, j) >= max_score) then
max_score = matrix(i, j)
col_coord = i
row_coord = j
end if
end do Inner_Loop
end do Outter_Loop
return
end subroutine
使用 fortran 中的内部函数会更优雅一些:
subroutine findthemax(cc, rr, matrix, threeple)
IMPLICIT NONE
integer, intent(in) :: cc, rr
integer, intent(in) :: matrix(cc+1,rr+1) ! not 0:rr, or its it 1:rr+1 ???
integer, intent(OUT) :: Threeple(3)
integer, DIMENSION(2) :: At_Min
! YOU MAY NEED TRANSPOSE - but just intentionally reverse rows and columns if python is row major??
Threeple(1) = MAXVAL(matrix)
At_Min = MAXLOC(Matrix)
Threeple(2) = At_Min(2) ! Or is it (1)??
Threeple(3) = At_Min(1) ! Or is it (2)??
return
end subroutine findthemax
您可以通过以下方式使用具有 多个 return 值 的 Fortran 子例程。
Fortran 代码findthemax.f90
subroutine findthemax(matrix, max_score, row, col)
integer, intent(in) :: matrix(:,:)
integer, intent(out) :: max_score, row, col
integer :: ind(2)
ind = maxloc(matrix)
row = ind(1)
col = ind(2)
max_score = matrix(row,col)
end subroutine
通过f2py编译
$ f2py -c findthemax.f90 -m findthemax
将其导入您的 python 代码
import findthemax
import numpy as np
matrix = np.array([[1, 10, 3, 4, 9],
[2, 1, 0, 9, 13],
[3, 5, 10, 18, 3]])
(max_score, row, col) = findthemax.findthemax(matrix)
print(max_score) # 18
print(row) # 3
print(col) # 4