Search code examples
python-3.xscipycomplex-numbersscipy-optimizescipy-optimize-minimize

Scipy optimize.minimize a complex function with 2 real variables and 1 argument


I'm looking to minimize a non linear complex function with 2 variables and 1 constant. I found a question for how to minimize a complex function and i think it work(?) I haven't tried it yet, because i want to firs solve the multiple variable one argument problem.

For example a super simple real function:

def function(param):
    x, y, a = param
    return(x**2 + y**2 + a*x)

I can make a minimization with respect of the 3 parameters, however not with respect to 2 variables 1 constant. If i do

minimize(function, [2,4,5])

it works fine.

I found this question where someone asked to to something similar to me, but the answer doesn't work for me, the answer says to do:

def function(x, y, a):
    return(x**2 + y**2 + a*x)
minimize(function, 2, 4 args=5)

but this gives me errors, even just minimizing with the 3 in this way minimize(function, 2, 4, 5) gives me a lot of lines of errors, and in this way minimize(function, (2,4,5)) is gives >missing 2 required positional arguments: 'y' and 'a'..

Next for the complex thing, in the answer i looked it said to separate the function into 2 real functions, solve them with minimize, then fuse both results into one. But i am not sure i understood so if someone can help me there. The function is a complex function (real and imaginary part) but the inputs (2 variables 1 constant) are real.

Maybe there is a package that does this?


Solution

  • You can do this by separating the arguments that you want to vary during the minimization process from the others. Something like:

    from scipy.optimize import minimize
    
    def function(t, a):
        x, y = t
        return(x**2 + y**2 + a*x)
    
    res = minimize(function, (2, 4), args=5)
    

    If you don't want to change the function signature and internals you can use a wrapper:

    from scipy.optimize import minimize
    
    def function(x, y, a):
        return(x**2 + y**2 + a*x)
    
    def wrapper(f, a):
        def newfunc(t):
            return f(*t, a)
        return newfunc
    
    res = minimize(wrapper(function, 5), (2, 4))