如何优化从3D矩阵生成线性索引的matlab函数
我用MATLAB写了一小段代码。这实际上是一个从3D矩阵生成线性索引的函数。这实际上是一个更大项目的一部分。问题是代码可以工作,但没有优化,速度很慢。当我在MATLAB上运行profiler时,90%的计算时间都被这个函数占用了。如何优化此代码如何优化从3D矩阵生成线性索引的matlab函数,matlab,optimization,vectorization,mathematical-optimization,Matlab,Optimization,Vectorization,Mathematical Optimization,我用MATLAB写了一小段代码。这实际上是一个从3D矩阵生成线性索引的函数。这实际上是一个更大项目的一部分。问题是代码可以工作,但没有优化,速度很慢。当我在MATLAB上运行profiler时,90%的计算时间都被这个函数占用了。如何优化此代码 % A = rand(3,3); H = 1200; W = 1500; S = rand(H,W,3,'uint8') R = zeros(H,W,3,'uint8'); lIR = zeros(1,H*W*3); lIC = zeros(1,H*W*
%
A = rand(3,3);
H = 1200;
W = 1500;
S = rand(H,W,3,'uint8')
R = zeros(H,W,3,'uint8');
lIR = zeros(1,H*W*3);
lIC = zeros(1,H*W*3);
count = 0;
for rY = 1:1:H
for rX = 1:1:W
[oX,oY] = func1(rX,rY);
cP = A*[oX; oY; 1];
cP = cP / cP(3);
cX = round(cP(1)); cY = round(cP(2));
if cX < size(S,2) && cX > 1 && cY < size(S,1) && cY > 1
lIR(count+1:count+3) = sub2ind([size(R) 1],[rY rY rY], [rX rX rX],1:3);
lIC(count+1:count+3) = sub2ind([size(S) 1],[cY cY cY],[cX cX cX],1:3);
count = count + 3;
end
end
end
%
function [oX,oY] = func1(rX,rY)
C1 = 1000;
C2 = 1200;
C3 = 1500;
C4 = 1700;
oX = C1 + (C3 - C1) * ((rX - 1) / (W - 1));
oY = C2 + (C4 - C2) * ((rY - 1) / (H - 1));
end
现在代码如下所示:
%
A = rand(3,3);
H = 1200;
W = 1500;
S = rand(H,W,3,'uint8')
R = zeros(H,W,3,'uint8');
lIR = zeros(1,H*W*3);
lIC = zeros(1,H*W*3);
count = 0;
[rX,rY] = meshgrid(1:W,1:H);
[oX,oY] = func1(rX,rY);
for j = 1:1:H
for i = 1:1:W
cP = A*[oX(i); oY(j); 1];
cP = cP / cP(3);
c = round(cP);
if cp(1) < size(S,2) && cp(1) > 1 && cp(2) < size(S,1) && cp(2) > 1
lIR(count+1:count+3) = sub2ind([size(R) 1],[rY rY rY], [rX rX rX],1:3);
lIC(count+1:count+3) = sub2ind([size(S) 1],[cY cY cY],[cX cX cX],1:3);
count = count + 3;
end
end
end
%
function [oX,oY] = func1(rX,rY)
C1 = 1000;
C2 = 1200;
C3 = 1500;
C4 = 1700;
oX = C1 + (C3 - C1) * ((rX - 1) / (W - 1));
oY = C2 + (C4 - C2) * ((rY - 1) / (H - 1));
end
这部分代码仍然非常慢…优化这段代码的最佳方法是将其矢量化,但我现在似乎不知道如何做到这一点,然而,我看到一些有待优化的东西,可能会给你一个小的加速,首先,行
[oX,oY] = func1(rX,rY);
可以从循环中取出并更新func1
,以生成两个矩阵[oX(ry,rj)]和[oY(ry,rj)],然后您只需访问这些值,而不是再次调用func1
,这将消除对func1
的近1800.000次调用所消耗的时间,同时又消耗了大约30 MB的内存(我在matlab中创建了一个1200x1500的随机矩阵,它的大小约为14.4MB)
同样地,这条线
cX = round(cP(1)); cY = round(cP(2));
可能只是
c=round(CP(1:2))
然后,您可以通过c(1)
替换cX
,通过c(2)
替换cY
,再次消除对轮的近180.000次调用
此外,我认为没有必要使用
cX < size(S,2) && cX > 1 && cY < size(S,1) && cY > 1
如果我明天有什么新想法,我现在真的需要睡觉了
干杯优化此代码的最佳方法是将其矢量化,但我现在似乎不知道如何做到这一点,然而,我看到一些有待优化的东西,可能会给您一个小的加速,首先,行
[oX,oY] = func1(rX,rY);
可以从循环中取出并更新func1
,以生成两个矩阵[oX(ry,rj)]和[oY(ry,rj)],然后您只需访问这些值,而不是再次调用func1
,这将消除对func1
的近1800.000次调用所消耗的时间,同时又消耗了大约30 MB的内存(我在matlab中创建了一个1200x1500的随机矩阵,它的大小约为14.4MB)
同样地,这条线
cX = round(cP(1)); cY = round(cP(2));
可能只是
c=round(CP(1:2))
然后,您可以通过c(1)
替换cX
,通过c(2)
替换cY
,再次消除对轮的近180.000次调用
此外,我认为没有必要使用
cX < size(S,2) && cX > 1 && cY < size(S,1) && cY > 1
如果我明天有什么新想法,我现在真的需要睡觉了
Cheers只需使用-一个内置函数,可将下标转换为线性索引
linearInd=sub2ind(数组化,dim1Sub,dim2Sub,dim3Sub,…)
返回与大小为arraySize的N维数组的每个维度的指定下标等效的线性索引。arraySize输入是一个N元素向量,用于指定数组中的维度数。dimNSub输入是正整数标量或向量,用于为数组指定一个或多个行-列下标矩阵
比如说,
A = rand(3, 4, 2);
linearInd = sub2ind(size(A), 2, 1, 2);
linearInd =
14
只需使用-一个将下标转换为线性索引的内置函数
linearInd=sub2ind(数组化,dim1Sub,dim2Sub,dim3Sub,…)
返回与大小为arraySize的N维数组的每个维度的指定下标等效的线性索引。arraySize输入是一个N元素向量,用于指定数组中的维度数。dimNSub输入是正整数标量或向量,用于为数组指定一个或多个行-列下标矩阵
比如说,
A = rand(3, 4, 2);
linearInd = sub2ind(size(A), 2, 1, 2);
linearInd =
14
首先,你可以去掉func1。你可以用
for ox = C1:( (C3-C1)/(W-1) ):C3
oy是类似的
实际上,我想知道在if条件内增加计数器是否是一个错误。因为lIR和lIC中的位置取决于结果。
此外,它是唯一依赖于循环中以前运行的值-如果您消除了这种依赖性,循环可以与parfor一起使用。对于其中一个,您可以消除func1。您可以用
for ox = C1:( (C3-C1)/(W-1) ):C3
oy是类似的
实际上,我想知道在if条件内增加计数器是否是一个错误。因为lIR和lIC中的位置取决于结果。
此外,它是唯一一个依赖于循环中以前运行的值-如果您消除了这种依赖,循环可以与parfor一起使用。您使用的是什么版本的matlab?我使用的是什么版本的matlab?我使用的是matlab 2012。第一点是函数“func1”用于处理每个点,输出是sub2ind的输入。如您所见,我在代码中使用sub2ind,但它是代码中最耗时的部分,应该进行优化。因此问题仍然没有解决。好的,我知道您需要优化的不是
sub2ind
。而是嵌套循环。sub2ind
已经是“矢量化”的,因为它可以获得多于一个点的输入。for循环和if条件需要矢量化。第一个点是函数“func1”用于处理每个点,输出是sub2ind的输入。如您所见,我在代码中使用sub2ind,但它是代码中最耗时的部分,应该进行优化。因此问题仍然没有解决。好的,我知道您需要优化的不是sub2ind
。而是嵌套循环。sub2ind
已经是“矢量的”因为它可以得到一个不止一个点的输入。你的for循环和if条件需要矢量化。谢谢你,伙计,你提到的没问题,但是当我在MATLAB的Profiler下运行这个代码时,最耗时的部分是'sub2ind',这是MATLAB的一个内部函数。实际上我正在考虑替换这个函数谢谢你,伙计,你提到的一切都很好,但是当我在MATLAB的Profiler下运行这段代码时,大多数时候