Search code examples
pythonscipyctypesscipy-optimize-minimize

ctypes array is not callable


I want to use the scipy.optimize.minimize function. The function contains commands from a DLL which require a ctypes array. The goal is to vary the inputs in the ctypes array to optimize a specific output which is also a ctypes array (see code below).

import os
import ctypes
import tkinter as tk
from PIL import ImageTk
from tkinter import filedialog
import numpy as np
from scipy.optimize import minimize

dll = ctypes.cdll.LoadLibrary(library)

LoadModelDef = dll.addModelDef(model)

nrExperiments = 1
nrin = dll.getNumInputs(LoadModelDef)

PDBL2ARR = ctypes.c_double * nrin * nrExperiments
inputs = PDBL2ARR()
inputs_init = PDBL2ARR()


def evaluaterel(library,Model,InputArray):
    nrExp = len(InputArray)
    DBL2ARR = ctypes.c_double * nrExp
    outputs = DBL2ARR()
    for i in range(2,13):
        Name= outputName(Model,i)
        library.evalVBA(Model,InputArray,nrExp,i,outputs)
        for i in range(nrExp):
            Value = str(outputs[i])
#        text = label.cget("text") + '\n' + str(Name)+ ' ' + str(Value)
#        label.configure(text=text)
    return outputs

data = np.array([line.split()[-1] for line in open("DATA.txt")], dtype=np.float64)
for i in range(nrExperiments):
    for j in range(nrin):
        inputs_init[i][j]= 0

for i in range(nrExperiments):
    for j in range(0,nrin):
        inputs[i][j]=data[j]

solution=minimize(evaluaterel(dll,LoadModelDef,inputs),inputs_init,method='SLSQP')
print(solution)

  File "c:\app\python27\lib\site-packages\scipy\optimize\optimize.py", line 292, in function_wrapper
    return function(*(wrapper_args + args))

TypeError: 'c_double_Array_1' object is not callable

Solution

  • According to [SciPy.Docs]: scipy.optimize.minimize(fun, x0, args=(), method=None, jac=None, hess=None, hessp=None, bounds=None, constraints=(), tol=None, callback=None, options=None), the 1st argument should be a callable (function, in your case).
    But, you're calling the function yourself when passing it, and therefore you're passing the function return value.

    Modify your code (faulty line) to:

    solution = minimize(evaluaterel, inputs_init, args=(dll, LoadModelDef, inputs), method="SLSQP")