草庐IT

我的开源项目之Matlab/Octave转Python工具(motopy)

falwat 2023-07-26 原文

目录

Motopy

介绍

motopy 是一款功能强大(😊自吹吧)的 Matlab/OctavePYthon工具. 在转换的过程中, 自动执行转换后的python语句, 保证转换过程的正确性. 例如下述Matlab/Octave代码:

a = ones(1, 3);
b = a';
c = a * b;

将转换为:

import numpy as np
a = np.ones((1, 3))
b = a.T
c = a @ b

变量 ab 的值类型均为数组类型. 所以在转换第三条语句 c = a * b 时, 将会转换为: c = a @ b.

点击 github链接, 访问我的代码仓库.

安装

使用 pip 安装 motopy.

pip install motopy

快速开始

motopy使用起来及其简单, 首先请准备好你的Matlab/Octave文件, 将脚本文件(*.m)和其调用的函数文件放置在同一个文件夹, 保证你的Matlab/Octave脚本能够正常运行, 并且满足motopy的使用要求. 下面我将给出一个简单的例子:

  • 创建名为"demo"的文件夹.

  • 在"demo"文件夹下, 创建两个.m文件, 文件名分别为"func.m" 和 “func_test.m”, 文件内容如下:

    % file: func.m
    function s = func(a, b)
        s = sqrt(a.^2 + b.^2);
    end
    
    % file: func_test.m
    a = 3;
    b = 4;
    s = func(a, b);
    disp(s)
    
  • 在"demo"文件夹中, 创建一个python脚本文件, 导入motopy, 并调用motopy.make()完成代码的转换. python脚本内容如下:

    import motopy
    motopy.make(entryfile='func_test')
    

    entryfile参数用于指定要转换的m文件的脚本入口(***!!注意, 此处不加扩展名!!***).

    当然, 你也可以直接在python命令行中执行上述代码. 请保证当前目录是"demo"文件夹.

指定输入输出文件夹

python脚本文件可以不放置到m文件所在文件夹中, 输入的m文件和输出的py文件也可以位于不同的文件夹中. 此时可以使用input_path参数指定输入m文件所在位置, 使用output_path参数指定生成的python文件的输出路径.

import motopy
motopy.make(
    entry_basename='func_test', # no extension
    input_path='输入m文件所在路径', 
    output_path='输出py文件所在路径')

指定替代函数

如果你已经完成了某个函数的转换, 可以通过motopy.make()函数中的 replaced_functions参数指定此函数的替代函数.

import motopy
motopy.make(
    entry_basename='func_test', # no extension
    input_path='输入m文件所在路径', 
    output_path='输出py文件所在路径',
    replaced_functions={
        'func': ('func', 'func') # 
    }
)

replaced_functions参数为一个字典, 键为m文件中出现的函数名, 值为二元元组(模块名, 函数名). 上述示例中, func函数文件将不会再次转换.

什么情况下使用replaced_functions?

  • motopy生成的py文件, 我们对其进行了修改, 并且不希望motopy重新生成它.
  • 对于某些m函数, 我们知道python中有功能一致, 且参数对应的函数与其等价. 比如: ceil <–> np.ceil, 我们可以在replaced_functions中添加'ceil': ('numpy', 'ceil')

日志信息

默认在output_path文件夹下生成名为"motopy.log"日志文件. 可以通过logging_file参数, 指定日志文件的输出位置和名称. 使用logging_level设置日志等级: WARN|INFO|DEBUG

import motopy
motopy.make(.., logging_level=motopy.DEBUG, ..)

缩进

默认生成的py文件使用4个空格进行缩进, 可以通过indent参数指定缩进所需的空格数.

motopy的使用要求

因为motopy采用边转译边执行的方式进行转换. 所以转换可能失败. 为了提高转换的成功率. 请对你的".m"代码进行适当修改.

  • 数组和元胞中的元素请不要使用空格进行分隔. 下述代码是一个错误示例:

    a = [1 2 3; 4 5 6];
    c = {1 2 'abc'};
    
  • 函数文件的名称和函数名必须相同.

  • 数组和元胞应该事先定义, 且分配足够大的空间. 下述代码是一个错误示例:

    for k=1:5
        A(k) = 2*k; % A 在赋值之前没有定义.
    end
    
    A = []; % 虽然定义了A, 但是没有给足够大的空间
    for k=1:5
        A(k) = 2*k; % A的大小在迭代的过程中改变了
    end
    

