如何尽快生成定制的棋盘格?

时间:2016-02-07 22:45:32

标签: matlab matrix

我需要一个能够创建一个棋盘格矩阵的函数,其中M行和N列为P*Q个矩形。我修改了here中的第三个解决方案来获得:

function [I] = mycheckerboard(M, N, P, Q)
nr = M*P;
nc = N*Q;
i = floor(mod((0:(nc-1))/Q, 2));
j = floor(mod((0:(nr-1))/P, 2))';
r = repmat(i, [nr 1]);
c = repmat(j, [1 nc]);
I = xor(r, c);

它没有问题:

I=mycheckerboard(2, 3, 4, 3)

I =
 0 0 0 1 1 1 0 0 0
 0 0 0 1 1 1 0 0 0
 0 0 0 1 1 1 0 0 0
 0 0 0 1 1 1 0 0 0
 1 1 1 0 0 0 1 1 1
 1 1 1 0 0 0 1 1 1
 1 1 1 0 0 0 1 1 1
 1 1 1 0 0 0 1 1 1

但它不够快,因为在一次运行中有很多这个函数的调用。有更快的方法来获得结果吗?如何删除floor函数的浮点除法和/或调用?

2 个答案:

答案 0 :(得分:4)

对于小型矩阵,您的代码速度相当快,但随着尺寸变大,代码变得越来越小。这是使用bsxfunimresize的单线程(大多数都需要图像处理工具箱):

m = 2;
n = 3;
p = 4;
q = 3;

I = imresize(bsxfun(@xor, mod(1:m, 2).', mod(1:n, 2)), [p*m q*n], 'nearest')

或者,受@ AndrasDeak使用kron的启发,R2015b的速度更快:

I = kron(bsxfun(@xor, mod(1:m, 2).', mod(1:n, 2)), ones(p, q))

为了更快一点,可以通过利用问题的结构简化kron的基础代码:

A = bsxfun(@xor, mod(1:m, 2).', mod(1:n, 2));
A = permute(A, [3 1 4 2]);
B = ones(q, 1, p);
I = reshape(bsxfun(@times, A, B), [m*n p*q]);

或作为一个(长)行:

I = reshape(bsxfun(@times, permute(bsxfun(@xor, mod(1:m, 2).', mod(1:n, 2)), [3 1 4 2]), ones(q, 1, p)), [m*n p*q]);

答案 1 :(得分:3)

我建议首先为棋盘的字段创建一个二进制矩阵,然后使用内置的kron将其炸成必要的大小:

M = 2;
N = 3;
P = 4;
Q = 3;
[iM,iN] = meshgrid(1:M,1:N);
A = zeros(M,N);
A(mod(iM.'+iN.',2)==1) = 1;
board = kron(A,ones(P,Q))