【问题标题】:seeking a way use non-looping method for calculation in matlab在matlab中寻求一种使用非循环方法进行计算的方法
【发布时间】:2012-05-21 21:48:49
【问题描述】:

我正在将一个 c 程序移植到 matlab 以模拟一些数学问题。我已经在 matlab 中重写了所有代码,但我发现在一个循环中花费了太多时间。我不知道是否有更好的方法来计算以下而不是使用 for 语句

我在一个结构中定义了大约 1000 个矩阵(所有维度都相同)

A{1} = 矩阵1 A{2} = 矩阵2 ... A{1000} = 矩阵1000

B是一个与A{n}维数相同的常数矩阵

我想计算 A{n} 和 B 的逐个元素生成,并将所有结果元素的总和返回给

for k=1:1000
  AllSum(k) = sum(sum(A{k}.*B))
end

A的大小取决于参数,典型大小为300x300。如果我运行一次上述循环,速度还可以。但是该循环将在另一个块中执行,该块将被调用多次,因此需要很长时间才能找到所有总和。我想知道有没有什么办法可以提升它。谢谢

【问题讨论】:

    标签: matlab loops


    【解决方案1】:

    同意您应该使用 3d 矩阵而不是单元格。

    sum of product 让你想起了什么?点积。一系列dot产品让你想起了什么?向量矩阵乘法。所以你想要做的是重塑你的数据,使你的矩阵的每一列都是一个展开的 A{k},你的 B 行向量是你展开的 B 矩阵。换句话说,A 和 B 是 2D 的事实与您的计算无关。

    如果您按照建议将 A 转换为 A(:,:,k) = A{k},则:

    vec = B(:).';
    mtx = reshape(A, size(A,1)*size(A,2), size(A,3));
    AllSum = vec*mtx;
    

    【讨论】:

    • 嗨,彼得,我在 rand 矩阵上尝试了这段代码,它非常快。但我只是忘记了一些我在问题中没有提到的东西(很抱歉)......实际上,A{k} 是一个巨大但稀疏的矩阵,所以如果我们把它做成 3D 矩阵,就会有太多的零反过来最终会大大降低效率。
    【解决方案2】:

    在您的具体情况下,您可以先计算所有A 矩阵的总和,然后乘以B。不要将A 定义为元胞数组,而是将它们定义为一个3d 数组:(我同意@SeçkinSavaşçı)

    A(:,:,i) = ...
    

    代替:

    A{i} = ...
    

    然后,求和并乘以B:

    result = sum(A,3).* B;
    

    【讨论】:

    • 我认为最后一个代码 sn-p 没有做我们想要的事情。它首先对 A 求和,然后与 B 相乘。我们需要将 A 的一部分与 B 相乘(按元素),然后得到这个结果的元素和。
    • @SeçkinSavaşçı,如果我错了,请纠正我,(a1 + a2 + a3) * B 与 a1 * b + a2 * b + a3 * b 相同
    • 你说得对,谢谢你的启发。但是他为数组中的每个 k 存储不同的结果,据我了解,没有累积结果。换句话说,他的结果给了我们 1000 个元素,而你的结果给了 100x100
    • @SeçkinSavaşçı,我认为 OP 的意思是计算单个总和 - 看看他的句子 - “返回所有结果元素的总和”。你说得对,代码 sn-p 照你说的做,但我猜到了他真正想要的。
    猜你喜欢
    • 2016-10-04
    • 1970-01-01
    • 1970-01-01
    • 2021-02-02
    • 2019-03-25
    • 2018-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多