我不知道如何从 optimization.minimize 函数中发送一个数组

I cant figure out how to send an array out of the optimization.minimize function

我正在构建一个用于科学计算的 Python 应用程序。 该应用程序是一个模型预测控制器 (MPC),我使用 scipy.optimize.minimize 函数作为优化算法。

solution_guess = minimize(objectiveFunction,
                                  U_guess,
                                  arg_guess,
                                  callback= None,
                                  method = "SLSQP")

其中 objective 函数是一个自制函数,其中执行了我的系统模拟。 它看起来像这样:

def objectiveFunction(x,*arg):
    U_test = x
    dt_test = arg[0]
    setpoint_test = arg[1]
    pred_horizion_length_test = arg[2]
    initStateValue_test = arg[3]
    # Defining Model Arrays
    NS_pred_horizion_test = int(pred_horizion_length_test/dt_test)+1
    pred_horizion_array_test = np.linspace(0, pred_horizion_length_test, NS_pred_horizion_test)
    SP_array_test = np.zeros(NS_pred_horizion_test) + setpoint_test
    Y_array_test = SP_array_test * 0

    # Defining parameters for the testing model
    timeDelay_test = 50
    initDelayValue_test = 0
    K_test = 4
    Tc1_test = 30
    Tc2_test = 60

    # Defining Model Object
    obj_model_test = model.secDegModel(dt = dt_test,
                                      K = K_test,
                                      Tc1 = Tc1_test,
                                      Tc2 = Tc2_test,
                                      timeDelay = timeDelay_test,
                                      initStateValue = initStateValue_test,
                                      initDelayValue = initDelayValue_test
                                      )


    ###########################################
    #|||||||||||||||||||||||||||||||||||||||||#
    #     Testing Values for U on Model       #
    #|||||||||||||||||||||||||||||||||||||||||#
    ###########################################


    # Running simulation of "real" model function
    for k in range(NS_pred_horizion_test):
        Y_array_test[k] = obj_model_test.run(u_k = U_test) 

    error = np.sum(abs(SP_array_test-Y_array_test))
    return error

我苦苦挣扎的是如何取回 Y_array_test 数组,这样我就可以在每次优化完成时绘制它。我尝试使用全局变量,但我没有让它工作,我也不认为它是使用全局变量的良好编码方式。有谁知道解决我的问题的好方法吗?也许使用回调函数? (如果回调是要走的路,我不完全理解这个方法是如何工作的或者如何以一种好的方式实现它)

你为什么不做下面的事情呢?

修改你的objectiveFunction如下

from numpy import savez

def objectiveFunction(x,*arg):
.
.
.
.
.

# Running simulation of "real" model function
for k in range(NS_pred_horizion_test):
    Y_array_test[k] = obj_model_test.run(u_k = U_test) 
# Just save Y_array_test in a file
# Add some call_no if you don't want to overwrite
# then filename would be 'Y_array_test_' + str(call_no) 
# You could increment this call_no, every time by 
# call_no = call_no + 1
savez(file_name, Y_array_test)
# Then you could plot it outside using matplotlib
error = np.sum(abs(SP_array_test-Y_array_test))
return error

根据您对 and reusing some code from (This itself is written by modifying @Scott (Scott Sievert) answer and using his drawnow Github package)

的评论

小鬼备注:

I didn't install drawnow Github package . Instead I just copied drawnow.py into my folder. (This is because I didn't find any way to install it via conda. I didn't wan't to use PyPi)

修改你的代码如下

from numpy.random import random_sample
from numpy import arange, zeros

from drawnow import drawnow
from matplotlib import use
from matplotlib.pyplot import figure, axes, ion
from matplotlib import rcParams
from matplotlib.pyplot import style
from matplotlib.pyplot import cla, close
use("TkAgg")
pgf_with_rc_fonts = {"pgf.texsystem": "pdflatex"}
rcParams.update(pgf_with_rc_fonts)
style.use('seaborn-whitegrid')

scott_fig = figure()  # call here instead!
ion()
# figure()  # call here instead!
# ion()    # enable interactivity



solution_guess = minimize(objectiveFunction,
                          U_guess,
                          arg_guess,
                          callback= None,
                          method = "SLSQP")





def objectiveFunction(x,*arg):
    .
    .
    .
    .
    .
    def draw_fig():
        # can be arbitrarily complex; just to draw a figure
        # figure() # don't call!
        scott_ax = axes()
        scott_ax.plot(x, y, '-g', label='label')
        # Need to add some pause element here
        # otherwise you won't be able to see the figure as  
        # it will change too fast
        # cla()
        # close(scott_fig)
        # show() # don't call!

    # Running simulation of "real" model function
    for k in range(NS_pred_horizion_test):
        Y_array_test[k] = obj_model_test.run(u_k = U_test)

    # Just plot Y_array_test now that you have updated it


    drawnow(draw_fig)
    # Then you could plot it outside using matplotlib
    error = np.sum(abs(SP_array_test-Y_array_test))
    return error