Matlab编程学习:用内建函数代替for循环
2016-01-20 22:28
519 查看
在使用matlab进行矩阵计算的时候,经常会遇到要使用for循环的情况。但其实很多操作可以用内部的一些函数代替。今天总结一些几个函数的用法:
bsxfun, arrayfun, cellfun, spfun, structfun
bsxfun:
bsxfun可以对矩阵A和矩阵B进行对应元素的fun函数操作。其中,fun是任何标量输入输出的二元操作的函数,例如基本的加减乘除,三角函数,大小比较,以及其他任何符合条件的自定义函数。
注意,fun不能是符号,例如+,*之类,这些符号都有对应的函数名。例如+ 对应 plus, >= 对应 ge,等等。可以通过matlab命令行输入
help <运算符号>
来查询。
一般来说,如果两个矩阵一样大,我们可以直接通过 A+B 这样的方式一样实现,但是bsxfun有一个优点,就是当A,B中任何一维长度为1的时候,函数会自动将该维度和另一个矩阵对应维度的每一行(列)进行运算。如果我们自己进行这样的操作,我们或者要使用循环,或者要使用repmat来扩展矩阵,这都比bsxfun在底层内部实现慢很多,或者要消耗更多内存。
网友提供了这样一个例子:假设我们有数据A和B, 每行是一个样本,每列是一个特征。我们要计算高斯核,既:
k(||x-xc||)=exp{- ||x-xc||^2/(2*σ)^2) } 其中xc为核函数中心,σ为函数的宽度参数 , 控制了函数的径向作用范围。
当然可以用双重for实现:
使用2,000×1,000大小的A和B, 运行时间为88秒。
考虑下面向量化后的版本:
使用同样数据,运行时间仅0.85秒,加速超过100倍。
a =
-0.4336
0.3426
3.5784
b = 2.7694 -1.3499 3.0349
c=bsxfun(@plus,a,b)
c =
2.3358 -1.7835 2.6013
3.1121 -1.0073 3.3775
6.3478 2.2285 6.6133
这个函数可以直接对数组中的元素进行func函数操作。其中,func函数接受n个输入,m个输出。当输出可以进行合并的时候,可以设置 'UniformOutput' 为true,这样所有 A1..An经过func的第m个输出就会合并为一个数组 Bm,如果'UniformOutput'为false,表示不同输入元素对应的输出不能合并,这样每个Bm就会是一个cell。
和arrayfun的用法类似,不过是对cell的对应元素进行操作。
类似的用法,对结构体S的所有域进行func操作。
这个函数可以对一个稀疏矩阵S的每个有值的元素进行fun操作。
这个函数的用途不仅仅是可以提升速度,更重要的是能够保持返回的f中,没有数据的地方依然为0. 例如:
bsxfun, arrayfun, cellfun, spfun, structfun
bsxfun:
1 | C = bsxfun(fun,A,B) |
注意,fun不能是符号,例如+,*之类,这些符号都有对应的函数名。例如+ 对应 plus, >= 对应 ge,等等。可以通过matlab命令行输入
help <运算符号>
来查询。
一般来说,如果两个矩阵一样大,我们可以直接通过 A+B 这样的方式一样实现,但是bsxfun有一个优点,就是当A,B中任何一维长度为1的时候,函数会自动将该维度和另一个矩阵对应维度的每一行(列)进行运算。如果我们自己进行这样的操作,我们或者要使用循环,或者要使用repmat来扩展矩阵,这都比bsxfun在底层内部实现慢很多,或者要消耗更多内存。
网友提供了这样一个例子:假设我们有数据A和B, 每行是一个样本,每列是一个特征。我们要计算高斯核,既:
k(||x-xc||)=exp{- ||x-xc||^2/(2*σ)^2) } 其中xc为核函数中心,σ为函数的宽度参数 , 控制了函数的径向作用范围。
当然可以用双重for实现:
1 2 3 4 5 6 | K1 = zeros(size(A,1),size(B,1)); for i = 1 : size(A,1) for j = 1 : size(B,1) K1(i,j) = exp(-sum((A(i,:)-B(j,:)).^2)/beta); end end |
考虑下面向量化后的版本:
1 2 3 | sA = (sum(A.^2, 2)); sB = (sum(B.^2, 2)); K2 = exp(bsxfun(@minus,bsxfun(@minus,2*A*B', sA), sB')/beta); |
a =
-0.4336
0.3426
3.5784
b = 2.7694 -1.3499 3.0349
c=bsxfun(@plus,a,b)
c =
2.3358 -1.7835 2.6013
3.1121 -1.0073 3.3775
6.3478 2.2285 6.6133
arrayfun:
1 2 | [B1,...,Bm] = arrayfun(func,A1,...,An) [B1,...,Bm] = arrayfun(func,A1,...,An,Name,Value) |
cellfun:
1 2 | [A1,...,Am] = cellfun(func,C1,...,Cn) [A1,...,Am] = cellfun(func,C1,...,Cn,Name,Value) |
structfun:
1 2 | [A1,...,An] = structfun(func,S) [A1,...,An] = structfun(func,S,Name,Value) |
spfun:
1 | f = spfun(fun,S) |
这个函数的用途不仅仅是可以提升速度,更重要的是能够保持返回的f中,没有数据的地方依然为0. 例如:
1 2 | S = spdiags([1:4]',0,4,4) f = spfun(@exp,S) |
@plus | Plus |
@minus | Minus |
@times | Array multiply |
@rdivide | Right array divide |
@ldivide | Left array divide |
@power | Array power |
@max | Binary maximum |
@min | Binary minimum |
@rem | Remainder after division |
@mod | Modulus after division |
@atan2 | Four quadrant inverse tangent |
@hypot | Square root of sum of squares |
@eq | Equal |
@ne | Not equal |
@lt | Less than |
@le | Less than or equal to |
@gt | Greater than |
@ge | Greater than or equal to |
@and | Element-wise logical AND |
@or | Element-wise logical OR |
@xor | Logical exclusive OR |
相关文章推荐
- MATLAB 画图 legend
- Matlab中Fuzzy Logic Controller使用注意
- MATLAB的小技巧
- MATLAB画图-legend,box用法
- Matlab的parfor并行编程
- 如何使用MATLAB将c/cpp文件编译成mex32/mex64文件
- 美国康奈尔大学BioNB441元胞自动机MATLAB应用
- 美国康奈尔大学BioNB441元胞自动机MATLAB应用
- libSVM在matlab下的使用安装
- SVM实例及Matlab代码
- SVM实例及Matlab代码
- 【zz】Matlab 二值图像形态学函数 bwmorph
- paper 11:matlab中fix函数,floor函数,ceil函数,round函数的区分
- vlfeat重编译以及visual studio与matlab联调
- MATLAB软件
- 批量提取 caffe 特征 (python, C++, Matlab)(待续)
- Matlab图像处理系列2———空间域平滑滤波器
- Python调用MATLAB Install MATLAB Engine for Python
- 随笔1.19.2016
- 【matlab函数】conv2、filter2、imfilter的区别