zoukankan      html  css  js  c++  java
  • python调用matlab脚本

    在MATLAB和Python之间建个接口,从Python中调用MATLAB脚本或者是MATLAB的函数。内容不是很难,毕竟现成的接口已经有了,在这儿记录一下API使用的一些事项。

    注:本篇使用的是MATLAB R2017a,windows 10系统。

    相关链接

    https://www.mathworks.com/help/matlab/matlab-engine-for-python.html
    https://www.mathworks.com/help/matlab/matlab_external/get-started-with-matlab-engine-for-python.html

    API的安装

    MATLAB在安装的过程中已经准备好了相关文档。根据教程,首先要找到rootR2017aexternenginespython文件夹。这里的root指的是MATLAB安装的根目录。对于笔者的电脑,我的全路径就是C:Program FilesMATLABR2017aexternenginespython。打开这个文件夹,可以看见下面这几个文件。
    1
    其中setup.py是我们想要用的文件。定位到它之后,我们在command window里面转到这个文件夹,然后执行安装。(启动command window的时候必须是管理员模式,否则可能会报“没有权限”的错误

    cd C:Program FilesMATLABR2017aexternenginespython
    python setup.py install
     

    2
    不出差错的话,到这里安装过程就结束了。如果你使用的是Python的虚拟环境,那么记得在安装前先将虚拟环境启动。

    基本调用

    这个API调用非常简单。在Python中,导入如下两个module就能实现MATLAB的全部控制:

    import matlab
    import matlab.engine

    其中,matlab包含的是一些数据形式,比如int8,int16之类。matlab.engine负责程序的启动。

    engine = matlab.engine.start_matlab() # Start MATLAB process
    engine = matlab.engine.start_matlab("-desktop") # Start MATLAB process with graphic UI

    上面两行代码,第一行指示MATLAB在后端运行;第二行则会启动MATLAB的图形界面窗口。调用任何MATLAB函数都通过engine变量来实现。笔者自己调用了一些声音工具箱中的函数,一点问题都没有。

    >>> engine.sqrt(2.)
    1.4142135623730951

    变量兼容性

    笔者自己尝试的时候遇到很多变量类型不正确这样的提示,因为MATLAB函数对于输入数据的类型有着比较严格的要求,比如log2对于int8类型输入就会报错。double类型是MATLAB里面用得最多的数据型,所以一般可以将python的数据转成MATLAB兼容的double类型来解决问题。举个例子,Python的list类型变量只需加上matlab.double就可以完成转换。

    >>> engine.sqrt([1.,2.,3.,4.,5.])
    # Some error
    >>> engine.sqrt(matlab.double([1.,2.,3.,4.,5.]))
    matlab.double([[1.0,1.4142135623730951,1.7320508075688772,2.0,2.23606797749979]])

    调用MATLAB脚本及自定义函数

    调用脚本和自定义函数的过程也几乎一样,也是从变量engine中去调用。值得注意的是,需要保证你的函数或脚本就在当前的工作路径下,否则engine会找不到文件而报错。

    比方说,笔者当前的工作路径下有两个文件:gaussian_pulse.mpy_matlab.py

    gaussian_pulse.m中的内容是这样的:

    function out = gaussian_pulse(fs, fc, repeat)
        N = 882;
        t = 0:1/fs:(N-1)/fs;
        yi = gauspuls(t,fc,1/8);
        temp = yi;
        for i = 1:repeat-1
            temp = cat(2, temp,yi);
        end
        out = temp;
    end

    py_matlab.py中,我定义了engine并调用这个函数:

    engine = matlab.engine.start_matlab()
    signal = engine.gaussian_pulse(matlab.double([44100]), matlab.double([3000]), matlab.double([5]))
     

    注意到每一个输入参数我都强制性进行了转换确保万无一失。加上方括号也是因为MATLAB的格式需求。

    指定输出个数

    默认情况下,API认为接收函数返回结果的参数有1个。这会导致没有返回值的函数在被调用时报错:“Too many output arguments”或是其他类似的信息。我们可以人为指定输出参数为0个来避免这样的错误。

    >>> playblocking(player) # playblocking is a MATLAB function with no returns
    Error using playblocking
    Too many output arguments
    >>> playblocking(player, nargout=0)
    # Success!
     

    True 与 False

    在MATLAB里面逻辑值是true与false,但是在Python里面它们是大写的True和False。毕竟我们还是在Python环境下编程,所以如果调用某个函数需要用到逻辑值,遵循Python的书写格式。

    后记

    官方文档里还有一些其他非常好的教程,包括标准输出/错误信息重导向、句柄的使用、画图等等。鉴于笔者时间原因这些没有涉及到,有需要的朋友可以从笔者在开篇提供的网站中找到答案。

  • 相关阅读:
    LeetCode 121. Best Time to Buy and Sell Stock
    LeetCode 221. Maximal Square
    LeetCode 152. Maximum Product Subarray
    LeetCode 53. Maximum Subarray
    LeetCode 91. Decode Ways
    LeetCode 64. Minimum Path Sum
    LeetCode 264. Ugly Number II
    LeetCode 263. Ugly Number
    LeetCode 50. Pow(x, n)
    LeetCode 279. Perfect Squares
  • 原文地址:https://www.cnblogs.com/jqpy1994/p/10901971.html
Copyright © 2011-2022 走看看