[m2py]matlab代码转Python——注意事项

Dustone

2021/5/12

 

本文为深度概率模型采样库pydpm中Topic model的matlab代码转Python代码时总结的细节及注意事项

宣传一下实验室的pydpm库:https://github.com/BoChenGroup/pydpm

 

函数替换m -> py

浮点数精度 eps -> np.spacing(1)

矩阵A*B -> np.dot(A,B)

A.*B -> A*B

randi(max,m,n) -> np.random.randint(max,size=(m,n))

A./sum(A,2) -> A/A.sum(axis=1,keepdims=1) # A为矩阵/ndarray

randg -> np.random.gamma

betarnd -> np.random.beta

x(find(x>0))=0 -> np.argwhere(x>t) 返回每个元素的索引

x[x>0]=0 x>0返回布尔值

np.where(a==1) 返回维数个array构成的tuple,array为元素的在某维下索引

max(array, realmin) -> np.maximum(array, realmin)

[row,col] = find(X, ...) -> col, row = np.where(X.T) matlab中一列一列地查找,Python中一行一行查找

reshape(X,m,n) -> X.reshape(m,n) 同find用法,matlab按列操作

repmat(x,m,n) -> np.tile(x,(m,n)) 复制数组m倍y轴,n倍x轴

np.repeat() 以element为最小单位进行复制

ones(size(a)) -> np.ones_like(a)

> np.ones(a.shape)

max(realmin, A) -> A[A

bsxfun(@rdivide,A,a) -> A/a A(n,m)ndarray a(n,1)

MEX Theta[k + Ksize*j] -> Theta[k, j] Theta(Ksize,N),MEX中按列索引

sparse(zs, ds, 1, k, N) -> sparse.csc_matrix((1*, zs, ds), shape=(P, N))

sparse(X) -> sparse.csc_matrix(X)

full(x) -> x.toarray() x: csc matrix

MEX,csc_matrix: mxGetPr mxGetIr mxGetJc -> .data(取值pr) .indices(行号lr) .indptr(列号jc)

csc_matrix((data, (row, col)), shape=(3, 3)) # row 行,col列, 按列存储 a[row_ind[k], col_ind[k]] = data[k]

 

不同

Matlab中函数的参数传递需要显式定义,而Python中面向对象编程,参数的传递可以通过属性

int/float/doubel的问题,matlab中double属性的整数可以作为索引,而Python中不可

numpy中(n,)和(n,1),(1,n)shape的array存在区别,a=np.ones(n),b=np.ones((n,1)),c=np.ones((1,n))。在matlab中就是(n,1)的形式,此类型变量一般可直接在Python中定义为(n,)的形式,因为很多函数输入(n,1)输出(n,)。在某些特殊运算中,如np.dot中可reshape一下。

matlab中(1,n)数组可索引到元素,py中需a[0][index]。所以变量一般可直接在Python中定义为(n,)的形式

matlab中sum(A,2)得到(m,1)结果,Python中np.sum(A,1)得到(m,) array

matlab中sparse可以直接索引,Python中需要toarray再索引

array的操作方法,如find,reshape

'~1' stand for logical 0(False) in matlab, but -2(按位取反运算符1) in python,逻辑判断一般采用if not flag

Python参数传递时是传递对象引用(传值和传址的混合方式),如果是数字,字符串,元组则传值;如果是列表,字典则传址。可通过copy.deepcopy()来传值;而matlab中是传值

in python, 'a is b' and 'a==b' is not equal. use 'a is b' to test if a&b share the same data in memery使用is查看两个变量名是否指向同一个地址

 

Debug-固定随机数调试

产生相同随机数方法:

rand('twister', 0)

rand(3,1) % matlab

np.random.seed(0)

np.random.rand(3,1) # python

通过

save data1 %in m

import scipy.io as sio

d = sio.loadmat('data1.mat') #in py. 反向使用savemat

将matlab工作区变量保存引入Python可对比变量是否相等(非int型可能会存在非常小的误差),d的嵌套比较多且形式会改变,可以通过reshape后进行对比

 

Debug-matlab和Python变量互传

%matlab 2 Python

save data1 %m

import scipy.io as sio # py

d = sio.loadmat('data1.mat') #py

#python 2 matlab

sio.savemat('python_phi.mat',{'phi':phi}) # py

phi=load('python_phi.mat').phi

 

matlab-混合编程mex

Matlab运算能力强大,但是太慢,而C语言速度极快。实际操作过程中可以通过mex混合编程把计算速度慢、涉及到大量循环的matlab代码转而用C来实现。

工作流程为:

编写执行核心计算任务的C语言函数代码

编写接口函数mexFunction

编译,matlab命令行 mex test.c

在matlab中调用

mexFunction可以看成是matlab与C的接口函数,matlab调用mexFunction来实现C语言的功能。mexFunction的定义如下:

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])

其中nlhs为输出的个数(n of left-hand-side),plhs为输出的指针数组。nrhs为输入参数的个数,prhs为输入参数的指针数组。

需要注意的是,c中通过指针索引数组值时是按列索引的,即Theta[k + Ksize*j]在Python转化为Theta[k, j],其中Theta.shape=(Ksize,N)

并且,由于for循环计算速度较慢,而且有些无法改造为对ndarray的操作,导致运行速度较慢

 

Python-CUDA并行加速

由于matlab通过mex使用c语言进行大量循环计算,速度较快,而Python中有很多操作需要for循环,导致运行速度远慢于matlab,可通过CUDA编程来实现并行加速

2do

 

Else-tips

matlab稀疏矩阵

https://www.cnblogs.com/sylar120/p/3278603.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值