我是靠谱客的博主 傻傻仙人掌,最近开发中收集的这篇文章主要介绍matlab去掉for循环方法,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

最近学习matlab分析和处理几个数据(文件约几百M到一两个G字节),一开始觉得程序很简单,随便写了下,结果matlab处理时间长得让人想哭,边学习边优化,发现主要是for循环占用太长时间,总结下可以去掉for循环的几种情况。

1.用克隆运算符(:和end)

比如一个长向量,想分别改变奇数位置和偶数位置元素的值,这个很简单

 a=rand(100);
 a(1:2:end)=0;
 a(2:2:end)=1;

2.用find或者逻辑索引

比如将矩阵中大于等于128的数减去256(8位补码转为有符号数)

A=randi(256,1,100);A=A-1;   
A(A>=128)=A(A>=128)-256;

或者复杂一点,A是一个10*20*30的三维矩阵,B是一个20*30的二维矩阵,如果A(i,j,k)满足某一条件,则用用B(j,k)替代。此处使用到了matlab矩阵的三种索引:下标索引,线性索引,逻辑索引。其中能用逻辑索引就用逻辑索引。

A=zeros(10,20,30);
A(5,6,4)=15;
B=ones(20,30);
[~,c,p]=ind2sub(size(A),find(A==15));
A(A==15)=B(sub2ind(size(B),c,p));
A(5.6,4)

3.用meshgrid等函数

对于一些二维的变换(多变量函数),使用meshigrid,比用两重for循环快多了

tic
[II,JJ]=meshgrid(1:1000,1:1000);
Y=sin(sqrt(II+JJ));
toc

4.使用mat2cell将矩阵转为cell(重点),并使用cellfun对每个小矩阵进行操作,最后用cell2mat转为矩阵

比如一个100*100的二维矩阵,将其分成100个10*10的小矩阵,对每一个小矩阵求均值

A=randi(255,100,100);
A_cell=mat2cell(A,10*ones(1,10),10*ones(1,10));
A_mean=cellfun(@(x)(mean(mean(x))+1),A_cell,'uniformoutput',false); %每一个小块求均值并加1

如果uniformoutput位false,A_mean依然位cell,然后就是一个矩阵

当然,此处完全可以自定义一个函数并存为func.m,然后再cellfun中引用。

%func.m定义函数
func.m
function out=func(in1,in2);
    out=in1-in2;
end
%调用func
A=randi(255,100,100);
B=cell(100,100);
A_cell=mat2cell(A,10*ones(1,10),10*ones(1,10));
A_cell=cellfun(@func,A_cell,B_cell,'uniformoutput',false);

两外,为了提高性能,推荐减小新变量,使用in-place操作,比如

使用x=x-1,不要使用y=x-1,

5.掌握改变矩阵结构的函数,比如reshape,permute,squeeze,rot90,shiftdim

有些时候,我们使用循环,是因为矩阵‘不顺’,把矩阵结构改一下,矩阵‘顺了’,自然可以使用简单的方法进行向量化操作。改变结构的时候,要注意matlab的列向量存储的特点。

另外为了提高性能,还要注意内存预分配,这个通过运行matlab的profiler即可,或者写程序的时候注意一下报警(代码下面打波浪线的地方)。profiler配合tic,toc,能很快定位问题,剩下的就是解决问题了。profiler用法如下

profile on;
待执行代码
profile viewer 
p = profile('info');
profsave(p,'profile_results') % 保存profile 结果
profile off;

tic toc用法如下:

tic
待执行代码
toc

经过优化代码(向量化操作),即使不借助并行技术(parfor等)或者诸如mex文件等,也能取得满意的效果。当然,如果对时间很敏感,可能还是c或者fortran合适。

 

 

 

 

最后

以上就是傻傻仙人掌为你收集整理的matlab去掉for循环方法的全部内容,希望文章能够帮你解决matlab去掉for循环方法所遇到的程序开发问题。

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

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

评论列表共有 0 条评论

立即
投稿
返回
顶部