将较小的矩阵索引到较大的矩阵的中心

时间:2019-05-16 15:15:32

标签: arrays matlab matrix indexing

我正在尝试以下作为一种业余爱好,而不是家庭作业。我对MATLAB还是陌生的,但对编码的了解却很少。我有一个坚持的问题。它来自使用MATLAB进行计算机编程:J。Michael Fitzpatrick和Akos Ledeckzi

问题10。编写一个名为cancel_middle的函数,该函数需要 A n - m 矩阵作为输入,其中 n m 均为奇数, k 为正 小于 m n 的奇数整数(该函数不必 检查输入)。该函数返回其中心 k k 矩阵清零的输入矩阵。检查以下运行,

>> cancel_middle(ones(5),3)
ans =
 1 1 1 1 1
 1 0 0 0 1
 1 0 0 0 1
 1 0 0 0 1
 1 1 1 1 1

我有一个嵌套的if函数,它将正确执行输入参数,但无法获得所需的输出。我认为这远没有效率,即使书中未涉及if语句,我也正在使用它。那是根据我以前的知识。因此,我认为要编写一个更简单,更有效的函数。

function M = cancel_middle(A,k);

[m,n] = size(A);
if rem([m,n],2) == [1,1]
    if rem(k,2)==1
        if [k,k]<[m,n]
            M = zeros(k);

        else
            fprintf('Error 1: k must be odd and smaller than A\n');
        end
    else
        fprintf('Error 2: k must be odd and smaller than A\n');
    end
else
    fprintf('Error 3: k must be odd and smaller than A\n');
end

我卡住的区域是应该在第8行上的输出参数。我正在正确输出k-by-k矩阵,但是出于明显的原因,它不在较大的矩阵上。我相信我想使用矩阵zeros(k)并将其索引到较大的矩阵A中。我相信我缺少一些关键函数,这些函数也使我不必使用3个if语句,但是我非常不了解

这是我运行函数时的输出:

>> cancel_middle(ones(5),3)
ans =
     0     0     0
     0     0     0
     0     0     0

很明显,这只是zeros(k)的输出。

2 个答案:

答案 0 :(得分:3)

我不知道您是否已经涵盖了MATLAB的 indexing 部分,但如果不是这样,我强烈建议您仔细阅读它们,因为这是MATLAB实力的支柱之一:

一旦理解了这一点,练习就是计算矩阵的哪些索引将被清零。有了索引列表后,将值辅助到位于这些位置的矩阵元素就可以实现单行琐碎分配。

请考虑下面的以下功能(对冗长的变量名表示抱歉,但我试图使其具有说服力)。每行末尾的注释中给出的结果值对于一组示例输入A=ones(5,7)k=3有效:

function M = cancel_middle(A,k)

    % find [m,n] (the size of A)
    [m,n] = size(A) ; % => m=5, n=7

    % calculate the coordinates of the "center" of the matrix
    center_row_idx = (m+1)/2  ; % => center_row_idx = 3
    center_col_idx = (n+1)/2  ; % => center_col_idx = 4

    % how much indices to take on each side of the center
    half_width = (k-1)/2 ;      % => center_row_idx = 3

    % generate the indices which will be zeroed
    row_indices = center_row_idx-half_width:center_row_idx+half_width ; % => row_indices = [2,3,4]
    col_indices = center_col_idx-half_width:center_col_idx+half_width ; % => col_indices = [3,4,5]

    % generate the output matrix M (as a copy of A)
    M = A ;
    % now you can zero the elements of matrix M directly by their indices
    M(row_indices,col_indices) = 0 ;

end

您可以验证:

>> M = cancel_middle(ones(5,7),3)
M =
     1     1     1     1     1     1     1
     1     1     0     0     0     1     1
     1     1     0     0     0     1     1
     1     1     0     0     0     1     1
     1     1     1     1     1     1     1

答案 1 :(得分:2)

您可以对end使用索引分配,如下所示:

A = randi(9,5,7); % example A
k = 3; % example k
t = -(k-1)/2:(k-1)/2;
A((end+1)/2 + t, (end+1)/2 + t) = 0;

示例结果:

A =
     2     5     2     9     3     6     9
     6     3     0     0     0     4     8
     7     7     0     0     0     8     5
     6     2     0     0     0     5     6
     5     7     1     5     8     4     6