【问题标题】:How to extract a submatrix without making a copy in Matlab如何在 Matlab 中提取子矩阵而不进行复制
【发布时间】:2016-08-21 01:41:46
【问题描述】:

我有一个大矩阵,我需要从整个大矩阵上运行的滑动窗口中提取一个小矩阵,但是在操作过程中提取的矩阵的内容不会改变,所以我想提取子矩阵而不创建新副本,而是像 C 指针一样指向大矩阵的一部分。我怎样才能做到这一点?请帮帮我,非常感谢:)

【问题讨论】:

  • MATLAB 中没有任何指针,您可以跟踪子矩阵的边界并像这样引用原始矩阵M(rmin:rmax, cmin:cmax)
  • @jodag 但是如果我写 A = M(rmin:rmax, cmin:cmax) 它不会创建一个新矩阵吗?并且写 M(rmin:rmax, cmin:cmax) 有点冗长:(
  • 是的,这将创建一个新矩阵。无论如何,当对子矩阵进行计算时,无论如何都会分配一个新矩阵。 MATLAB 不像 C 那样是一种低级语言,您不能直接控制内存分配。 MATLAB 中没有指针。
  • @jodag 函数句柄怎么样? :(
  • @DangManhTruong 这就是过早优化的定义。

标签: matlab matrix


【解决方案1】:

我做了一些基准测试来测试不使用显式临时矩阵是否更快,但可能不是:

function move_mean(N)
M = randi(100,N);
window_size = [50 50];
dir_time = timeit(@() direct(M,window_size))
tmp_time = timeit(@() with_tmp(M,window_size))
end

function direct(M,window_size)
m = zeros(size(M)./2);
for r = 1:size(M,1)-window_size(1)
    for c = 1:size(M,2)-window_size(2)
        m(r,c) = mean(mean(M(r:r+window_size(1),c:c+window_size(2))));
    end
end
end

function with_tmp(M,window_size)
m = zeros(size(M)./2);
for r = 1:size(M,1)-window_size(1)
    for c = 1:size(M,2)-window_size(2)
        tmp = M(r:r+window_size(1),c:c+window_size(2));
        m(r,c) = mean(mean(tmp));
    end
end
end

M 大小为 100*100:

dir_time =
      0.22739
tmp_time =
      0.22339

所以看起来使用临时变量只会使您的代码可读,而不是变慢。

【讨论】:

  • 其实我觉得你测试的区别在于直接情况下对mean的双重调用,如果你把temp case代码改成mean(mean(tmp)),那就没有区别了跨度>
  • @NoelSegura 你说得对,我太马虎了。编辑了我的答案以纠正这个问题。
【解决方案2】:

在这个答案中,我描述了一般的“最佳”解决方案。对于这个答案,我将“最佳”定义为最易读且不会显着影响性能。 (现有答案部分显示)。

基本上你可能会遇到两种情况。

1。您多次使用子矩阵

在这种情况下,通常最好的解决方案是创建一个包含子矩阵的临时变量。

A = M(rmin:rmax, cmin:cmax)

可能有一些方法可以绕过它(定义一个函数/匿名函数,为您索引到矩阵中),但通常不会让您满意。

2。您只使用了 1 次子矩阵

在这种情况下,最好的解决方案通常正是您在 cmets 中提到的:

M(rmin:rmax, cmin:cmax)

只使用一次子矩阵的一个特定情况是它被传递给一个函数一次。当然,子矩阵的内容可能会在那个函数中多次使用,但这无关紧要。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-14
    • 1970-01-01
    • 1970-01-01
    • 2011-11-12
    • 2015-09-20
    • 2012-04-25
    • 1970-01-01
    • 2012-02-04
    相关资源
    最近更新 更多