簡體   English   中英

使用f2py將numpy字符串格式數組傳遞給fortran

[英]Passing numpy string-format arrays to fortran using f2py

我的目標是從fortran中的python numpy數組中打印第二個字符串,但是我只打印了第一個字符,並且它也不一定是正確的字符串。

任何人都可以告訴我將完整的字符串數組傳遞給fortran的正確方法是什么?

代碼如下:

testpy.py

import numpy as np
import testa4

strvar = np.asarray(['aa','bb','cc'], dtype = np.dtype('a2'))
testa4.testa4(strvar)

testa4.f90

subroutine testa4(strvar)
implicit none

character(len=2), intent(in) :: strvar(3)
!character*2 does not work here - why?

print *, strvar(2)

end subroutine testa4

編譯

f2py -c -m testa4 testa4.f90

輸出上述代碼

c

期望的輸出

bb

我不知道如何使用f2py做到這f2py 但它可以用ctypes完成。 你得到一個字符數組,但你可以很容易地將它轉換為字符串。

subroutine testa4(strvar) bind(C, name='testa4')
  use iso_c_binding
  implicit none

  character(len=1,kind=c_char), intent(in) :: strvar(2,3)

  print *, strvar(:,2)

end subroutine testa4

編譯: gfortran -shared -fPIC testa4.f90 -o testa4.so

import numpy as np
import ctypes

testa4 = ctypes.CDLL("./testa4.so")

strvar = np.asarray(['aa','bb','cc'], dtype = np.dtype('a2'))
strvar_p = ctypes.c_void_p(strvar.ctypes.data)

testa4.testa4(strvar_p)

跑:

> python testpy.f90 
 bb

根據文檔 ,f2py喜歡使用dtype ='c'傳遞的字符串數組(即'| S1')。 這會讓你成為那里的一部分,雖然在幕后有一些奇怪的陣列形狀(例如,在我的很多測試中,我發現fortran會保留2個字符的長度,但是將6個字符解釋為指示一個2x6陣列,所以我會在輸出中得到隨機存儲器)。 這(據我所知),要求您將Fortran數組視為2D字符數組(而不是1D“字符串”數組)。 不幸的是,我無法讓它采取假定的形狀,並最終將字符串的數量作為參數傳遞。

我很確定我錯過了一些相當明顯的東西,但這應該暫時有效。 至於為什么CHARACTER * 2不起作用......我真的不知道。

MODULE char_test

CONTAINS

SUBROUTINE print_strings(strings, n_strs)
    IMPLICIT NONE

    ! Inputs
    INTEGER, INTENT(IN) :: n_strs
    CHARACTER, INTENT(IN), DIMENSION(2,n_strs) :: strings

!f2py INTEGER, INTENT(IN) :: n_strs
!f2py CHARACTER, INTENT(IN), DIMENSION(2,n_strs) :: strings

    ! Misc.
    INTEGER*4 :: j


    DO j=1, n_strs
        WRITE(*,*) strings(:,j)
    END DO

END SUBROUTINE print_strings

END MODULE char_test

----------------

import numpy as np
import char_test as ct

strings = np.array(['aa', 'bb', 'cc'], dtype='c').T
ct.char_test.print_strings(strings, strings.shape[1])

strings = np.array(['ab', 'cd', 'ef'], dtype='c').T
ct.char_test.print_strings(strings, strings.shape[1]) 

-->python run_char_test.py
 aa
 bb
 cc
 ab
 cd
 ef

不是一個答案,但是評論太久了:也許這有助於......

在你的第一種情況下,傳遞給fortran的是由於某種原因每個字符串的第一個字符:

'abc'

在fortran中,在長度為2的數組中最終為'ab','c'。 如果你嚴格地使用長度一個字符串陣列一切都很好,我想。 不幸的是你不能偽造系統並在python中分成單個字符數組['a','a','b','b'.. - 如果數組長度不匹配則拋出錯誤。

關於你的第二個問題,如果你宣布

  character*2

它實際上只是傳遞一個常規的python字符串列表:

  testa4.testa4(['aa','bb','cc'])

(如果你嘗試numpy字符串數組,現在會拋出一個錯誤。)。 字符串必須是正確的正確長度,否則它也會引發錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM