我是靠谱客的博主 生动皮卡丘,最近开发中收集的这篇文章主要介绍Matlab编程学习:用内建函数代替for循环 1  C = bsxfun(fun,A,B) arrayfun:cellfun:structfun:spfun:,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

在使用matlab进行矩阵计算的时候,经常会遇到要使用for循环的情况。但其实很多操作可以用内部的一些函数代替。今天总结一些几个函数的用法: bsxfun, arrayfun, cellfun, spfun, structfun

bsxfun:

1
 C = bsxfun(fun,A,B)

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实现:

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

使用2,000×1,000大小的A和B, 运行时间为88秒。

考虑下面向量化后的版本:

1
2
3
 sA =  ( sum (A.^ 22 ) );
 sB =  ( sum (B.^ 22 ) );
 K2 =  exp (bsxfun (@minus,bsxfun (@minus, 2*A*B', sA ), sB' )/ beta );

使用同样数据,运行时间仅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

arrayfun:

1
2
 [B1, ...,Bm ] = arrayfun (func,A1, ...,An )
 [B1, ...,Bm ] = arrayfun (func,A1, ...,An,Name,Value )

这个函数可以直接对数组中的元素进行func函数操作。其中,func函数接受n个输入,m个输出。当输出可以进行合并的时候,可以设置 'UniformOutput' 为true,这样所有 A1..An经过func的第m个输出就会合并为一个数组 Bm,如果'UniformOutput'为false,表示不同输入元素对应的输出不能合并,这样每个Bm就会是一个cell。

cellfun:

1
2
 [A1, ...,Am ] =  cellfun (func,C1, ...,Cn )
 [A1, ...,Am ] =  cellfun (func,C1, ...,Cn,Name,Value )

和arrayfun的用法类似,不过是对cell的对应元素进行操作。

structfun:

1
2
 [A1, ...,An ] = structfun (func,S )
 [A1, ...,An ] = structfun (func,S,Name,Value )

类似的用法,对结构体S的所有域进行func操作。

spfun:

1
 f =  spfun (fun,S )

这个函数可以对一个稀疏矩阵S的每个有值的元素进行fun操作。

这个函数的用途不仅仅是可以提升速度,更重要的是能够保持返回的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编程学习:用内建函数代替for循环 1  C = bsxfun(fun,A,B) arrayfun:cellfun:structfun:spfun:的全部内容,希望文章能够帮你解决Matlab编程学习:用内建函数代替for循环 1  C = bsxfun(fun,A,B) arrayfun:cellfun:structfun:spfun:所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(39)

评论列表共有 0 条评论

立即
投稿
返回
顶部