현재 Ctypes를 사용하여 SciPy를 사용하여 최적화하려는 Fortran 함수가 있습니다. 이것이 가능한가? 아마도 구현에서 잘못된 점을 발견했을 것입니다. 예를 들어, 가정 내가 가진 :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))
1 ex 국부 최소값 f2 (pi/2, pi) = -1을 구한다. cost.sin_2_cos 반환 값을 사용하여 f2를 호출하면 "minimimum"이 (1,1)의 초기 추측에서 제공됩니다. "파이썬"반환 값을 사용하여 f2를 호출하면 optimize가 올바른 최소값을 찾습니다.
차원 (2) 배열 입력을 가져 오기 위해 sin_2_cos를 재정의하려고 시도했지만 비슷한 동작이 나타납니다. 아마 내가 minim_2로 직접 sin_2_cos를 호출 할 필요가있다. (그렇다면 인수에 대해 어떻게 c_float를 지정 하겠는가?) 어떤 생각이라도 감사드립니다!
편집 : 아래 주석에 두 개의 주석이 달린 print(f2(...))
줄이 예상 값을 생성합니다. 따라서 Fortran 함수가 Python f2 함수를 통해 제대로 호출되고 있다고 생각합니다.
인수에 'value'속성을 추가해야합니다 (다른 문제가있을 수 있음). http://www.fortran90.org/src/best-practices를 참조하십시오.html # using-ctypes –
왜해야합니까? f2에 대한 호출의 주석을 제거하면 제대로 작동합니다. 여러분이 열거 한 웹 페이지는 'value'가 왜 존재하는지 명확하게하지 않으며 이전의'iso_c_binding' 예제에서 사용하지도 않습니다. 값을 추가한다고해서 문제가 해결되지는 않습니다. –
제목을 좀 더 구체적으로 변경했습니다. 나는 "그렇습니다."라고 가정합니다. 너에게 받아 들일 수있는 대답은 아니 겠지. –