我目前有一個Fortran函數,我想用SciPy使用Ctypes對其進行優化。這可能嗎?也許我在執行過程中做了錯誤的事情。例如,假設我有:使用ctypes在Fortran函數上使用scipy.optimize.minimize產生的錯誤結果
cost.f90
module cost_fn
use iso_c_binding, only: c_float
implicit none
contains
function sin_2_cos(x,y) bind(c)
real(c_float) :: x, y, sin_2_cos
sin_2_cos = sin(x)**2 * cos(y)
end function sin_2_cos
end module cost_fn
,我與編譯:
gfortran -fPIC -shared -g -o cost.so cost.f90
,然後嘗試找到一個(本地)最低配:
成本.py
#!/usr/bin/env python
from ctypes import *
import numpy as np
import scipy.optimize as sopt
cost = cdll.LoadLibrary('./cost.so')
cost.sin_2_cos.argtypes = [POINTER(c_float), POINTER(c_float)]
cost.sin_2_cos.restype = c_float
def f2(x):
return cost.sin_2_cos(c_float(x[0]), c_float(x[1]))
# return np.sin(x[0])**2 * np.cos(x[1])
# print(f2([1, 1]))
# print(f2([0.5 * np.pi, np.pi]))
print(sopt.minimize(f2, (1.0, 1.0), options={'disp': True}, tol=1e-8))
我ex將局部最小值f2(pi/2,pi)= -1。當我用cost.sin_2_cos返回值調用f2時,「minimimum」僅在(1,1)的初始猜測中給出。如果我用「Python」返回值調用f2,則優化會找到正確的最小值。
我試過重新定義sin_2_cos來取維(2)數組輸入,但看到了類似的行爲。也許我需要直接調用sin_2_cos來最小化(但是如何爲參數指定c_float)?任何想法都很感激!
編輯:對於下面的註釋,請注意,兩條註釋print(f2(...))
行會產生預期值。因此,我相信通過Python f2函數正在調用Fortran函數。
您必須在參數中至少添加(可能存在其他問題)'value'屬性,請參閱http://www.fortran90.org/src/best-practices。html#using-ctypes –
爲什麼我必須這樣做?如果我取消對f2的呼叫的註釋,它會正常工作。您列出的網頁沒有說清楚爲什麼「價值」在那裏,也沒有在早期的'iso_c_binding'示例中使用它。請注意,增加值不能解決問題。 –
我將標題更改爲更具體的標題。我假設「是的,可以。」對你而言不是一個可以接受的答案。 –