我正在尝试索引MATLAB中的一个大矩阵,该矩阵包含跨行和跨列的单调递增的数字,即如果矩阵被称为A
,则每(i,j)
,{{1} }和A(i+1,j) > A(i,j)
。
我需要创建一个随机数A(i,j+1) > A(i,j)
并将其与矩阵A的值进行比较,以查看该随机数应放置在矩阵A中的位置。换句话说,n的值可能不是等于矩阵的任何内容,但它可能位于任意两行和任意两列之间,并确定一个“bin”,用于标识其在A中的位置。一旦找到此位置,我将增加相应的索引与A相同大小的新矩阵。
问题是我想这样做1,000,000次。我需要创建一百万次随机数并对每个数字进行索引检查。这是蒙特卡罗模拟的一百万个光子来自一个登陆屏幕的点;矩阵A由球坐标中的角度组成,随机数是每个入射光子的立体角。
到目前为止我的代码是这样的(我没有在这里复制粘贴,因为细节并不重要):
n
“if”语句只是检查以找到形成n的边界的A的索引。
这种方法非常好,但是它需要非常长,特别是因为我的矩阵A是尺寸为11856 x 11000的图像。是否有更快/更聪明/更简单的方法?
提前致谢。
答案 0 :(得分: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中的数组大小,该方法会耗尽内存。
答案 1 :(得分:2)
A
bin中的值是否边缘?即A
指定网格?如果是这种情况,那么您可以使用hist3
快速填充A.
这是一个例子: numRand = 1e n =兰迪(100,1e6,1); nMatrix = [floor(data./10),mod(data,10)];
edges = {0:1:9, 0:10:99};
A = hist3(dataMat, edges);
如果您的A
未指定网格,则应创建一次所有随机值并对其进行排序。然后迭代这些值。
因为您知道n(i) >= n(i-1)
您不必检查对n(i-1)
来说太小的邮箱。这是优化大多数冗余检查的一种非常简单的方法。
答案 2 :(得分:1)
这是一个应该在内循环中有很多帮助的片段,它会找到小于value
的最大点的位置。
idx1 = A<value
idx2 = A(idx1) == max(A(idx1))
如果您想找到确切的位置,可以使用find
包装它。