3

我试图在 MATLAB 中索引一个大矩阵,其中包含跨行和跨列单调递增的数字,即如果矩阵被调用A,对于每个(i,j)A(i+1,j) > A(i,j)A(i,j+1) > A(i,j)

我需要创建一个随机数n并将其与矩阵 A 的值进行比较,以查看该随机数应放置在矩阵 A 中的哪个位置。换句话说,n 的值可能不等于矩阵的任何内容,但它可能位于任意两行和任意两列之间,这确定了一个“bin”,该“bin”标识了它在 A 中的位置。一旦找到这个位置,我就会在与 A 大小相同的新矩阵中增加相应的索引.

问题是我想这样做 1,000,000 次。我需要创建一个随机数一百万次,并对这些数字中的每一个进行索引检查。这是从一个点降落在屏幕上的一百万个光子的蒙特卡罗模拟;矩阵 A 由球坐标中的角度组成,随机数是每个入射光子的立体角。

到目前为止,我的代码是这样的(我没有在这里复制粘贴它,因为细节并不重要):

for k = 1:1000000  
    n = rand(1,1)*pi;  
    for i = length(A(:,1))  
        for j = length(A(1,:))  
            if (n > A(i-1,j)) && (n < A(i+1,j)) && (n > A(i,j-1)) && (n < A(i,j+1))  

                new_img(i,j) = new_img(i,j) + 1;   % new_img defined previously as zeros

            end
        end
    end
end

“if”语句只是检查以查找形成 n 边界的 A 的索引。

这工作得很好,但它需要很长时间,特别是因为我的矩阵 A 是尺寸为 11856 x 11000 的图像。有没有更快/更聪明/更简单的方法来做到这一点?

提前致谢。

4

3 回答 3

2

Are the values in A bin edges? Ie does A specify a grid? If this is the case then you can QUICKLY populate A using hist3.

Here is an example: numRand = 1e n = randi(100,1e6,1); nMatrix = [floor(data./10), mod(data,10)];

edges = {0:1:9, 0:10:99};

A = hist3(dataMat, edges);

If your A doesn't specify a grid, then you should create all of your random values once and sort them. Then iterate through those values.

Because you know that n(i) >= n(i-1) you don't have to check bins that were too small for n(i-1). This is a very easy way to optimize away most redundant checks.

于 2012-12-31T16:41:45.530 回答
2

A您可以通过一次对所有元素执行计算来摆脱内部循环。此外,您可以一次创建所有随机数,而不是一次创建一个。请注意,最外面的像素new_img永远不能不为零。

randomNumbers = rand(1,1000000)*pi;
new_img = zeros(size(A));
tmp_img = zeros(size(A)-2);

for r = randomNumbers
    tmp_img = tmp_img + A(:,1:end-2)<r & A(:,3:end)>r & A(1:end-1,:)<r & A(3:end,:)>r;
end

new_img(2:end-1,2:end-1) = tmp_img;

/aside:如果数组更小,我会用于bsxfun比较,但是使用 OP 中的数组大小,该方法会耗尽内存。

于 2012-12-31T16:32:48.393 回答
1

这是一个在内部循环中应该有很大帮助的片段,它会找到比你的value.

idx1 = A<value
idx2 = A(idx1) == max(A(idx1))

如果你想找到确切的位置,你可以用find.

于 2012-12-31T16:36:12.267 回答