如何使用matlab引擎API从python中调用matlab函数文件?

问题描述 投票:1回答:1

我有一个名为'calculate_K_matrix.m'的matlab函数文件,其中包含以下代码:

function K = calculate_K_matrix(A, B, n)

K = place(A, B, eigs(A)*n)

end

我可以像这样从matlab调用它:

addpath('/home/ash/Dropbox/SimulationNotebooks/Control')

A = [0 1 ;-100 -5]
B = [0 ; 7]


n = 1.1 % how aggressive feedback is

K = calculate_K_matrix(A, B, n)

但是当我尝试使用matlab引擎API从python中调用它时,如下所示:

import matlab                                                                                                       
import matlab.engine                                                                                                

eng = matlab.engine.start_matlab()                                                                                  

A = matlab.double([[0, 1],[-100, -5]])                                                                              
B = matlab.double([[0],[7]])                                                                                        
n = 1.1                  double(param initializer=None, param size=None, param is_complex=False)                    
n_matlab = matlab.double([n])                                                                                       

eng.addpath(r'/home/ash/Dropbox/SimulationNotebooks/Control')                                                       
K = eng.calculate_K_matrix(A, B, n_matlab) 

然后我收到以下错误:

In [17]: run test.py
Attempt to execute SCRIPT calculate_K_matrix as a function:
/home/ash/Dropbox/SimulationNotebooks/Control/calculate_K_matrix.m

---------------------------------------------------------------------------
MatlabExecutionError                      Traceback (most recent call last)
/home/ash/Dropbox/SimulationNotebooks/Control/test.py in <module>()
     10 
     11 eng.addpath(r'/home/ash/Dropbox/SimulationNotebooks/Control')
---> 12 K = eng.calculate_K_matrix(A, B, n_matlab)

/home/ash/anaconda2/envs/python3/lib/python3.5/site-packages/matlab/engine/matlabengine.py in __call__(self, *args, **kwargs)
     76         else:
     77             return FutureResult(self._engine(), future, nargs, _stdout,
---> 78                                 _stderr, feval=True).result()
     79 
     80     def __validate_engine(self):

/home/ash/anaconda2/envs/python3/lib/python3.5/site-packages/matlab/engine/futureresult.py in result(self, timeout)
     66                 raise TypeError(pythonengine.getMessage('TimeoutCannotBeNegative'))
     67 
---> 68         return self.__future.result(timeout)
     69 
     70     def cancel(self):

/home/ash/anaconda2/envs/python3/lib/python3.5/site-packages/matlab/engine/fevalfuture.py in result(self, timeout)
     80                 raise TimeoutError(pythonengine.getMessage('MatlabFunctionTimeout'))
     81 
---> 82             self._result = pythonengine.getFEvalResult(self._future,self._nargout, None, out=self._out, err=self._err)
     83             self._retrieved = True
     84             return self._result

MatlabExecutionError: Attempt to execute SCRIPT calculate_K_matrix as a function:
/home/ash/Dropbox/SimulationNotebooks/Control/calculate_K_matrix.m

我该如何解决这个问题?

python matlab matlab-engine
1个回答
1
投票

使用getattr,如:

   import matlab.engine
    engine = matlab.engine.start_matlab()
    engine.cd('<your path>')
    getattr(engine, 'calculate_K_matrix')(A, B, n, nargout=0)

多数民众赞成我怎么做:

import matlab.engine, sys, cmd, logging


class MatlabShell(cmd.Cmd):
    prompt = '>>> '
    file = None

    def __init__(self, engine = None, completekey='tab', stdin=None, stdout=None):
        if stdin is not None:
            self.stdin = stdin
        else:
            self.stdin = sys.stdin
        if stdout is not None:
            self.stdout = stdout
        else:
            self.stdout = sys.stdout
            self.cmdqueue = []
            self.completekey = completekey

        if engine == None:
            try:
                print('Matlab Shell v.1.0')
                print('Starting matlab...')
                self.engine = matlab.engine.start_matlab()
                print('\n')
            except:
                logging.exception('>>> STARTUP FAILED')
                input()
        else:
            self.engine = engine

        self.cmdloop()

    def do_run(self, line):
        try:
            getattr(self.engine, line)(nargout=0)
        except matlab.engine.MatlabExecutionError:
            pass

    def default(self, line):
        try:
            getattr(self.engine, 'eval')(line, nargout=0)
        except matlab.engine.MatlabExecutionError:
            pass


if __name__ == "__main__":
    MatlabShell()

图片:Result function

© www.soinside.com 2019 - 2024. All rights reserved.