【问题标题】:Is there a way to make this code faster and if possible avoid loops?有没有办法让这段代码更快,如果可能的话避免循环?
【发布时间】:2015-03-09 17:25:17
【问题描述】:

A1B1C1A2B2C26 矩阵,具有相同的维度 4435X2000

我必须找到 ijk 的值,其中 A1(k,2000) == A2(i,j)B1(k,2000) == B2(i,j)C1(k,2000) == C2(i,j) 条件为 X(k)==1Y(i,j)==1

目标是找到:counterLTD

有没有办法让这段代码更快?我可以避免循环吗?

counter=0;
L(1)=0;
T(1)=0;
D(1)=0;

for k=1:4435
    if X(k)==1      % X is a vector (4435x1)
       F(k,:) = [A1(k,2000) B1(k,2000) C1(k,2000)] 
       for i=1:4435
           for j=100:1999
               if Y(i,j)==1      % Y is a matrix (4435x1999)
                  if F(k,:) == [A2(i,j) B2(i,j) C2(i,j)]
                     counter = counter+1;
                     L(counter)=k;
                     T(counter)=i;
                     D(counter)=j;
                  end 
               end
           end
       end
    end 
end

我想要一个至少能节省 80% 计算时间的解决方案! 并且没有错误消息:内存不足

【问题讨论】:

  • 其中使用的变量的实际数据大小是多少?
  • @Divakar:对于 A1、A2、B1、B2、C1 和 C2:4435x2000
  • if F(k,:) == 可能不是if F(k,:) =?那是一个数组比较,而不是一个标量比较,对吧?
  • @Daniel:是的,X 和 Y 支持向量化操作。
  • 您可以用简单的英语解释一下代码在做什么,而不是向我们展示代码?这样,我们愿意做一些完全不同的事情,我们仍然可以实现您的主要目标。如果我们不局限于优化您的特定做事方法,我们还可以进一步优化您正在做的事情。

标签: performance matlab loops matrix runtime


【解决方案1】:

看看这对你有什么影响 -

%// Store X-Y data by calling X() and Y() functions
X_data = X(1:4435);
Y_data = Y(1:4435,100:1999);

range1 = 100:1999 %// define range for columns
A2 = A2(:,range1); %// Crop out A2, B2, C2 based on column-range
B2 = B2(:,range1);
C2 = C2(:,range1);
Y_data = Y_data(:,range1)==1;

%// Indices for dim-3
idx_X = find(X_data==1) 

%// Map X==1 onto A1, B1, C1
A1Lr = A1(X_data==1,end)
B1Lr = B1(X_data==1,end)
C1Lr = C1(X_data==1,end)

%// Setup output array to store L, T, D as single Nx3 output array
out = zeros(sum(Y_data(:))*numel(A1Lr),3);
%// Try out(sum(Y_data(:)==1)*numel(A1Lr),3)=0; instead for speed!

%// Start collecting output indices
count = 1;
for iter1 = 1:numel(A1Lr)
    [R,C] = find(Y_data & A2==A1Lr(iter1) & B2==B1Lr(iter1) & C2==C1Lr(iter1));
    nR = numel(R);
    out(count:count+nR-1,:) = [R C repmat(iter1,nR,1)];
    count = count + nR;
end
out(find(out(:,1)==0,1):end,:)=[];

%// Packup the outputs
T = out(:,1)
D = out(:,2) + range1(1)-1
L = idx_X(out(:,3))

【讨论】:

  • @bzak Y_data 的大小是多少?
  • 4435x1900 和 range1 : 1x1900
  • @bzak 啊对不起我的错!将该行从 Y_data = Y_data(:,range1)==1; 更改为 Y_data = Y_data==1; 并查看它是否有效?
  • ???错误使用 ==> zeros 内存不足。键入 HELP MEMORY 作为您的选项。错误 ==> out = zeros(sum(Y_data(:))*numel(A1Lr),3);如果你花太多时间在我的问题上,对不起!!!
  • @bzak 没关系,别担心! :) 看看this 是否有效?
【解决方案2】:

如果不真正解释您的代码,就很难确定您的代码实际上应该完成什么。但是,我会试一试:

% Determine where X is true.
XTrue = X == 1;

% Extract values from A1,B1,C1 where X is true.
F ( XTrue , 1 : 3 ) = [ A1(XTrue,2000) B1(XTrue,2000) C1(XTrue,2000) ];

% Determine where Y is true.
YTrueIndex = find ( Y == 1 );

% Determine where the extracted values match
counter = [];
L = [];
T = [];
D = [];

for ( ii = 1 : length(YTrueIndex) )
  indexCurrent = YTrueIndex(ii)
  FRowsThatMatch = F(:,1)==A2(indexCurrent) & F(:,2)==B2(indexCurrent) & F(:,3)==C2(indexCurrent);

  matchCount = length ( find ( FRowsThatMatch ) );

  if ( matchCount > 0 )
    counter = counter + matchCount;

    [ i , j ] = ind2sub ( size ( Y ) , indexCurrent );
    L = [ L , find ( FRowsThatMatch ) ];
    T = [ T , ones(matchCount,1)*i ];
    D = [ D , ones(matchCount,2)*j ];
  end
end

【讨论】:

  • 我必须先用你的答案运行我的程序,然后才能知道它是否有效。通常使用我的代码,我必须等待五个小时才能得到结果!!!
  • 这可能是错误的,但它开始摆脱几个循环。
  • ???错误使用 ==> find 没有足够的输入参数。 ==> L = [ L , 查找 (FRowsThatMatch) ] 中的错误;
  • 这可能是因为间距... MATLAB 在其空白允许方面不一致。查找(FRowsThatMatch)
  • ???使用 ==> horzcat 时出错 内存不足。键入 HELP MEMORY 作为您的选项。 ==> D = [ D , one(matchCount,2)*j ]; 中的错误
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-13
  • 1970-01-01
  • 2020-03-19
  • 1970-01-01
  • 1970-01-01
  • 2020-03-05
  • 1970-01-01
相关资源
最近更新 更多