我正在尝试从Matlab调用一个自定义函数,该函数引用以前在Python中定义的变量。
事件的顺序如下:
在Python中定义变量,包括一个函数(fminconMaster_py),该函数使用2个以'x'作为参数的匿名函数(fun_py,obj_py)
调用使用fmincon算法解决优化问题的Matlab函数(optim_mat)-该优化问题具有在Matlab中定义的2个匿名函数(fun_mat,obj_mat)(目标和约束)
每当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中构建的复杂函数
关于如何解决此问题的任何想法?
答案 0 :(得分:0)
将它们传递给函数。
你不能用魔术来做到这一点; Python不与MATLAB的任何部分共享名称空间-实际上,Python名称空间是特定于模块的。您必须将它们传递进来,以使它们从一种语言的表示形式转换为另一种语言的表示形式。
您可以 做的是定义一个将变量加载到Python模块的全局命名空间中的函数。像这样:
def load_globals_py(d):
globals().update(d)
此函数将使用一个字典,其中的键是变量名,并将其添加到模块的全局名称空间中。您可以在运行其他函数之前从MATLAB调用此函数。