从Matlab调用Python函数,该函数使用先前在Python环境中定义的全局变量

时间:2018-10-18 15:26:06

标签: python matlab global-variables

我正在尝试从Matlab调用一个自定义函数,该函数引用以前在Python中定义的变量。

事件的顺序如下:

  1. 在Python中定义变量,包括一个函数(fminconMaster_py),该函数使用2个以'x'作为参数的匿名函数(fun_py,obj_py)

  2. 调用使用fmincon算法解决优化问题的Matlab函数(optim_mat)-该优化问题具有在Matlab中定义的2个匿名函数(fun_mat,obj_mat)(目标和约束)

  3. 每当fmincon例程调用Matlab目标和约束匿名函数(fun_mat,obj_mat)时,它们都指向调用fminconMaster_py的matlab函数(fupdate),后者依次引用python匿名函数fun_py和obj_py

问题在于,当发生3时,在Python中定义的fminconMaster_py无法识别fun_py和obj_py(“ Python错误:NameError:未定义名称xxx”)

请参见下面的代码

fminconMaster_py的Python代码(调用fun_py和obj_py)

def fminconMaster_py(x):

    validNonLinearUpperConstraint =  Cu != np.Inf
    validNonLinearLowerConstraint = Cl != -np.Inf

    nonLinearUpperConstraint = Cu[validNonLinearUpperConstraint]
    nonLinearLowerConstraint = Cl[validNonLinearLowerConstraint]

    cUpper = fun_py (x)[validNonLinearUpperConstraint] - nonLinearUpperConstraint
    cLower = nonLinearLowerConstraint - fun_py (x)[validNonLinearLowerConstraint]

    c= np.vstack(cUpper, cLower)   
    obj = obj_py(x)

    return obj, c

fupdate的Matlab代码

pyfunction='pythonModule.fminconMaster_py' 

function [J, cin, gJ, gcin] = fupdate(x)
    eval(['output = py.', pyfunction, '(x);'])  
    ...
end

由于由fminconMaster_py(Cu,Cl,fun_py,obj_py)未定义某些变量,因此fupdate对表达式求值时会发生错误。查看下面粘贴的错误

Python Error: NameError: name 'Cu' is not defined

Error in optimize/obj (line 69)
    [J, cin, gJ, gcin] = fupdate(x);

Error in fmincon (line 546)
  initVals.f = feval(funfcn{3},X,varargin{:});

Error in optimize (line 34)
[xopt, fopt, exitflag, optoutput] = fmincon(@obj, x0, A, b, Aeq, beq, lb, ub, @con, opt);

Caused by:
Failure in initial objective function evaluation. FMINCON cannot continue.

我可以将Cu和Cl作为参数传递,因为它们是数组,但是fun_py和obj_py是我在Python中构建的复杂函数

关于如何解决此问题的任何想法?

1 个答案:

答案 0 :(得分:0)

将它们传递给函数。

你不能用魔术来做到这一点; Python不与MATLAB的任何部分共享名称空间-实际上,Python名称空间是特定于模块的。您必须将它们传递进来,以使它们从一种语言的表示形式转换为另一种语言的表示形式。


您可以 做的是定义一个将变量加载到Python模块的全局命名空间中的函数。像这样:

def load_globals_py(d):
    globals().update(d)

此函数将使用一个字典,其中的键是变量名,并将其添加到模块的全局名称空间中。您可以在运行其他函数之前从MATLAB调用此函数。