使用 python subprocess.Popen 调用 matlab 函数
Calling a matlab function with python subprocess.Popen
我有一个 python 代码,它在后台运行一个 matlab 函数 sussum(a,nx,ny) subprocess.Popen。我无法让它工作。因为我无法将输入参数正确传递给 matlab。这是 python 代码:
#!/usr/bin/env python
import matlab.engine
import scipy.io as sio
import numpy as np
import subprocess as sb
nproc = 5
input = sio.loadmat('sus_py.mat')
totq = input['totq']
nx,ny = input['nx'],input['ny']
nq = totq+1
nx,ny = matlab.int32(nx.tolist()) , matlab.int32(ny.tolist())
iq = range(1,nq)
gp = len(iq)/nproc
list = [iq[j:j+nproc] for j in range(0,len(iq),nproc)]
for g in range(0,len(list)):
i = len(list[g])
p = []
for n in range(0,i):
a = matlab.int32(list[g][n])
fun = '-r "sussum(a,nx,ny); exit" '
lmb = ['/usr/local/bin/matlab','-nodesktop','-nosplash','-nodisplay','-nojvm',fun]
p.append(sb.Popen(lmb))
for q in p:
q.wait()
python脚本在集群网络的命令终端中执行,直到吐出错误信息:Undefined function or variable 'a'.
我确信 matlab 函数 sussum(a,nx,ny) 工作正常,因为我已经使用 Python-Matlab API 作为 matlab.engine.start_matlab().sussum 对其进行了测试(a,nx,ny) 并给出了所需的输出。在获取 python 代码 运行 subprocess.Popen() 方面的任何帮助将不胜感激。
当您使用 subprocess.Popen(args)
创建一个 Popen
对象时,您实际上是在使用它来将 lmb
列表的内容(用空格连接)传递给 shell 被执行。在这种情况下,您的命令等效于:
/usr/local/bin/matlab -nodesktop -nosplah -nodisplay -nojvm -r "sussum(a,nx,ny); exit"
显然,如果您直接从 shell 运行 它会导致错误,因为通过此命令创建的 MATLAB 实例不知道 a
、nx
和 ny
是变量,在这种情况下,shell 只是将整个字符串作为参数传递给 -r
参数。如果您是 运行 从命令行执行此操作,则需要将这些符号替换为在传递给 MATLAB 时有意义的值。您可以通过在命令本身中手动编写变量,或者对您正在使用的 shell 使用适当的变量扩展方法来做到这一点。
如果您尝试 运行 通过 Python Popen
对象,您需要将变量替换为实际的 fun
字符串。如果你在 Python 中 严格地 这样做,你可以做类似
# define variables
a = 10
nx = [1, 2, 3, 4]
ny = [10, 20, 30, 40]
# build fun string from above variables
# -r "sussum(10, [1,2,3,4], [10,20,30,40]); exit;
fun = '-r "sussum({}, [{}], [{}]); exit";'.format(a, ','.join(nx), ','.join(ny))
不幸的是,由于您要从 scipy.io.loadmat
给您的 numpy.ndarray
中提取 a
、nx
和 ny
值,您已经从那里提取值并将它们格式化为 sussum
函数可接受的格式。
我有一个 python 代码,它在后台运行一个 matlab 函数 sussum(a,nx,ny) subprocess.Popen。我无法让它工作。因为我无法将输入参数正确传递给 matlab。这是 python 代码:
#!/usr/bin/env python
import matlab.engine
import scipy.io as sio
import numpy as np
import subprocess as sb
nproc = 5
input = sio.loadmat('sus_py.mat')
totq = input['totq']
nx,ny = input['nx'],input['ny']
nq = totq+1
nx,ny = matlab.int32(nx.tolist()) , matlab.int32(ny.tolist())
iq = range(1,nq)
gp = len(iq)/nproc
list = [iq[j:j+nproc] for j in range(0,len(iq),nproc)]
for g in range(0,len(list)):
i = len(list[g])
p = []
for n in range(0,i):
a = matlab.int32(list[g][n])
fun = '-r "sussum(a,nx,ny); exit" '
lmb = ['/usr/local/bin/matlab','-nodesktop','-nosplash','-nodisplay','-nojvm',fun]
p.append(sb.Popen(lmb))
for q in p:
q.wait()
python脚本在集群网络的命令终端中执行,直到吐出错误信息:Undefined function or variable 'a'.
我确信 matlab 函数 sussum(a,nx,ny) 工作正常,因为我已经使用 Python-Matlab API 作为 matlab.engine.start_matlab().sussum 对其进行了测试(a,nx,ny) 并给出了所需的输出。在获取 python 代码 运行 subprocess.Popen() 方面的任何帮助将不胜感激。
当您使用 subprocess.Popen(args)
创建一个 Popen
对象时,您实际上是在使用它来将 lmb
列表的内容(用空格连接)传递给 shell 被执行。在这种情况下,您的命令等效于:
/usr/local/bin/matlab -nodesktop -nosplah -nodisplay -nojvm -r "sussum(a,nx,ny); exit"
显然,如果您直接从 shell 运行 它会导致错误,因为通过此命令创建的 MATLAB 实例不知道 a
、nx
和 ny
是变量,在这种情况下,shell 只是将整个字符串作为参数传递给 -r
参数。如果您是 运行 从命令行执行此操作,则需要将这些符号替换为在传递给 MATLAB 时有意义的值。您可以通过在命令本身中手动编写变量,或者对您正在使用的 shell 使用适当的变量扩展方法来做到这一点。
如果您尝试 运行 通过 Python Popen
对象,您需要将变量替换为实际的 fun
字符串。如果你在 Python 中 严格地 这样做,你可以做类似
# define variables
a = 10
nx = [1, 2, 3, 4]
ny = [10, 20, 30, 40]
# build fun string from above variables
# -r "sussum(10, [1,2,3,4], [10,20,30,40]); exit;
fun = '-r "sussum({}, [{}], [{}]); exit";'.format(a, ','.join(nx), ','.join(ny))
不幸的是,由于您要从 scipy.io.loadmat
给您的 numpy.ndarray
中提取 a
、nx
和 ny
值,您已经从那里提取值并将它们格式化为 sussum
函数可接受的格式。