【问题标题】:Vectorize for cell array assignment: How to avoid multiple for loop or nested for loop?Vectorize for cell array assignment:如何避免多个 for 循环或嵌套 for 循环?
【发布时间】:2017-01-01 13:23:00
【问题描述】:

在 MATLAB 中,我有 c 是之前计算的一个大型稀疏矩阵,我想通过使用 c 列的外积将值分配给单元格数组 D。但是,我必须实施特殊规则,并且无法获得相同 c 列的外部产品。

使用第一个 for 循环从第 1 列开始,我必须实现另一个 for 循环和 if-else 语句(用于“标记”,因为我在第二个 for 循环中增加索引)以避免相同 @987654325 的外部产品@ 列。

最终,在嵌套的 for 循环之后,我想将所有的 D 相加得到一个矩阵 K。这是我的第一个版本和背后的想法:

c = rand(100,100);    
D = cell(1,100);
D{1} = eye(100);
for i = 1:100
        flag = false;
        for z = 2 :100
            j = z-1;
            if j == i
               flag = true;
            end 
            if flag == true
               D{z} = (c(:,j+1)*c(:,i)');
            else 
               D{z} = (c(:,j)*c(:,i)');
            end
        end
         for z = 2 : 100
             K = K + D{z}';
         end
end

我知道如何去除嵌套循环,但反过来我仍然需要在第一层进行多个 for 循环,并且性能不是太强。我一直在考虑使用NDGRIDbsxfun 来执行此操作,但无济于事。

【问题讨论】:

  • 能否为c添加一个示例?
  • @Finn c 是一个 100 x 100 矩阵。它在其他地方计算,其中列是来自另一个矩阵的特征向量。它没有特殊的结构。 (可以是rand(100,100)
  • 能否请您提供更多详细信息:您有一个 100x100 矩阵并希望从中创建 100 个 100x100 矩阵。最后,您想要这 100 个矩阵的总和。总的来说,您希望每个列的乘积之和与其他列相乘,而不是它自己的下一个乘以两次。对吗?
  • @Finn 只是省略了自己,外部产品只完成了一次。因此,在一个循环内加法是 99 次。我想在没有嵌套循环的情况下如何做到这一点。但仍然不是每一个都表现出色。任何像 bsxfun 甚至没有第一个循环的函数都非常感谢。
  • c?i 的值在什么范围内可能有办法,但如果将 99 个值相乘,有些是 e^10,有些是 e^-10,则可能会出现舍入错误,因为双精度

标签: arrays matlab optimization vectorization


【解决方案1】:

好的,我得到了一些东西;您检查要采用哪些向量,然后创建 99 个产品,然后将它们相加。我会得到 99 个向量,将它们相加,然后创建产品,作为 ab+ac=a*(b+c)。在您的代码中,这将使:

c=rand(100,100);
D = cell(1,100);
D{1} = eye(100);
K=zeros(100);
tic
for i = 1:100
        flag = false;
        for z = 2 :100
            j = z-1;
            if j == i
               flag = true;
               FLAGMATRIX(i,j)=true;
            end 
            if flag == true
               D{z} = (c(:,j+1)*c(:,i)');
            else 
               D{z} = (c(:,j)*c(:,i)');
            end
        end
         for z = 2 : 100
             K = K + D{z}';
         end
end
toc
Matrix=zeros(100);
tic
for i=1:100
    %creating 1:100 the vector w/o i
    vector=1:100;
    vector(i)=[];
    %sum up the 2nd dimension
    sumvec=sum(c(:,vector),2);
    Matrix=[Matrix + c(:,i)*sumvec'];
end
toc

您可以在代码中使其更短,但这不会改变性能

Matrix2=zeros(100);
tic
for i=1:100
    sumvec=sum(c(:,[1:i-1 i+1:100]),2);%vector creation + sum
    Matrix2=[Matrix2 + c(:,i)*sumvec'];
end
toc

在我的机器上执行

Elapsed time is 0.527004 seconds.
Elapsed time is 0.006401 seconds.
Elapsed time is 0.007078 seconds.

这可能无关紧要,但你和我在 e-13 部门的成绩有所不同。但是我会争辩说,如果数字来自与总结大致相同的范围,那么我会更接近现实

【讨论】:

    猜你喜欢
    • 2012-06-25
    • 2019-12-26
    • 2021-05-09
    • 2017-08-27
    • 2017-11-11
    • 2023-03-15
    • 2020-05-21
    • 1970-01-01
    • 2021-08-19
    相关资源
    最近更新 更多