列的块对角矩阵


16

灵感来自于Stack Overflow的此问题

给定一个矩阵A,创建一个矩阵B,使的列A以块对角线的方式排列。例如,给定

1 2 3
4 5 6

输出将是

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

规则

输入和输出可以采用2D数组,嵌套数组或具有不同行和列分隔符的字符串的形式。

输入(matrix A)中的数字将为正整数。

一元格式是允许的,只要以某种合理的方式在输出中显示零即可。例如,可以使用引号将每个数字括起来显示上述结果:

'1' '' ''
'1111' '' ''
'' '11' ''
'' '11111' ''
'' '' '111'
'' '' '111111'

测试用例

输入输出:

1 2 3
4 5 6

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


10 20

10  0
 0 20    


10
20

10
20


  1   2   3
 10  20  30
100 200 300

  1   0   0
 10   0   0
100   0   0
  0   2   0
  0  20   0
  0 200   0
  0   0   3
  0   0  30
  0   0 300

 2  4
 6  8
10 12

 2  0
 6  0
10  0
 0  4
 0  8
 0 12

A中的所有数字都会不同吗?
亚当

@Nᴮᶻ不,他们可以相等
Luis

Answers:


7

MATL,6个字节

"@N$Yd

在语言/编译器的当前版本(13.0.0)中工作。

输入具有以下形式,其中以分号作为行分隔符,并在每行内用逗号或空格作为列分隔符:

[1, 2, 3; 4, 5, 6]

在线尝试!

说明

"         % implicitly input 2D array and loop over its columns
  @       %   push column
  N$Yd    %   build block-diagonal matrix from all stack contents. Stack contents are
          %   a single column in the first iteration, or a partially built 2D array
          %   and a new column in all other iterations
          % end loop
          % implicit display

工作的例子

考虑输入[1 2 3; 4 5 6]。以for开头的for循环"接受输入的每一列。在每次迭代中,@将当前列压入堆栈。因此,在第一个迭代中它推送了[1; 4]N$指定所有堆栈内容都将用作以下函数的输入Yd

此函数(对应于MATLAB blkdiag)“对角连接”其输入以生成块对角矩阵(2D数组)。因此,在第一次迭代中,Yd它接受一个输入,并产生与该输入相等的输出,该输出[1; 4]保留在堆栈中。

在第二次迭代中,输入的第二列[2; 5]推送。现在Yd取两个2×1输入,即[1; 4][2; 5],并产生4×2数组[1 0; 4 0; 0 2; 0 5]

在第三次迭代中,Yd获取后者的4×2数组和输入的第三列[3; 6],并产生最终结果[1 0 0; 4 0 0; 0 2 0; 0 5 0; 0 0 3; 0 0 6]


3

ES6,65个字节

a=>[].concat(...a[0].map((_,i)=>a.map(b=>b.map((c,j)=>i-j?0:c))))

将输入数组作为输入并返回输出。


1
@WashingtonGuedes内部映射返回原始2D数组的副本,其中除一列外的所有列均被清零。然后需要将这些副本连接起来,而不仅仅是外部3​​D数组的元素。
尼尔

3

Mathematica,40 39字节

感谢@Seeq for Infixing Flatten

Transpose[DiagonalMatrix/@#]~Flatten~1&

输入是由{}方括号定界的行向量的列表。因此,最初的示例由

{{1,2,3},{4,5,6}}

DiagonalMatrix从输入的行生成一个数组,其中每个数组都有对角线元素(3-D数组)。Transpose因此该Flatten操作会删除正确的括号对,以提供所需的矩阵(现在为二维数组)。


1
不行DiagonalMatrix/@#吗 并且,通过扩展,Transpose[DiagonalMatrix/@#]~Flatten~1&
seequ '16

很好,我打算在汇总后解决此问题。没想到使用Infix Flatten。+1。
IPoiler '16


1

果冻,13个字节

ZLR’×L0ẋ;"Zz0

在线尝试!

怎么运行的

ZLR’×L0ẋ;"Zz0  Main link. Input: M (matrix)

Z              Transpose M.
 L             Get the length of the result. This yields the number of M's columns.
  R            Range; for m columns, yield [1, ..., m].
   ’           Decrement to yield [0, ..., m-1].
    ×L         Multiply each by the length (number of rows) of M.
               This yields [0, n, ..., n(m-1)], where n is the number of rows.
      0ẋ       Push a list of lists of zeroes.
               First element is [], last is n(m-1) zeroes.
        ;"Z    Prepend the kth vector of zeroes to the kth column of M.
           z0  Zip, filling the non-rectangular 2D array with zeroes.

1

Mathematica,111个字节

Join@@@ReplacePart[Table[0,#2/#3]~Table~#3~Table~#3,Table[{n,n}->#[[n]],{n,#3}]]&[Length@#,Length@Flatten@#,#]&

输入语法是什么?这将引发TablePart在混合尺寸的阵列使用标准MMA矩阵符号和结果时的错误。
IPoiler '16

1

红宝石,81岁 78 76 62字节

->a{i=-1;a[0].flat_map{i+=1;a.map{|b|x=b.map{0};x[i]=b[i];x}}}

感叹指数的手动保持跟踪比短with_index

->a{
i=-1;            # index of the flat_map
a[0]             # duplicate all rows as many times as necessary
.flat_map{       # we're wrapping each "group" of original rows with yet another
                 #  array, so we need to flat_map to get rid of those
i+=1;            # increment the index of the current subarray
a.map{|b|        # for each sub-subarray (these are the rows)...
x=b.map{0};      # zero everything out
x[i]=b[i];       # replace the desired elements
x}}}             # finally, return the modified array

1

R,41个字节

pryr::f(Matrix::.bdiag(plyr::alply(a,2)))

假设 pryrMatrixplyr安装包。

这将创建一个采用2D数组(a)并返回“ sparseMatrix”的函数,其中(其中0表示为 .

(a=matrix(1:6,ncol=3))
#      [,1] [,2] [,3]
# [1,]    1    3    5
# [2,]    2    4    6
pryr::f(Matrix::.bdiag(plyr::alply(a,2)))(a)
# 6 x 3 sparse Matrix of class "dgTMatrix"
#          
# [1,] 1 . .
# [2,] 2 . .
# [3,] . 3 .
# [4,] . 4 .
# [5,] . . 5
# [6,] . . 6

说明:

plyr::alply(a,2) 每列 a和返回的将这些结果组合在一个列表中

Matrix::.bdiag(lst) 从矩阵列表创建块对角矩阵

pryr::f 是创建函数的简便方法。

一个完整的基本R解决方案,为59个字节(使用@PieCot的Matlab答案的逻辑):

function(a){l=dim(a);diag(l[2])%x%matrix(1,nrow=l[1])*c(a)}

1

MATLAB,69 68字节

   function h=d(a)
   [r,c]=size(a);h=repmat(a,c,1).*kron(eye(c),~~(1:r)')

减少了一个字节:感谢Luis Mendo :)


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.