已实现的转换

矩阵, 数组和元胞的创建

Matlab/OctavePythonNote
a = [1,2,3,4]a = np.array([1, 2, 3, 4])matlab中的数组会被转换为np.array
a = [1,2;3,4]a = np.array([[1, 2], [3, 4]])
a = [1;2;3;4]a = np.array([[1], [2], [3], [4]])
C = {1,2,3;'4',[5,6],{7,8,9}}C = [[1, 2, 3], ['4', np.array([5, 6]), [7, 8, 9]]]matlabcell 会被转换成 python中的list
r1 = 1:10;r1 = arange(1, 11)上限自动+1
N = 10;
r2 = 1:N;
N = 10
r2 = arange(1, N + 1)
zeros(3)np.zeros((3, 3))
zeros(2,3)np.zeros((2, 3))
ones(3)np.ones((3, 3))
ones((2, 3))np.ones((2, 3))

矩阵, 数组和元胞的切片

Matlab/OctavePythonNote
a(1,1)a[0, 0]如果索引为数值, 使用减1后的值替代
a(1,:)a[0, :]
a(:,1)a[:, 0]
a(1, 1:2)a[0, 0:2]
a(1:2, 1)a[0:2, 0]
a(1,2:end)a[0, 1:]
m = 1;
n = 1;
a(m, n*2)
m = 1
n = 1
a[m - 1, n * 2 - 1]
如果索引为变量或表达式, 则对变量或表达式-1

函数

Matlab/OctavePythonNote
acosnp.arccos
asinnp.arcsin
atannp.arctan
ceilnp.ceil
cosnp.cos
diagnp.diag
dispprint
eyenp.eye
expnp.exp
fftnp.fft
fixnp.fix
floornp.floor
fprintf
ifftnp.ifft
invlinalg.inv
linspacenp.linspace
lognp.log
log10np.log10
log2np.log2
ndimsnp.ndim
numelnp.size
pinvlinalg.pinv
ranklinalg.matrix_rank
roundnp.round
sinnp.sin
sortnp.sort
sprintf('%d%s',a, b)f'{a}{b}'
sqrtnp.sqrt
uniquenp.unique

说明

Motopy 目前处于开发阶段, 如果你在使用的过程中发现任何关于motopy的问题, 烦请提交至Issues, 或邮件告知(falwat@163.com), 留言亦可. 我将在后续版本中更新修复. 感谢使用motopy.

有关我的开源项目之Matlab/Octave转Python工具(motopy)的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  3. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  4. ruby-on-rails - 新 Rails 项目 : 'bundle install' can't install rails in gemfile - 2

    我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="

  5. ruby-on-rails - 如何在我的 Rails 应用程序 View 中打印 ruby​​ 变量的内容? - 2

    我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby​​中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R

  6. ruby - 我可以将我的 README.textile 以正确的格式放入我的 RDoc 中吗? - 2

    我喜欢使用Textile或Markdown为我的项目编写自述文件,但是当我生成RDoc时,自述文件被解释为RDoc并且看起来非常糟糕。有没有办法让RDoc通过RedCloth或BlueCloth而不是它自己的格式化程序运行文件?它可以配置为自动检测文件后缀的格式吗?(例如README.textile通过RedCloth运行,但README.mdown通过BlueCloth运行) 最佳答案 使用YARD直接代替RDoc将允许您包含Textile或Markdown文件,只要它们的文件后缀是合理的。我经常使用类似于以下Rake任务的东西:

  7. Ruby 从大范围中获取第 n 个项目 - 2

    假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit

  8. jquery - 我的 jquery AJAX POST 请求无需发送 Authenticity Token (Rails) - 2

    rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送

  9. Python 相当于 Perl/Ruby ||= - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。

  10. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

随机推荐