MATLAB:为蒙特卡罗模拟索引一个大矩阵

时间:2012-12-31 16:21:11

标签: matlab indexing

我正在尝试索引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的图像。是否有更快/更聪明/更简单的方法?

提前致谢。

3 个答案:

答案 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包装它。