![]() |
[求助]用MATLAB来计算一些科学数据,但用FOR循环计算时发现速度太慢
各位大侠,我是一个处于偏僻山区的教育者,现在急用MATLAB来计算一些科学数据,但用FOR循环计算时发现速度太慢,不知道还有什么办法解决。请大侠们多多帮且我啊。太恩不言谢,兄弟就此拜托了。
以下是我这个刚学MATLAM的阿呆(:cry:) 的计算程序,请大侠们帮看看并提出增加速度的方案,小的在这有礼了! k=0.1:0.0000005:0.91; j=1; for m=0.1:0.0000005:0.91 e0=8.85*10^(-12); p0=4*pi*10^(-7);c0=3*10^8;a=3*10^(-10); na=sqrt(9.0);nb=sqrt(1);nc=sqrt(4);nd=sqrt(1.0);ng=sqrt(16);nh=1.0; da=0.5*a;db=0.5*a;dc=0.5*a;dd=0.5*a;dg=0.5*a;dh=0.5*a; g0=sqrt(e0/p0)*1; ga=g0*na;gb=g0*nb;gc=g0*nc;gd=g0*nd;gg=g0*ng;gh=g0*nh; sa=-na*pi*m;sb=-nb*pi*m;sc=-nc*pi*m;sd=-nd*pi*m;sg=-ng*pi*m;sh=-nh*pi*m; A=[cos(sa),-i*sin(sa)/ga;-i*ga*sin(sa),cos(sa)];B=[cos(sb),-i*sin(sb)/gb;-i*gb*sin(sb),cos(sb)]; C=[cos(sc),-i*sin(sc)/gc;-i*gc*sin(sc),cos(sc)];D=[cos(sd),-i*sin(sd)/gd;-i*gd*sin(sd),cos(sd)]; G=[cos(sg),-i*sin(sg)/gg;-i*gg*sin(sg),cos(sg)];H=[cos(sh),-i*sin(sh)/gh;-i*gh*sin(sh),cos(sh)]; M1=(G*H)^(5)*(A*B)^(5)*(C*D)^(5)*(B*A)^(5)*(H*G)^(5); A1=M1(1,1);B1=M1(1,2);C1=M1(2,1);D1=M1(2,2); r1=2*g0/(A1*g0+B1*g0^2+C1+D1*g0); f1=r1*r1'; R1(1,j)=f1; j=j+1; end plot(k,R1,'k');axis([0.1,0.9,0,1]),ylabel('Transmission'); |
循环次数达1620001次,的确慢。想快也快不起来
|
这个程序可以优化提速,等会儿给lz上程序,working...
|
感谢Mathjiang,remnant大侠对小的支持!
感谢Mathjiang,remnant大侠对小的支持!这个程序对于我,太重要了。谢谢!
初学者 顿首拜谢 |
听说写成向量形式代替循环比较快
|
进一步麻烦大侠们
我的本本电脑CPU主频是2.4,内存升级后为2.0G,在运行MATLAB程序的过程中出现如下提示符,该什么办?“??? Error using ==> plus
Out of memory. Type HELP MEMORY for your options.” 恳请大侠们救救火哦,谢谢啦! 初学者 敬拜 |
[QUOTE=sa7312;14032] 我的本本电脑CPU主频是2.4,内存升级后为2.0G,在运行MATLAB程序的过程中出现如下提示符,该什么办?“??? Error using ==> plus
Out of memory. Type HELP MEMORY for your options.” 恳请大侠们救救火哦...[/QUOTE] 好,先上程序,边看边说。 %% clear; clc; %% t0 = cputime; e0 = 8.85 * 10^(-12); p0 = 4 * pi * 10^(-7); c0 = 3 * 10^8; a = 3 * 10^(-10); na = sqrt( 9.0 ); nb = sqrt( 1 ); nc = sqrt( 4 ); nd = nb; ng = sqrt( 16 ); nh = 1.0; da = 0.5 * a; db = da; dc = da; dd = da; dg = da; dh = da; g0 = sqrt( e0/p0 ); ga = g0 * na; gb = g0 * nb; gc = g0 * nc; gd = g0 * nd; gg = g0 * ng; gh = g0 * nh; m = 0.1:0.0000005:0.91; m_size = length( m ); sa = -1 * na * pi * m; sb = -1 * nb * pi * m; sc = -1 * nc * pi * m; sd = -1 * nd * pi * m; sg = -1 * ng * pi * m; sh = -1 * nh * pi * m; A = zeros( 2, 2, m_size ); B = zeros( 2, 2, m_size ); C = zeros( 2, 2, m_size ); % D = zeros( 2, 2, length(m) ); G = zeros( 2, 2, m_size ); % H = zeros( 2, 2, length(m) ); A( 1, 1, : ) = cos( sa ); A( 1, 2, : ) = -i * sin( sa ) / ga; A( 2, 1, : ) = -i * ga * sin( sa ); A( 2, 2, : ) = A( 1, 1, 1:end ); B( 1, 1, : ) = cos( sb ); B( 1, 2, : ) = -i * sin( sb ) / gb; B( 2, 1, : ) = -i * gb * sin( sb ); B( 2, 2, : ) = B( 1, 1, 1:end ); C( 1, 1, : ) = cos( sc ); C( 1, 2, : ) = -i * sin( sc ) / gc; C( 2, 1, : ) = -i * gc * sin( sc ); C( 2, 2, : ) = C( 1, 1, 1:end ); G( 1, 1, : ) = cos( sg ); G( 1, 2, : ) = -i * sin( sg ) / gg; G( 2, 1, : ) = -i * gg * sin( sg ); G( 2, 2, : ) = G( 1, 1, 1:end ); % sa,sb,sc,sd,sg,sh is not used from here to last, so, clear them for more memory. clear( 'sa' ); clear( 'sb' ); clear( 'sc' ); clear( 'sd' ); clear( 'sg' ); clear( 'sh' ); %% % Because of B==D==G , % M1 = (GB)^5 * (AB)^5 * (CD)^5 * (BA)^5 * (HG)^5 => M1 = G * (BG)^4 * (BA)^5 * B * (CB)^5 * (BA)^5 * (BG)^4 * B * G % so, A and C can be clear from memory after we get BA and CB. % We must clear all varibles not to be used again. % Step 1. Calculate BA, clear A BA = Mat3dx( B, A ); clear( 'A' ); % Step 2. Calculate CB, clear C CB = Mat3dx( C, B ); clear( 'C' ); % Step 3. get BG, then calculate (BG)^4 ,clear BG BG = Mat3dx( B, G ); BG4 = Mat3dx( BG, BG ); clear( 'BG' ); BG4 = Mat3dx( BG4, BG4 ); % Step 4. calculate (BA)^5, clear BA BA5 = Mat3dx( BA, BA ); BA5 = Mat3dx( BA5, BA5 ); BA5 = Mat3dx( BA5, BA ); clear( 'BA' ); % Step 5. calculate (CB)^5 , clear CB CB5 = Mat3dx( CB, CB ); CB5 = Mat3dx( CB5, CB5 ); CB5 = Mat3dx( CB5, CB ); clear( 'CB' ); %% start calculate M1 % now, M1 = G * BG4 * BA5 * B * (CB5 * BA5) * BG4 * B * G; % we must start calculation from CB5 * BA5 or B * CB5 , because one Matrix % must to be clear after every multiplication for more memory. CBA5 = Mat3dx( CB5, BA5 ); clear( 'CB5' ); % now, M1 = G * BG4 * BA5 * B * (CBA5 * BG4) * B * G; CBG4 = Mat3dx( CBA5, BG4 ); clear( 'CBA5' ); % now, M1 = G * BG4 * BA5 * B * (CBG4 * B) * G; CB5B = Mat3dx( CBG4, B ); clear( 'CBG4' ); % now, M1 = G * BG4 * BA5 * B * (CB5B * G); CB5G = Mat3dx( CB5B, G ); clear( 'CB5B' ); % now, M1 = G * BG4 * BA5 * (B * CB5G); BCB5G = Mat3dx( B, CB5G ); clear( 'B' ); clear( 'CB5G' ); % now, M1 = G * BG4 * (BA5 * BCB5G); BAG = Mat3dx( BA5, BCB5G ); clear( 'BA5' ); clear( 'BCB5G' ); % now, M1 = G * (BG4 * BAG); BGG = Mat3dx( BG4, BAG ); clear( 'BG4' ); clear( 'BAG' ); % now, M1 = G * BGG; M1 = Mat3dx( G, BGG ); clear( 'G' ); clear( 'BGG' ); % now, M1 done %% r1 = zeros( 1, m_size ); r1( 1:end ) = 2 * g0 ./ ( g0 * M1( 1, 1, : ) + M1( 1, 2, : ) * g0^2 + M1( 2, 1, : ) + M1( 2, 2, : ) * g0 ); clear( 'M1' ); R1 = r1 .* ( r1(:)' ); clear( 'r1' ); plot( m, R1, 'k' ); axis( [ 0.1, 0.9, 0, 1 ] ); ylabel( 'Transmission' ); %% t = cputime - t0; disp( t ); %% 程序运行出结果(画出图)所需时间92.3秒,内存从320-1220M,平均900M。总算在有生之年看到结果了,热泪盈眶。 下面,说一下编程思想。 1。首先,观察你的程序,发现用的一个超级for循环,这让我们无法在有生之年看到结论。所以,全部改成向量和矩阵运算。直接运行发现内存不够,靠,我2G内存都不够,继续优化。观察了一下,A,B,C,D,G,H,M1是内存占用大户,还有一些中间结果。 2。再看你的参数定义,发现B,D,G三个量完全一样,优化,只存1个即可,然后在运算过程中保证每次矩阵相乘都可以至少clear掉一个矩阵,这样边算边clear,直到最后。程序里做了简单注释,看看就明白了。 3。不知道自己逻辑写错没,这里不得不提一下,你的coding style实在是太糟糕了,我看了第一眼你的程序就知道可以优化,但是实在没兴趣再看第2眼,所以详细的逻辑过程我不想在去做verification了。coding style这个东西,一定要早早注意并形成好的代码风格,这个非常影响代码编写效率,易维护性和执行效率。 论坛里很多人都有着很糟糕的coding style,大家都应该注意这一点。工作中如果写出这样的代码,直接就沦为垃圾代码重写了。 |
这个程序在内存上还可以进一步优化,比如,先产生A,B(只产生A,B)然后计算好
M1中需要用A,B做运算的部分。然后,clear掉不需要再次用到的变量。 |
衷心地感谢remnant楼主
remnant楼主:
非常感谢您的鼎力帮助,我用你的方法自己优化了我的程序,运行一次耗时59秒,速度超快!您真是太伟大了!因为兴奋,昨晚我连续工作到现在! 谢谢,非常感谢! 我是个老来才学电脑的,本来是个电脑盲,再加上编程,头全大完了!见到您的程序,就如见到署光一番! 我工作单位在广西宜州市,我的QQ号是771089083,QQ名“老爷子”,邮箱是[email protected]。欢迎您和家人到广西宜州市来观光旅游和指导工作!之所以写上这些,没有别的意思,也不奢望什么,只是想表示我诚挚地谢意! 今后还恳请继续得到您的指导和帮助,再次感谢您! 初学者:老爷子拜谢 |
[QUOTE=remnant;14046]好,先上程序,边看边说。
%% clear; clc; %% t0 = cputime; e0 = 8.85 * 10^(-12); p0 = 4 * pi * 10^(-7); c0 = 3 * 10^8; a = 3 * 10^(-10); na = sqr...[/QUOTE] 晕啊,忘记把调用的一个子程序放出来了,补上,2 x 2 x length 的3d矩阵相乘的子程序。 function [ prMat ] = Mat3dx( MatA, MatB ) %% 2 x 2 x m matrix multiplier A11xB11 = MatA( 1, 1, : ) .* MatB( 1, 1, : ); A11xB12 = MatA( 1, 1, : ) .* MatB( 1, 2, : ); A12xB21 = MatA( 1, 2, : ) .* MatB( 2, 1, : ); A12xB22 = MatA( 1, 2, : ) .* MatB( 2, 2, : ); A21xB11 = MatA( 2, 1, : ) .* MatB( 1, 1, : ); A21xB12 = MatA( 2, 1, : ) .* MatB( 1, 2, : ); A22xB21 = MatA( 2, 2, : ) .* MatB( 2, 1, : ); A22xB22 = MatA( 2, 2, : ) .* MatB( 2, 2, : ); prMat( 1, 1, : ) = A11xB11 + A12xB21; prMat( 1, 2, : ) = A11xB12 + A12xB22; prMat( 2, 1, : ) = A21xB11 + A22xB21; prMat( 2, 2, : ) = A21xB12 + A22xB22; 说的那么客气,搞的我都不好意思了。 共同进步吧。学无止境。 另外,如果你老是需要做类似上面这种大数据量的处理,建议装Linux然后安装Linux版的 Matlab,执行速度会再次改善。这是由于Linux系统的内存管理机制和windows的差异造成的。 还有,如非必要,尽量不要clear掉中间产生的过度变量,那样的话一旦程序结果出错,跟踪 debug起来比较麻烦。提高程序效率的关键还是算法和coding style,要简洁高效。 |
所有时间均为北京时间。现在的时间是 03:19。 |
Powered by vBulletin
版权所有 ©2000 - 2025,Jelsoft Enterprises Ltd.