MATLAB向量化函数 举例,MatLab-向量化技巧

《MatLab-向量化技巧》由会员分享,可在线阅读,更多相关《MatLab-向量化技巧(10页珍藏版)》请在人人文库网上搜索。

1、MatLab 向量化技巧家家 2007-05-17 13:53大家都知道MatLab是一种解释性语言,它的长处在矩阵运算。因此需要将问题尽量用矩阵表示,并且要避免对单个矩阵元素操作,而用整体矩阵运算。一个重要过程就是所谓将问题矢量化(vectorizing)。一个问题是如果需要对矩阵的不同元素作不同操作,那么怎么办?举个例子对矩阵X,作A=5*sin(X)/X,显然当X某元素-0时,A对应元素-5。按照通常在其他语言思路编程为:Nx=2000;X=2.0*pi*(rand(Nx,Nx)-0.5);X(1:Nx/2,:)=0.0;%生成NxXNx矩阵X,一半为随机分布,一半为0。A=zeros(。

2、Nx,Nx);form=1:Nxforn=1:Nxif(abs(X(m,n)=eps)A(m,n)=5.0.*sin(X(m,n)./X(m,n);elseA(m,n)=5.0;endendend%(ProgramNo.1)以上代码通过循环语句对每一个矩阵元素进行单独操作,这段代码在MatLab里效率特别低。为避免循环,考虑如下方法:方法I:用所谓logicalsubscripting。Nx=2000;X=2.0*pi*(rand(Nx,Nx)-0.5);X(1:Nx/2,:)=0.0;A=zeros(Nx,Nx);I=(abs(X)=eps);A=I.*5.0.*sin(X)./(X+(1-。

3、I)+(1-I).*5.0;%(ProgramNo.2)或者上面最后一行用如下代码代替:A(I)=5.0.*sin(X(I)./X(I);A(I)=5.0;%(ProgramNo.3)一个看起来更有效的办法是先生成一个所有元素都是5的A矩阵。代码如下:Nx=2000;X=2.0*pi*(rand(Nx,Nx)-0.5);X(1:Nx/2,:)=0.0;A=5.0;A=A(ones(Nx,Nx);%用Tonystrick生成矩阵A,所有元素=5I=(abs(X)=eps);A(I)=5.0.*sin(X(I)./X(I);%(ProgramNo.4)方法II:用find函数。Nx=2000;X=。

4、2.0*pi*(rand(Nx,Nx)-0.5);X(1:Nx/2,:)=0.0;A=5.0;A=A(ones(Nx,Nx);I=find(abs(X)=eps);A(I)=5.0.*sin(X(I)./X(I);%(ProgramNo.5)我在P41.6G,512MDDR266上作了个测试,每个程序执行5遍,选最小执行时间:ProgramNo.time(s)171.2023.3132.6442.8053.22显然ProgramNo.3是最快的。如果X矩阵中0元素很少,那么ProgramNo.2、ProgramNo.3以及ProgramNo.4的执行时间会非常接近。大家可以用profiler分。

5、析每一个语句所用时间情况。以上是我用过的两种方法,有没有更有效的方法呢?还有个问题就是,如何将主对角元素的Index加入到变量I中?例如需要将满足abs(X)1)if (mod(n,2)=1)n=n*3+1;elseif(mod(n,2)=0)n=n/2;else break;endendf=n;验证1:, 以前我们可能这样做:代码:a=zeros(1,);for k=1:a(k)=jiaogu(k);endall(a)现在我们只需这样:代码:all(arrayfun(jiaogu,1:)举这两个例子目的是为了让大家知道很多以前不能优化的程序利用这个函数还可以进一步优化。具体了解请doc ar。

6、rayfun 。另外cellfun和structfun也提供了类似的功能,关于其用法,帮助文档里写的很详细。向量化操作的又一重要函数accumarray的用法总结向量化编程是MATLAB编程区别于其他语言的最重要特征之一,MATLAB不断增强其向量化编程的能力。版本7以后出现的accumarray函数就是一个很好的例子。accumarray函数最早出现于7.0版(R14),在随后的7.1 (R14SP3), 7.2 (R2006a)版里又对其功能进行增强。大家可以在帮助文档里了解其基本信息,这里结合自己的使用经验给出其用法的举例,大家可以看看其效果。例1:生成一个*1的向量,其元素服从1,之间。

7、离散均匀分布,找出都有哪些元素出现了a=unidrnd(,1);方法1:tic;b=union(a,a);toc;Elapsed time is 0. seconds.方法2:tic;c=unique(a);toc;Elapsed time is 0. seconds.方法3tic,d=accumarray(a,1,1);e=find(d);tocElapsed time is 0. seconds.d 给出了每个元素出现的个数,如果还需要这方面的信息,无疑方法3占绝对优势。例2:在1000*1000的正方形区域内随机生成个点(坐标值是整数),统计每个坐标点上生成的点的个数。在这个例子下,像例。

8、1一样简单应用union和unique就不行了。通常我们考虑用循环:p=unidrnd(1000,2);tic;A=zeros(1000);for k=1:A(p(k,1),p(k,2)=A(p(k,1),p(k,2)+1;endtocElapsed time is 0. seconds.而用accumarray,可以这样: tic;a=accumarray(p,1,1000,1000);tocElapsed time is 0. seconds. isequal(A,a)ans =1速度整整提高了10倍。例3:1000人,身高分布在170-180,体重在110-200斤,年龄分布在20-50。

9、岁,计算身高体重都相等的人的年龄平均值。结果用矩阵表示:行数表示身高,列数表示体重,元素表示年龄的平均值。首先生成数据:rand(state,0)height=unidrnd(10,1000,1)+170;rand(state,0)weight=unidrnd(90,1000,1)+110;rand(state,0)old=unidrnd(30,1000,1)+20;利用accumarray计算的语句如下:tic;mo=accumarray(height,weight,old,mean);tocElapsed time is 0. seconds.这个矩阵比较稀疏也可以结果用稀疏矩阵来表示tic;mo=accumarray(height,weight,old,mean,0,true);tocElapsed time is 0. seconds.维数大后,稀疏矩阵会有优势,这个例子还不明显。大家有兴趣可以试试传统方法效果。以上仅举了三个例子,实际上,accumaary的应用方法非常灵活,尤其是对于很多要操作大矩阵的情况下。大家可以仔细看看帮助文档。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值