I have successfully wrapped some C code using ctypes and brought into Python. I am trying to use Scipy to do optimization on it using the direct method and I am getting this error: TypeError: this function takes at least 2 arguments (1 given). Below is my code and the print statments and errors that I am getting:
in file ctype_tutorial.py:
import ctypes
from ctypes import *
import numpy as np
from numpy import ctypeslib
from scipy.optimize import minimize
from scipy.optimize import direct, Bounds, basinhopping
clibrary = ctypes.CDLL(r"C:\Users\mhaja\OneDrive\Desktop\Github\Honours\ctypes\clibrary.so")
styblinski_tang = clibrary.styblinski_tang
styblinski_tang.argtypes = [ctypes.c_int, ctypes.c_int]
styblinski_tang.restype = ctypes.c_int
print(styblinski_tang(1, 1))
result = direct(styblinski_tang, [[-4,4], [-4,4]])
print(result.x, result.fun, result.nfev)
in clibrary.c file:
#include <stdio.h>
#include <math.h>
int styblinski_tang(int x, int y){
return 0.5 * (pow(x, 4) - 16*pow(x, 2) + 5*x + pow(y, 4) - 16*pow(y, 2) + 5*y);
}
Error that I am getting:
-10
Traceback (most recent call last):
File "c:\Users\mhaja\OneDrive\Desktop\Github\Honours\ctypes\ctypes_tutorial.py", line 44, in <module>
result = direct(styblinski_tang, [[-4,4], [-4,4]])
File "C:\Users\mhaja\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\scipy\optimize\_direct_py.py", line 256, in direct
x, fun, ret_code, nfev, nit = _direct(
File "C:\Users\mhaja\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\scipy\optimize\_direct_py.py", line 249, in _func_wrap
f = func(x)
TypeError: this function takes at least 2 arguments (1 given)
I can see that I am successfully wrapping the function cause when I try the input of 1,1 on the function I get the correct output of -10 but when I try to use Scipy on it, i get the error. I think it might be due to the ctypes and how it converts between C and python. Any help will be appreciated with either Ctypes or Scipy. I am doing this for my honours so please help.
update: It was suggested to me to add a wrapper method so I did and this is the updated code:
import ctypes
from ctypes import *
import numpy as np
from numpy import ctypeslib
from scipy.optimize import minimize
from scipy.optimize import direct, Bounds, basinhopping
clibrary = ctypes.CDLL(r"C:\Users\mhaja\OneDrive\Desktop\Github\Honours\ctypes\clibrary.so")
styblinski_tang = clibrary.styblinski_tang
styblinski_tang.argtypes = [ctypes.c_int, ctypes.c_int]
styblinski_tang.restype = ctypes.c_int
print(styblinski_tang(1, 1))
# Using a wrapper function
def foo(xy):
x,y = xy
return styblinski_tang(x, y)
print(foo([1,1]))
result = direct(foo, [[-4,4], [-4,4]])
print(result.x, result.fun, result.nfev)
This helped a bit but I am still getting this error message:
-10
-10
Traceback (most recent call last):
File "c:\Users\mhaja\OneDrive\Desktop\Github\Honours\ctypes\ctypes_tutorial.py", line 51, in <module>
result = direct(foo, [[-4,4], [-4,4]])
File "C:\Users\mhaja\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\scipy\optimize\_direct_py.py", line 256, in direct
x, fun, ret_code, nfev, nit = _direct(
File "C:\Users\mhaja\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\scipy\optimize\_direct_py.py", line 249, in _func_wrap
f = func(x)
File "c:\Users\mhaja\OneDrive\Desktop\Github\Honours\ctypes\ctypes_tutorial.py", line 47, in foo
return styblinski_tang(x, y)
ctypes.ArgumentError: argument 1: TypeError: wrong type
Try a wrapper function
def foo(xy):
x,y = xy
# or x=xy[0]; y=xy[1]
return styblinski_tang(x, y)