在Matlab中生成“修改的”对角矩阵

时间:2018-02-09 18:06:42

标签: matlab

我想在维度A的Matlab中构建一个矩阵w x (m*w),其中

除了m连续ones之外,每一行都是零,当我们向下移动到行时,它会向右侧移动。

很少有例子可以澄清

w=3,m=4
A=[1 1 1 1 0 0 0 0 0 0 0 0;
   0 0 0 0 1 1 1 1 0 0 0 0;
   0 0 0 0 0 0 0 0 1 1 1 1]

w=3, m=3
A=[1 1 1 0 0 0 0 0 0;
   0 0 0 1 1 1 0 0 0;
   0 0 0 0 0 0 1 1 1]

w=2, m=3
A=[1 1 1 0 0 0;
   0 0 0 1 1 1]

我看不清楚如何继续,任何提示都会非常有帮助。

2 个答案:

答案 0 :(得分:6)

步骤1.简化问题

如果您编写“修改后的对角线矩阵”,您会将其视为行向量,它将始终如下所示

% 1 ... 1 0 ... ... 0 ... ... ... ... ... ... ... ... 1 ... 1
% m ones   m*w zeros    w-1 times the same as before   m ones   

步骤2.考虑如何解决简化问题

  1. 您需要的基本单位是m个向量,后跟m*w个零;
  2. 一旦你构建了这样的向量,你需要重复w次,MATLAB已经知道https://xyz.123.com/artifactory/bx-test;
  3. 你唯一遗漏的是尾随的:追加它们;
  4. 现在您要查找的矢量已完成,您需要将其转换为矩阵。 MATLAB也已经知道how to do that
  5. 最终代码

    一旦理解了上述步骤,即使使用单行

    也可以实现最终行为
    >> m = 4; w = 3;
    >> vec2mat([repmat([ones(1, m) zeros(1, m*w)], 1, w-1) ones(1, m)], w*m)
    
    ans =
    
         1     1     1     1     0     0     0     0     0     0     0     0
         0     0     0     0     1     1     1     1     0     0     0     0
         0     0     0     0     0     0     0     0     1     1     1     1
    

    关于速度

    这是真的,因为循环不再那么慢了。我计算了我的单行解决方案,简单的for循环和how to do thiseye()repelem()

    点击图片进行缩放

    Luis Mendo's solution for loop

    for loop 2 my solution

    my solution 2 eye() and repelem()

    使用MATLAB R2018a在同一台机器上测试。

    正如您所看到的,只要mw非常小,即使您可以指出速度上的某些差异,它们也不会被人类注意到。

    无论如何,如果你打算使用更大的矩阵,很明显哪种解决方案是最好的。

答案 1 :(得分:4)

以下是一些方法:

  • 使用eyerepelem

    A = repelem(eye(w), 1, m);
    
  • 使用eye并编制索引:

    A = eye(w);
    A = A(1:w, ceil(1/m:1/m:w));
    
  • 使用eyekron

    A = kron(eye(w), ones(1,m));
    
  • 使用singleton expansion

    A = bsxfun(@eq, (1:m).', ceil(1/m:1/m:w)); % Or A = (1:m).'==ceil(1/m:1/m:w);