如何优化从3D矩阵生成线性索引的matlab函数

如何优化从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*

我用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*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下运行这段代码时,大多数时候