24小时热门版块排行榜    

查看: 1954  |  回复: 15

myw052

金虫 (正式写手)

博士

[求助] matlab for循环速度 提高方法

下面的程序是我用matlab写的一个程序,程序中需要用到for循环,由于是高位矩阵,在运行的时候循环速度效率很低,造成计算成本很大。在许多论坛上寻找好的方法来解决matlab运行中循环的速度提高方法,始终没有找到。有人说用矢量化解决问题,但是描述的不具体,操作起来有困难。有人说用“少拿多取”的思想,但是在简单情况下,可以理解,像如下的情况,似乎难以实行。

故在本版发帖,希望斑竹或者各位程序达人能出来指点一二。本人不胜感激。
(注:此贴绝不是无病呻吟)。

function for_cycle()
tic
clc
clear
close all
beta=rand(10^5,10,10);
gama=rand(10^5,10,10);

[Row,Column,Volume]=size(beta);
gama_u=rand(1,1);
m=2;

for k=1:Volume                     
    k
    for i=1:Row                    
        for j=1:Column               
            D(i,j,k)=beta(i,j,k)/(beta(i,j,k)+(1-beta(i,j,k))*(gama(i,j,k)-(gama(i,j,k)/gama_u)^m)/(gama(i,j,k)-1));
        end
    end
end

D
toc
end
回复此楼
天天快乐
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

sudo

木虫 (正式写手)

【答案】应助回帖

★ ★ ★ ★ ★ ★ ★ ★
感谢参与,应助指数 +1
xzhdty: 金币+1, 欢迎常来 2012-04-24 13:54:50
myw052: 金币+7, ★★★★★最佳答案, 您的程序写的很好,矢量化确实很厉害。 2012-04-24 18:52:29
把规模改小了,方便对比测试
CODE:
tic
clc
clear
close all
beta=rand(10,10,10);
gama=rand(10,10,10);

[Row,Column,Volume]=size(beta);
gama_u=rand(1,1);
m=2;

D=zeros(size(beta));

for k=1:Volume                    
    for i=1:Row                    
        for j=1:Column               
            D(i,j,k)=beta(i,j,k)/(beta(i,j,k)+(1-beta(i,j,k))*(gama(i,j,k)-(gama(i,j,k)/gama_u)^m)/(gama(i,j,k)-1));
        end
    end
end

D
toc

tic
D_vectorized = beta ./ ( beta + (ones(size(beta)) - beta) .* (gama-(gama/gama_u).^m) ./ (gama - ones(size(gama))) )
toc

2楼2012-04-24 10:42:35
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

sudo

木虫 (正式写手)

这就是传说中的矢量化
3楼2012-04-24 10:43:24
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

lijie169

铜虫 (著名写手)

【答案】应助回帖


感谢参与,应助指数 +1
myw052: 金币+1, 嗯,这个道理我还是懂的。只是对于高维数组有时候想要实现比较麻烦。 2012-04-24 18:56:50
matlab上说 矩阵运算比for循环高效很多
4楼2012-04-24 12:24:47
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

zhfzh

木虫 (正式写手)

你拭下用矢量化计算
就是把for,end去了,常数乘个同维度的单位阵,所有的乘除号前加点
还有你算beta,gamma的时候不要重复调用,用个临时变量存起来
还慢的话你用C语言写吧
5楼2012-04-24 12:31:51
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

zhfzh

木虫 (正式写手)

【答案】应助回帖


感谢参与,应助指数 +1
myw052: 金币+1 2012-04-24 18:56:17
你拭下用矢量化计算
就是把for,end去了,常数乘个同维度的单位阵,所有的乘除号前加点
还有你算beta,gamma的时候不要重复调用,用个临时变量存起来
还慢的话你用C语言写吧
6楼2012-04-24 12:32:12
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

lurencyj

木虫 (著名写手)

【答案】应助回帖


感谢参与,应助指数 +1
myw052: 金币+1, 感谢您的帮助。 2012-04-24 18:57:04
楼主可以尝试使用matlab里面的冒号。可以极大的提高程序的效率,避免低效的for和while循环。
很女子很弓虽大
7楼2012-04-24 16:41:34
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

myw052

金虫 (正式写手)

博士

引用回帖:
7楼: Originally posted by lurencyj at 2012-04-24 16:41:34:
楼主可以尝试使用matlab里面的冒号。可以极大的提高程序的效率,避免低效的for和while循环。

我的理解,冒号操作,只是产生数组。譬如N=-1:0.1:1
能避免for循环么?
lurencyj能否给一个小例子验证下。。。
天天快乐
8楼2012-04-24 18:55:04
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

myw052

金虫 (正式写手)

博士

引用回帖:
6楼: Originally posted by zhfzh at 2012-04-24 12:32:12:
你拭下用矢量化计算
就是把for,end去了,常数乘个同维度的单位阵,所有的乘除号前加点
还有你算beta,gamma的时候不要重复调用,用个临时变量存起来
还慢的话你用C语言写吧

嗯,你的方法跟前面sudo说的一样。C很久不用了,生疏了。
天天快乐
9楼2012-04-24 18:56:10
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

lurencyj

木虫 (著名写手)

【答案】应助回帖

CODE:
A = rand(4,4);

B = ones(4,1);

B(:) = sin(A(:,1))

B(:) = sin(A(:,2))

[ 发自手机版 http://muchong.com/3g ]
很女子很弓虽大
10楼2012-04-24 19:15:53
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
相关版块跳转 我要订阅楼主 myw052 的主题更新
信息提示
请填处理意见