zoukankan      html  css  js  c++  java
  • Python的扩展接口[3] -> Matlab引擎 -> 使用 Python 调用 Matlab 程序

    Python - Matlab


    目录

    1. Python-Matlab 引擎
    2. Python-Matlab 数组
    3. Python-Matlab 基本操作
    4. Python-Matlab 调用 m 文件

    Matlab的官方文档中介绍了Matlab与其余编程语言之间的引擎接口,其中包括对于Python开放的引擎API,可参考官方教程,其中包括引擎安装,基本使用,以及Python与Matlab之间的数据类型转换及交互。

    除了使用官网的Matlab引擎来驱动Matlab外,还可以使用第三方包mlab来进行连接或直接使用win32comdispatch来进行控制,但目前mlab仅支持Python 2的版本。

    1 Python-Matlab引擎 / Pyhton-Matlab Engine

    首先,需要确保Matlab及Python的配置和安装,利用Matlab提供的setup.py文件安装Python的引擎包,安装步骤及过程如下,

    1. 确保安装可用的Python和Matlab,且两者版本对应,如32位的Matlab需对应32位的Python,同时还需查看Matlab支持的Python版本(目前2015a版支持的Python版本为2.7/3.3/3.4);

    2. 添加Python目录到环境变量(如果未添加);

    3. 获取Matlab文件夹目录,可通过Matlab命令行窗口输入matlabroot命令返回;

    4. 安装引擎,Windows利用下面的命令(此处路径可能需要修改)进行安装,此处可能需要管理员权限运行。

    1 cd C:Program FilesMATLABR2015aexternenginespython  
    2 python setup.py install  
    3 pause  

    2 Python-Matlab数组 / Pyhton-Matlab Array

    在Python中,如果需要创建一个Matlab的数组,也可以通过Matlab引擎API来完成,主要数据类型如下图显示。

    下面介绍数组的基本使用,其基本使用方法与numpy类似,但是reshape()函数略有不同,

     1 import matlab.engine
     2 
     3 # Basic usage
     4 int_8 = matlab.int8([1, 2, 3, 4, 5, 6])
     5 print(int_8)    # [[1, 2, 3, 4, 5, 6]]
     6 print(int_8.size)   # (1, 6)
     7 int_8.reshape((2, 3))   # reshape function is different from numpy
     8 print(int_8)    # [[1, 3, 5], [2, 4, 6]]
     9 
    10 double = matlab.double([[1, 2, 3], [4, 5, 6]])
    11 print(double)   # [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]
    12 print(double[0])    # [1.0, 2.0, 3.0]
    13 print(double[1][2]) # 6.0

    对于数组的切片,Matlab的array与Python的list也有所不同,官网给出的解释在于,Matlab数组切片返回的是一个视图,而不是像Python中返回一个浅拷贝。

    1 # Slice array
    2 py = [[1, 2, 3], [4, 5, 6]]
    3 mt = matlab.int32([[1, 2, 3], [4, 5, 6]])
    4 py[0] = py[0][::-1]
    5 mt[0] = mt[0][::-1]
    6 # Slicing a Matlab array returns a view instead of a shallow copy
    7 print(py)   # [[3, 2, 1], [4, 5, 6]]
    8 print(mt)   # [[3, 2, 3], [4, 5, 6]]

    3 Python-Matlab基本操作 / Pyhton-Matlab Basic Operation

    Python还可以通过引擎完成对Matlab的一些基本操作与控制。

    完整代码

     1 import matlab.engine
     2 
     3 eng = matlab.engine.start_matlab()
     4 
     5 print(eng.sqrt(4.))     # 2.0
     6 eng.plot(matlab.int32([1, 2, 3, 4]), matlab.int32([1, 2, 3, 4]))
     7 
     8 eng.eval("hold on", nargout=0)
     9 eng.eval("plot([4, 3, 2, 1], [1, 2, 3, 4])", nargout=0)
    10 
    11 eng.eval("x = 3", nargout=0)
    12 eng.eval("y = 41", nargout=0)
    13 eng.eval("z = [213, 123]", nargout=0)
    14 print(eng.workspace)
    15 print(eng.workspace['x'], eng.workspace['z'])
    16 """
    17   Name      Size            Bytes  Class     Attributes
    18 
    19   x         1x1                 8  double
    20   y         1x1                 8  double
    21   z         1x2                16  double
    22 
    23 3.0 [[213.0,123.0]]
    24 """
    25 
    26 input("Press Enter to exit.")
    27 eng.quit()
    View Code

    分段解释

    1 import matlab.engine
    2 
    3 eng = matlab.engine.start_matlab()

    首先导入需要的包并生成实例,此处调用sqrt()函数计算,得到结果,还可以利用引擎实例调用plot函数进行画图,但需要注意的是,传入的参数需要是Matlab类型参数。

    1 print(eng.sqrt(4.))     # 2.0
    2 eng.plot(matlab.int32([1, 2, 3, 4]), matlab.int32([1, 2, 3, 4]))

    当我们需要执行某些Matlab命令时,可以利用eval函数对其进行输入,下面的方法画出了另外一条直线,其中nargout参数为设置输出返回参数的数量,默认为1。无参数返回时需要设置为0。

     1 eng.eval("hold on", nargout=0)
     2 eng.eval("plot([4, 3, 2, 1], [1, 2, 3, 4])", nargout=0)
     3 
     4 eng.eval("x = 3", nargout=0)
     5 eng.eval("y = 41", nargout=0)
     6 eng.eval("z = [213, 123]", nargout=0)
     7 print(eng.workspace)
     8 print(eng.workspace['x'], eng.workspace['z'])
     9 """
    10   Name      Size            Bytes  Class     Attributes
    11 
    12   x         1x1                 8  double
    13   y         1x1                 8  double
    14   z         1x2                16  double
    15 
    16 3.0 [[213.0,123.0]]
    17 """
    18 
    19 input("Press Enter to exit.")
    20 eng.quit()

    4 Python-Matlab调用m文件 / Pyhton-Matlab Call m File

    下面介绍如何使用Python调用m来进行计算并获得返回结果,首先定义以下的m文件,在被调用的m文件中再调用下一个m文件,使用的m文件如下,

    定义入口函数callentry,接收两个参数,随后对两个参数分别在内部进行加和乘操作,再调用外部另一个m文件的callsub函数进行相减操作,将返回的结果保存在数组r中返回。

    callentry.m 代码

    function [x, y, z] = callentry(a, b);
    x = add(a, b)
    y = mul(a, b)
    z = callsub(a, b)
    end
    
    function l = mul(m, n);
    l=m*n;
    end
    
    function l = add(m, n);
    l=m+n;
    end

    callsub.m 代码

    function r = callsub(a, b);
    r = a-b;
    end

    在Python中,运行如下代码,

    1 import matlab.engine
    2 
    3 eng = matlab.engine.start_matlab()
    4 print(eng.callentry(7.7, 2.1, nargout=3))
    5 eng.quit()

    Note: 值得注意的是,此处需要设置nargout参数,当未设置时默认为1,即默认只返回1个参数,当知道Matlab返回参数的数量时,通过nargout进行设置来获取所有需要的参数。无参数返回时请设为0

    在第一次运行生成实例时会较慢,因为需要启动Matlab引擎,最终得到输出如下,可以看到,Matlab的console界面显示的结果在Python中也会输出,最后得到的结果是列表形式的Python数据。

    x =  
        9.8000  
      
    y =  
       16.1700  
      
    z =  
        5.6000  
      
    r =  
        9.8000   16.1700    5.6000  
      
    (9.8, 16.17, 5.6)  
  • 相关阅读:
    【题解】NOI2014购票
    【题解】HEOI2013Eden 的新背包问题
    【题解】ZJOI2013蚂蚁寻路
    【题解】POI2014FAR-FarmCraft
    【题解】NOI2015寿司晚宴
    【题解】HNOI2018寻宝游戏
    省选算法学习-数据结构-虚树
    [HDU3516] Tree Construction [四边形不等式dp]
    [HDU3480] Division [四边形不等式dp]
    [POJ1160] Post Office [四边形不等式dp]
  • 原文地址:https://www.cnblogs.com/stacklike/p/8279277.html
Copyright © 2011-2022 走看看