如何在任何大小的矩阵中制作零菱形?

时间:2016-03-30 18:02:02

标签: matlab

我有一个方形矩阵N x M,奇数尺寸,我想用一个零的菱形,例如,用于5 x 5矩阵:

1 3 2 4 2
5 7 8 9 5
3 2 4 6 3 
6 8 2 1 3 
3 3 3 3 3 

转换为:

1 3 0 4 2 
5 0 8 0 5 
0 2 4 6 0 
6 0 2 0 3
3 3 0 3 3 

如何有效地完成这项工作?

4 个答案:

答案 0 :(得分:2)

我咬了,这是一种方法:

% NxN matrix
N = 5;
assert(N>1 && mod(N,2)==1);
A = magic(N);

% diamond mask
N2 = fix(N/2);
[I,J] = meshgrid(-N2:N2);
mask = (abs(I) + abs(J)) == N2;

% fill with zeros
A(mask) = 0;

结果:

>> A
A =
    17    24     0     8    15
    23     0     7     0    16
     0     6    13    20     0
    10     0    19     0     3
    11    18     0     2     9

答案 1 :(得分:1)

我也有时间玩游戏。对于我的解决方案,没有关于A是奇数,偶数还是大于1的限制。每个整数都很好(即使0有效,但没有意义)。

% NxN matrix
N = 7;
A = magic(N);

half = ceil( N/2 );

mask = ones( half );
mask( 1 : half+1 : half*half ) = 0;
mask = [ fliplr( mask ) mask ];
mask = [ mask; flipud( mask ) ];
if( mod(N,2) == 1 )
    mask(half, :) = []
    mask(:, half) = []
end

A( ~mask ) = 0;
A

我首先创建一个“四分之一”大小的方形子矩阵掩码(列数的一半和行数的一半,ceil()以便在N为奇数的情况下再获得一个)。

N=7 - >的示例half=4

mask =

     1     1     1     1
     1     1     1     1
     1     1     1     1
     1     1     1     1

然后我将它的对角线值设置为零:

mask =

     0     1     1     1
     1     0     1     1
     1     1     0     1
     1     1     1     0

水平镜像遮罩:

mask =

     1     1     1     0     0     1     1     1
     1     1     0     1     1     0     1     1
     1     0     1     1     1     1     0     1
     0     1     1     1     1     1     1     0

然后垂直镜像:

mask =

     1     1     1     0     0     1     1     1
     1     1     0     1     1     0     1     1
     1     0     1     1     1     1     0     1
     0     1     1     1     1     1     1     0
     0     1     1     1     1     1     1     0
     1     0     1     1     1     1     0     1
     1     1     0     1     1     0     1     1
     1     1     1     0     0     1     1     1

由于N很奇怪,我们得到了一个冗余行和冗余列,然后将其删除:

mask =

     1     1     1     0     1     1     1
     1     1     0     1     0     1     1
     1     0     1     1     1     0     1
     0     1     1     1     1     1     0
     1     0     1     1     1     0     1
     1     1     0     1     0     1     1
     1     1     1     0     1     1     1

然后将逻辑not用作掩码,以选择原始矩阵中设置为0的值。

可能不如@ Amro的解决方案效率高,但它确实有效。 :d

答案 2 :(得分:1)

我的解决方案:

查看矩阵的第一个左半部分

    第一行中的
  • 0位于中间列(让我们称之为mc
  • 第二行中的
  • 0位于mc-1
  • 等等,而行增加
  • 当您到达第1列时,序列会继续但mc+1但行减少

对于矩阵的右半部分采用类似的方法

n=7
a=randi([20 30],n,n)
% Centre of the matrix
p=ceil(n/2)
% Identify the column sequence
col=[p:-1:1 2:p p+1:n n-1:-1:p]
% Identify the row sequence
row=[1:n n-1:-1:1]
% Transorm the row and column index in linear index
idx=sub2ind(size(a),row,col)
% Set the 0'
a(idx)=0


a =

    22    29    23    27    27    21    23
    29    29    21    27    24    26    24
    30    28    21    27    29    28    25
    28    22    24    20    27    24    25
    23    26    21    20    30    20    29
    26    20    26    23    25    22    25
    21    24    25    25    23    21    30


a =

    22    29    23     0    27    21    23
    29    29     0    27     0    26    24
    30     0    21    27    29     0    25
     0    22    24    20    27    24     0
    23     0    21    20    30     0    29
    26    20     0    23     0    22    25
    21    24    25     0    23    21    30

希望这有帮助。

Qapla'

答案 3 :(得分:1)

使用索引(仅在N为奇数时才有效):

N = 7;

% Random matrix
A = randi(100, N);

idx = [N-1:-2:1; 2:2:N];
A(cumsum([ceil(N/2) idx(:)' idx(end-1:-1:1)])) = 0

A =

    60    77    74     0    54    83     9
     8    48     0    76     0    28    67
     6     0    32    78    83     0    10
     0    27    25     5    11    39     0
    76     0    49    43    67     0    16
    79     7     0    86     0    70    78
    57    28    85     0    81    44    81