Python調(diào)用Fortran的三種形式
1. 簡(jiǎn)介
在一些研究領(lǐng)域很多經(jīng)典算法和工具都由上古語(yǔ)言Fortran編寫(xiě),而這部分代碼又沒(méi)有對(duì)應(yīng)的C/C++和Python版本。因此,掌握Python語(yǔ)言調(diào)用Fortran程序這一技能,在一些研究領(lǐng)域有助于我們站在巨人的肩上看的更遠(yuǎn)。Python調(diào)用Fortran可以總結(jié)為如下三種:
1)通過(guò) F2PY:F2PY 是 NumPy 團(tuán)隊(duì)開(kāi)發(fā)的一個(gè)工具,可以把 Fortran 程序轉(zhuǎn)換為 Python 模塊,從而在 Python 中調(diào)用 Fortran 程序。
2)通過(guò) ctypes 庫(kù):ctypes 是 Python 內(nèi)置的一個(gè)庫(kù),可以用來(lái)調(diào)用外部 C 動(dòng)態(tài)鏈接庫(kù),因此也可以用于調(diào)用 Fortran 程序。通過(guò) ctypes 可以讓 Python 調(diào)用 Fortran 程序,也可以從 Fortran 中調(diào)用 Python 函數(shù)。
3)利用Python的os包調(diào)用Fortran。
2. Python調(diào)用Fortran的三種方法
2.1 基于 F2PY的f2py調(diào)用Fortran
步驟1:
計(jì)算圓面積的Fortran函數(shù)。接下來(lái)將用下面的函數(shù)進(jìn)行演示。這里的例子是返回一個(gè)參數(shù)的,返回多個(gè)參數(shù)以及修改參數(shù)的Fortran用法。
Fortran77定義變量時(shí)候不用加::
function area_of_circle (r) ! function result implicit none ! dummy arguments real :: area_of_circle ! local variables real :: r real :: pi pi = 4 * atan (1.0) area_of_circle = pi * r**2 end function area_of_circle
或
function area_of_circle (r) result(a) implicit none real :: a real :: r real :: pi pi = 4 * atan (1.0) a = pi * r**2 end
或
subroutine area_of_circle (r,a) implicit none real, intent(out) :: a real, intent(in) :: r real :: pi pi = 4 * atan (1.0) a = pi * r**2 end
步驟2:
新建circle.f90后,在終端中運(yùn)行如下代碼:
python -m numpy.f2py -c circle.f90 -m circle
具體步驟如下圖,然后可以看到生成的circle.cpython-36m-x86_64-linux-gnu.so
步驟3:
在Python中,可以直接import上面的函數(shù)名
import circle print(circle.__doc__) print(circle.area_of_circle(2))
注意上面的__doc __是f2py自動(dòng)生成的,可以看到fortran模塊里面包含幾個(gè)函數(shù),每個(gè)函數(shù)里面還可以再調(diào)用doc看到接口參數(shù)類(lèi)型。
2.2 使用動(dòng)態(tài)鏈接庫(kù)調(diào)用Fortran
步驟1:
修改上面的Fortran代碼,用result返回函數(shù)結(jié)果,指定輸入和返回?cái)?shù)據(jù)類(lèi)型。
function area_of_circle(r) result(area) bind(c, name='area_of_circle') use iso_c_binding implicit none real(c_double) :: area real(c_double), intent(in) :: r real :: pi pi = 4 * atan (1.0) area = pi * r**2 end function area_of_circle
步驟2:
如2.1節(jié) 所示,在系統(tǒng)終端或者Pycharm終端中輸入命令:
gfortran -shared circle2.f90 -o circle2.so
步驟3:
編寫(xiě)Python調(diào)用腳本
import ctypes as ct # import the shared library fortlib = ct.CDLL('./circle2.so') # Specify arguments and result types fortlib.area_of_circle.argtypes = [ct.POINTER(ct.c_double)] fortlib.area_of_circle.restype = ct.c_double # Create a double and pass it to Fotran (by reference) a = ct.c_double(2) b = fortlib.area_of_circle(ct.byref(a)) print(b)
2.3 利用Python的os包調(diào)用Fortran
步驟1:
以2.1節(jié)中的Fortran代碼為例,稍作修改,這種方式需要Fortran代碼是完整的程序可編譯為可執(zhí)行程序。下面代碼包含了主函數(shù),即調(diào)用函數(shù)的函數(shù)主體。
program calling_func real :: a a = area_of_circle(2.0) Print *, "The area of a circle with radius 2.0 is" Print *, a end program calling_func function area_of_circle(r) ! function result implicit none ! dummy arguments real :: area_of_circle ! local variables real :: r real :: pi pi = 4 * atan (1.0) area_of_circle = pi * r**2 end function area_of_circle
步驟2:
編譯和調(diào)用,Windows系統(tǒng)注意修改路徑,以及可執(zhí)行程序名后綴應(yīng)該是exe,Linux可執(zhí)行程序后綴可以是out或者沒(méi)有。
import os #編譯 os.system(r"gfortran ./circle3.f90 -o circle") #調(diào)用編譯的circle程序 os.system('./circle')
上述代碼就是類(lèi)似于Windows中調(diào)用cmd。
3. 總結(jié)
方法1:比較推薦,針對(duì)Python編程,如果返回?cái)?shù)據(jù)類(lèi)型復(fù)雜,也不是太方便;
方法2:過(guò)于繁瑣不推薦;
方法3:是一種需要首先編譯出可執(zhí)行程序然后調(diào)用,交互性不方便。如果將輸入輸出寫(xiě)為固定文件,然后由Python生產(chǎn)輸入文件,由Python讀取輸出文件,也是一種比較好的選擇。
到此這篇關(guān)于Python調(diào)用Fortran的三種形式的文章就介紹到這了,更多相關(guān)Python調(diào)用Fortran內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
PyTorch中torch.utils.data.DataLoader實(shí)例詳解
torch.utils.data.DataLoader主要是對(duì)數(shù)據(jù)進(jìn)行batch的劃分,下面這篇文章主要給大家介紹了關(guān)于PyTorch中torch.utils.data.DataLoader的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09Python網(wǎng)絡(luò)爬蟲(chóng)之爬取微博熱搜
這篇文章主要介紹了Python網(wǎng)絡(luò)爬蟲(chóng)之爬取微博熱搜的相關(guān)知識(shí),非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-04-04python下10個(gè)簡(jiǎn)單實(shí)例代碼
最近學(xué)python比較順手,找到感覺(jué)了,所以,我想把我用來(lái)練習(xí)的實(shí)例題目分享出來(lái),有興趣的朋友可以關(guān)注一下。 文章分為10篇,每篇10題,共100道實(shí)例。后續(xù)如果需要可以增加2017-11-11Python實(shí)現(xiàn)截取PDF文件中的幾頁(yè)代碼實(shí)例
今天小編就為大家分享一篇關(guān)于Python實(shí)現(xiàn)截取PDF文件中的幾頁(yè)代碼實(shí)例,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-03-03python工具——Mimesis的簡(jiǎn)單使用教程
這篇文章主要介紹了python工具——Mimesis的簡(jiǎn)單使用教程,幫助大家更好的理解和使用python,感興趣的朋友可以了解下2021-01-01Python中reduce()函數(shù)的用法詳細(xì)解讀
這篇文章主要介紹了Python中reduce()函數(shù)的用法詳細(xì)解讀,reduce函數(shù)是通過(guò)函數(shù)對(duì)迭代器對(duì)象中的元素進(jìn)行遍歷操作,但需要注意的是?reduce?函數(shù)返回的是計(jì)算的結(jié)果,而?map/filter?返回的是作用后的迭代器對(duì)象,需要的朋友可以參考下2023-08-08如何利用Python實(shí)現(xiàn)簡(jiǎn)單C++程序范圍分析
這篇文章主要介紹了如何利用Python實(shí)現(xiàn)簡(jiǎn)單C++程序范圍分析,文章以舉例說(shuō)明及過(guò)程實(shí)現(xiàn)思路的方式展開(kāi)講解,具有一定的的參考價(jià)值,需要的小伙伴可以參考一下,希望對(duì)你有所幫助2022-02-02