從一些實驗(*)看來,Python/f2py認爲np.int8
與logical*1
兼容,而np.bool
或np.bool8
不是由於某些原因。插入print *, "(fort) x = ", x
成foo.f90後,我們得到:
>>> foo.foo(np.array([ True, False, False ], dtype=np.bool))
copied an array: size=3, elsize=1
(fort) x = T F F
>>> foo.foo(np.array([ False, True, False ], dtype=np.bool8))
copied an array: size=3, elsize=1
(fort) x = F T F
>>> foo.foo(np.array([ False, False, True ], dtype=np.int8)) # no copy
(fort) x = F F T
由於True
和False
被簡單地映射到1和0,使用在Python端的int8
陣列可以是方便。
(*)一些實驗
在這裏,我改變了f2py意圖註釋inout
,看看我們是否可以從Fortran語言方面修改數組。
foo.f90:
subroutine foo(x, n)
use iso_c_binding
implicit none
integer n
logical*1 x(n)
! logical x(n)
! logical(c_bool) x(n)
!f2py intent(inout) x
!f2py intent(hide), depend(x) :: n=shape(x,0)
print *, "(fort) x = ", x
print *, "(fort) sizeof(x(1)) = ", sizeof(x(1))
print *, "(fort) resetting x(:) to true"
x(:) = .true.
end subroutine
test.py:
import numpy as np
import foo
for T in [ np.bool, np.bool8,
np.int, np.int8, np.int32, np.int64,
np.uint, np.uint8, np.uint32, np.uint64,
np.dtype('b'), np.dtype('int8'), np.dtype('int32') ]:
print("-------------------------")
print("dtype =", T)
x = np.array([ True, False, True ], dtype=T)
print("input x =", x)
try:
foo.foo(x)
print("output x =", x)
except:
print("failed")
結果與logical*1
:
-------------------------
dtype = <class 'bool'>
input x = [ True False True]
failed
-------------------------
dtype = <class 'numpy.bool_'>
input x = [ True False True]
failed
-------------------------
dtype = <class 'int'>
input x = [1 0 1]
failed
-------------------------
dtype = <class 'numpy.int8'>
input x = [1 0 1]
(fort) x = T F T
(fort) sizeof(x(1)) = 1
(fort) resetting x(:) to true
output x = [1 1 1]
-------------------------
dtype = <class 'numpy.int32'>
input x = [1 0 1]
failed
-------------------------
dtype = <class 'numpy.int64'>
input x = [1 0 1]
failed
-------------------------
dtype = <class 'numpy.uint64'>
input x = [1 0 1]
failed
-------------------------
dtype = <class 'numpy.uint8'>
input x = [1 0 1]
(fort) x = T F T
(fort) sizeof(x(1)) = 1
(fort) resetting x(:) to true
output x = [1 1 1]
-------------------------
dtype = <class 'numpy.uint32'>
input x = [1 0 1]
failed
-------------------------
dtype = <class 'numpy.uint64'>
input x = [1 0 1]
failed
-------------------------
dtype = int8
input x = [1 0 1]
(fort) x = T F T
(fort) sizeof(x(1)) = 1
(fort) resetting x(:) to true
output x = [1 1 1]
-------------------------
dtype = int8
input x = [1 0 1]
(fort) x = T F T
(fort) sizeof(x(1)) = 1
(fort) resetting x(:) to true
output x = [1 1 1]
-------------------------
dtype = int32
input x = [1 0 1]
failed
結果與logical
(默認的那種):
-------------------------
dtype = <class 'bool'>
input x = [ True False True]
failed
-------------------------
dtype = <class 'numpy.bool_'>
input x = [ True False True]
failed
-------------------------
dtype = <class 'int'>
input x = [1 0 1]
failed
-------------------------
dtype = <class 'numpy.int8'>
input x = [1 0 1]
failed
-------------------------
dtype = <class 'numpy.int32'>
input x = [1 0 1]
(fort) x = T F T
(fort) sizeof(x(1)) = 4
(fort) resetting x(:) to true
output x = [1 1 1]
-------------------------
dtype = <class 'numpy.int64'>
input x = [1 0 1]
failed
-------------------------
dtype = <class 'numpy.uint64'>
input x = [1 0 1]
failed
-------------------------
dtype = <class 'numpy.uint8'>
input x = [1 0 1]
failed
-------------------------
dtype = <class 'numpy.uint32'>
input x = [1 0 1]
(fort) x = T F T
(fort) sizeof(x(1)) = 4
(fort) resetting x(:) to true
output x = [1 1 1]
-------------------------
dtype = <class 'numpy.uint64'>
input x = [1 0 1]
failed
-------------------------
dtype = int8
input x = [1 0 1]
failed
-------------------------
dtype = int8
input x = [1 0 1]
failed
-------------------------
dtype = int32
input x = [1 0 1]
(fort) x = T F T
(fort) sizeof(x(1)) = 4
(fort) resetting x(:) to true
output x = [1 1 1]
結果與logical(c_bool)
(通過ISO_C_BINDING):
-------------------------
dtype = <class 'bool'>
input x = [ True False True]
failed
-------------------------
dtype = <class 'numpy.bool_'>
input x = [ True False True]
failed
-------------------------
dtype = <class 'int'>
input x = [1 0 1]
failed
-------------------------
dtype = <class 'numpy.int8'>
input x = [1 0 1]
failed
-------------------------
dtype = <class 'numpy.int32'>
input x = [1 0 1]
(fort) x = T F F
(fort) sizeof(x(1)) = 1
(fort) resetting x(:) to true
output x = [65793 0 1]
-------------------------
dtype = <class 'numpy.int64'>
input x = [1 0 1]
failed
-------------------------
dtype = <class 'numpy.uint64'>
input x = [1 0 1]
failed
-------------------------
dtype = <class 'numpy.uint8'>
input x = [1 0 1]
failed
-------------------------
dtype = <class 'numpy.uint32'>
input x = [1 0 1]
(fort) x = T F F
(fort) sizeof(x(1)) = 1
(fort) resetting x(:) to true
output x = [65793 0 1]
-------------------------
dtype = <class 'numpy.uint64'>
input x = [1 0 1]
failed
-------------------------
dtype = int8
input x = [1 0 1]
failed
-------------------------
dtype = int8
input x = [1 0 1]
failed
-------------------------
dtype = int32
input x = [1 0 1]
(fort) x = T F F
(fort) sizeof(x(1)) = 1
(fort) resetting x(:) to true
output x = [65793 0 1]
出於某種原因,這最後logical(c_bool)
不符合上述使用工作...(f2py似乎認爲logical(c_bool)
爲4個字節,而gfortran對待它作爲1個字節,所以有些不一致......)
[This fortran 95 guide](http://northstar-www.dartmouth.edu/doc/solaris-forte/manuals/fortran/user_guide/C_f95.html)說邏輯* 1是一個字節的邏輯類型。使用'邏輯'給出相同的信息。 –
那麼,這個人不是一個標準的文件。 francescalus是對的,'*'語法只是字符類型的標準。但可能它不會改變太多。 –