我需要一个能够创建一个棋盘格矩阵的函数,其中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
函数的浮点除法和/或调用?
答案 0 :(得分:4)
对于小型矩阵,您的代码速度相当快,但随着尺寸变大,代码变得越来越小。这是使用bsxfun
和imresize
的单线程(大多数都需要图像处理工具箱):
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))