Tính tổng Kronecker của hai ma trận


9

Trong các ví dụ dưới đây, ABsẽ là các ma trận 2 nhân 2 và các ma trận được lập chỉ mục một.

Một sản phẩm Kronecker có các thuộc tính sau:

A⊗B =  A(1,1)*B   A(1,2)*B
        A(2,1)*B   A(2,2)*B

     =  A(1,1)*B(1,1)   A(1,1)*B(1,2)   A(1,2)*B(1,1)   A(1,2)*B(1,2)
        A(1,1)*B(2,1)   A(1,1)*B(2,2)   A(1,2)*B(2,1)   A(1,2)*B(2,2)
        A(2,1)*B(1,1)   A(2,1)*B(1,2)   A(2,2)*B(1,1)   A(2,2)*B(1,2)
        A(2,2)*B(2,1)   A(2,2)*B(1,2)   A(2,2)*B(2,1)   A(2,2)*B(2,2)

Một Kronecker sum có các thuộc tính sau:

A⊕B = A⊗Ib + Ia⊗B

IaIblà các ma trận danh tính với kích thước ABtương ứng. ABlà ma trận vuông. Lưu ý rằng ABcó thể có kích cỡ khác nhau.

A⊕B =  A(1,1)+B(1,1)  B(1,2)         A(1,2)         0
        B(2,1)         A(1,1)+B(2,2)  0              A(1,2)
        A(2,1)         0              A(2,2)+B(1,1)  B(1,2)
        0              A(2,1)         B(2,1)         A(2,2)+B(2,2)

Cho hai ma trận vuông ABtính tổng Kronecker của hai ma trận.

  • Kích thước của ma trận sẽ ít nhất 2-by-2. Kích thước tối đa sẽ là bất cứ thứ gì máy tính / ngôn ngữ của bạn có thể xử lý theo mặc định, nhưng 5-by-5đầu vào tối thiểu (đầu ra 5 MB).
  • Tất cả các giá trị đầu vào sẽ là số nguyên không âm
  • Các hàm dựng sẵn tính toán tổng sản phẩm Kronecker hoặc sản phẩm Kronecker không được phép
  • Nói chung: Các quy tắc chuẩn về định dạng I / O, chương trình & chức năng, sơ hở, v.v.

Các trường hợp thử nghiệm:

A =
     1     2
     3     4
B =
     5    10
     7     9

A⊕B =
     6    10     2     0
     7    10     0     2
     3     0     9    10
     0     3     7    13

----

A =
    28    83    96
     5    70     4
    10    32    44
B =
    39    19    65
    77    49    71
    80    45    76

A⊕B =
    67    19    65    83     0     0    96     0     0
    77    77    71     0    83     0     0    96     0
    80    45   104     0     0    83     0     0    96
     5     0     0   109    19    65     4     0     0
     0     5     0    77   119    71     0     4     0
     0     0     5    80    45   146     0     0     4
    10     0     0    32     0     0    83    19    65
     0    10     0     0    32     0    77    93    71
     0     0    10     0     0    32    80    45   120

----

A =
    76    57    54
    76     8    78
    39     6    94
B =
    59    92
    55    29

A⊕B =
   135    92    57     0    54     0
    55   105     0    57     0    54
    76     0    67    92    78     0
     0    76    55    37     0    78
    39     0     6     0   153    92
     0    39     0     6    55   123

Câu trả lời:


2

Thạch , 26 21 20 19 byte

æ*9Bs2¤×€€/€S;"/€;/

Đầu vào là danh sách hai danh sách 2D, đầu ra là danh sách 2D đơn. Hãy thử trực tuyến! hoặc xác minh tất cả các trường hợp thử nghiệm .

Làm thế nào nó hoạt động

æ*9Bs2¤×€€/€S;"/€;/  Main link.
                     Argument: [A, B] (matrices of dimensions n×n and m×m)

      ¤              Evaluate the four links to the left as a niladic chain.
  9B                 Convert 9 to base 2, yielding [1, 0, 0, 1].
    s2               Split into sublists of length 2, yielding [[1, 0], [0, 1]].
æ*                   Vectorized matrix power.
                     This yields [[A¹, B⁰], [A⁰, B¹]], where B⁰ and A⁰ are the
                     identity matrices of dimensions m×m and n×n.
          /€         Reduce each pair by the following:
        €€             For each entry of the first matrix:
       ×                 Multiply the second matrix by that entry.
            S        Sum the two results, element by element.
                     This yields the Kronecker sum, in form of a n×n matrix of
                     m×m matrices.
               /€    Reduce each row of the outer matrix...
             ;"        by zipwith-concatenation.
                     This concatenates the columns of the matrices in each row,
                     yielding a list of length n of n×nm matrices.
                 ;/  Concatenate the lists, yielding a single nm×nm matrix.

Rất nhiều euro ... chương trình của bạn rất phong phú!
Luis Mendo

5

CJam, 40 39 38 byte

9Yb2/q~f{.{_,,_ff=?}:ffff*::.+:~}:..+p

Định dạng đầu vào là danh sách chứa ABdưới dạng danh sách 2D, ví dụ:

[[[1 2] [3 4]] [[5 10] [7 9]]]

Định dạng đầu ra là một danh sách 2D kiểu CJam duy nhất.

Bộ thử nghiệm. (Với định dạng đầu ra dễ đọc hơn.)

Giải trình

Mã này là một bài tập trong các toán tử ghép (hoặc infix). Chúng thường hữu ích cho thao tác mảng, nhưng thách thức này làm trầm trọng thêm sự cần thiết của chúng. Dưới đây là tổng quan nhanh:

  • fmong đợi một danh sách và một cái gì đó khác trên ngăn xếp và ánh xạ toán tử nhị phân sau qua danh sách, chuyển vào phần tử khác làm đối số thứ hai. Vd [1 2 3] 2 f*2 [1 2 3] f*cả hai cho [2 4 6]. Nếu cả hai phần tử là danh sách, phần tử thứ nhất được ánh xạ và phần tử thứ hai được sử dụng để làm cho toán tử nhị phân.
  • :có hai cách sử dụng: nếu toán tử theo sau nó là unary, đây là một bản đồ đơn giản. Ví dụ như [1 0 -1 4 -3] :z[1 0 1 4 3], nơi zđược các mô đun của một số. Nếu toán tử theo sau nó là nhị phân, điều này sẽ gấp toán tử thay thế. Ví dụ như [1 2 3 4] :+10.
  • .véc tơ một toán tử nhị phân. Nó mong đợi hai danh sách làm đối số và áp dụng toán tử cho các cặp tương ứng. Vd [1 2 3] [5 7 11] .*cho [5 14 33].

Lưu ý rằng :bản thân nó luôn là một toán tử đơn nguyên, trong khi đó f.chính chúng luôn là các toán tử nhị phân. Chúng có thể được lồng tùy ý (miễn là chúng có các hương liệu phù hợp). Và đó là những gì chúng ta sẽ làm ...

9Yb      e# Push the binary representation of 9, i.e. [1 0 0 1].
2/       e# Split into pairs, i.e. [[1 0] [0 1]]. We'll use these to indicate
         e# which of the two inputs we turn into an identity matrix.
q~       e# Read and evaluate input, [A B].
f{       e# This block is mapped over the [[1 0] [0 1]] list, also pushing
         e# [A B] onto the stack for each iteration.
  .{     e#   The stack has either [1 0] [A B] or [0 1] [A B]. We apply this
         e#   block to corresponding pairs, e.g. 1 A and 0 B.
    _,   e#     Duplicate the matrix and get its length/height N.
    ,_   e#     Turn into a range [0 1 ... N-1] and duplicate it.
    ff=  e#     Double f on two lists is an interesting idiom to compute an
         e#     outer product: the first f means that we map over the first list
         e#     with the second list as an additional parameter. That means for
         e#     the remaining operator the two arguments are a single integer
         e#     and a list. The second f then maps over the second list, passing
         e#     in the the number from the outer map as the first parameter.
         e#     That means the operator following ff is applied to every possible
         e#     pair of values in the two lists, neatly laid out in a 2D list.
         e#     The operator we're applying is an equality check, which is 1
         e#     only along the diagonal and 0 everywhere else. That is, we've
         e#     created an NxN identity matrix.
    ?    e#     Depending on whether the integer we've got along with the matrix
         e#     is 0 or 1, either pick the original matrix or the identity.
  }
         e#   At this point, the stack contains either [A Ib] or [Ia B]. 
         e#   Note that A, B, Ia and Ib are all 2D matrices.
         e#   We now want to compute the Kronecker product of this pair.
  :ffff* e#   The ffff* is the important step for the Kronecker product (but
         e#   not the whole story). It's an operator which takes two matrices
         e#   and replaces each cell of the first matrix with the second matrix
         e#   multiplied by that cell (so yeah, we'll end up with a 4D list of
         e#   matrices nested inside a matrix).
         e#   The leading : is a fold operation, but it's a bit of a degenerate
         e#   fold operation that is only used to apply the following binary operator
         e#   to the two elements of a list.
         e#   Now the ffff* works essentially the same as the ff= above, but
         e#   we have to deal with two more dimensions now. The first ff maps
         e#   over the cells of the first matrix, passing in the second matrix
         e#   as an additional argument. The second ff then maps over the second
         e#   matrix, passing in the cell from the outer map. We multiply them
         e#   with *.
         e#   Just to recap, we've essentially got the Kronecker product on the
         e#   stack now, but it's still a 4D list not a 2D list.
         e#   The four dimensions are:
         e#     1. Columns of the outer matrix.
         e#     2. Rows of the outer matrix.
         e#     3. Columns of the submatrices.
         e#     4. Rows of the submatrices.
         e#   We need to unravel that into a plain 2D matrix.
  ::.+   e#   This joins the rows of submatrices across columns of the outer matrix.
         e#   It might be easiest to read this from the right:
         e#     +    Takes two rows and concatenates them.
         e#     .+   Takes two matrices and concatenates corresponding rows.
         e#     :.+  Takes a list of matrices and folds .+ over them, thereby
         e#          concatenating the corresponding rows of all matrices.
         e#     ::.+ Maps this fold operation over the rows of the outer matrix.
         e#   We're almost done now, we just need to flatten the outer-most level
         e#   in order to get rid of the distinction of rows of the outer matrix.
  :~     e#   We do this by mapping ~ over those rows, which simply unwraps them.
}
         e# Phew: we've now got a list containing the two Kronecker products
         e# on the stack. The rest is easy, just perform pairwise addition.
:..+     e# Again, the : is a degenerate fold which is used to apply a binary
         e# operation to the two list elements. The ..+ then simply vectorises
         e# addition twice, such that we add corresponding cells of the 2D matrices.
p        e# All done, just pretty-print the matrix.

fffffffffff những gì trên trái đất ... Tôi hy vọng rằng còn sống sót để chơi golf để cuối cùng bạn giải thích nó: P
FryAmTheEggman

@FryAmTheEggman :ffff*có thể là toán tử (hợp chất) dài nhất tôi từng sử dụng trong CJam ... Đối với một byte nữa, người ta có thể thậm chí còn điên hơn: 9Yb2/Q~f.{\{,,_ff=}&}::ffff*:::.+::~:..+p(và vâng, sẽ thêm một lời giải thích khi tôi chơi golf).
Martin Ender

4

J - 38 33 31 byte

i=:=@i.@#
[:,./^:2(*/i)+(*/~i)~

Sử dụng

   f =: [:,./^:2(*/i)+(*/~i)~
   (2 2 $ 1 2 3 4) f (2 2 $ 5 10 7 9)
6 10 2  0
7 10 0  2
3  0 9 10
0  3 7 13
   (3 3 $ 28 83 96 5 70 4 10 32 44) f (3 3 $ 39 19 65 77 49 71 80 45 76)
67 19  65  83   0   0 96  0   0
77 77  71   0  83   0  0 96   0
80 45 104   0   0  83  0  0  96
 5  0   0 109  19  65  4  0   0
 0  5   0  77 119  71  0  4   0
 0  0   5  80  45 146  0  0   4
10  0   0  32   0   0 83 19  65
 0 10   0   0  32   0 77 93  71
 0  0  10   0   0  32 80 45 120
   (3 3 $ 76 57 54 76 8 78 39 6 94) f (2 2 $ 59 92 55 29)
135  92 57  0  54   0
 55 105  0 57   0  54
 76   0 67 92  78   0
  0  76 55 37   0  78
 39   0  6  0 153  92
  0  39  0  6  55 123

Sử dụng phân chia ma trận sẽ thất bại nếu một trong các ma trận là số ít. Ví dụ, (2 2 $ 1 2 3 4) f (2 2 $ 1 1 1 1)sẽ đưa ra một lỗi tên miền.
Dennis

@Dennis bắt tốt, tôi chỉ kiểm tra các giá trị ngẫu nhiên ? 4 4 $ 100. Tôi không chắc có cách nào để sử dụng sáng tác dyad x f&g y = (g x) f (g y)hay cái gì khác ở đây không.
dặm

2

Julia, 60 59 58 56 byte

A%B=hvcat(sum(A^0),sum(i->map(a->a*B^i,A'^-~-i),0:1)...)

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

  • Đối với ma trận AB , hãy map(a->a*B,A')tính sản phẩm Kronecker A⊗B .

    Kết quả là một vector của khối ma trận với kích thước của B .

    Chúng ta phải hoán vị A (với ') vì ma trận được lưu theo thứ tự chính của cột.

  • Vì bitwise KHÔNG với phần bù hai thỏa mãn nhận dạng ~ n = - (n + 1) cho tất cả các số nguyên n , nên chúng ta có - ~ -n = - (~ (-n)) = - ((- n) + 1) = 1 - n , vì vậy - ~ -0 = 1- ~ -1 = 0 .

    Bằng cách này, hàm ẩn danh i->map(a->a*B^i,A'^-~-i)áp dụng bản đồ trên cho B⁰ (ma trận nhận dạng có kích thước của B ) và A¹ = A khi i = 0 và cho A⁰ khi i = 1 .

  • sum(i->map(a->a*B^i,A'^-~-i),0:1)tính tổng {0,1} với hàm ẩn danh ở trên, tính tổng Kronecker A⊕BA¹⊗B⁰ + A⁰⊗B¹ .

    Kết quả là một vector của khối ma trận với kích thước của B .

  • sum(A^0)tính tổng của tất cả các mục trong ma trận danh tính các kích thước của A. Đối với ma trận n × n A , điều này mang lại n .

  • Cuối cùng, hvcat(sum(A^0),sum(i->map(a->a*B^i,A'^-~-i),0:1)...)ghép các khối ma trận tạo thành A⊕B .

    Với đối số thứ nhất n , hvcatnối các khối ma trận n theo chiều ngang và các khối kết quả (lớn hơn) theo chiều dọc.


0

Hồng ngọc, 102

->a,b{r=0..-1+a.size*q=b.size
r.map{|i|r.map{|j|(i/q==j/q ?b[i%q][j%q]:0)+(i%q==j%q ?a[i/q][j/q]:0)}}}

Trong chương trình thử nghiệm

f=->a,b{r=0..-1+a.size*q=b.size
r.map{|i|r.map{|j|(i/q==j/q ?b[i%q][j%q]:0)+(i%q==j%q ?a[i/q][j/q]:0)}}}

aa =[[1,2],[3,4]]
bb =[[5,10],[7,9]]
f[aa,bb].each{|e|p e}
puts

aa =[[28,83,96],[5,70,4],[10,32,44]]
bb =[[39,19,65],[77,49,71],[80,45,76]]
f[aa,bb].each{|e|p e}
puts

aa =[[76,57,54],[76,8,78],[39,6,94]]
bb =[[59,92],[55,29]]
f[aa,bb].each{|e|p e}
puts

Yêu cầu hai mảng 2D làm đầu vào và trả về một mảng 2D.

Có lẽ có nhiều cách tốt hơn để làm điều này: sử dụng một chức năng để tránh lặp lại; sử dụng một vòng lặp duy nhất và in đầu ra. Sẽ xem xét chúng sau.


0

JavaScript (ES6), 109

Được xây dựng dựa trên câu trả lời cho thử thách khác

(a,b)=>a.map((a,k)=>b.map((b,i)=>a.map((y,l)=>b.map((x,j)=>r.push(y*(i==j)+x*(k==l))),t.push(r=[]))),t=[])&&t

Kiểm tra

f=(a,b)=>a.map((a,k)=>b.map((b,i)=>a.map((y,l)=>b.map((x,j)=>r.push(y*(i==j)+x*(k==l))),t.push(r=[]))),t=[])&&t

console.log=x=>O.textContent+=x+'\n'

function show(label, mat)
{
  console.log(label)
  console.log(mat.join`\n`)
}

;[ 
  {a:[[1,2],[3,4]], b:[[5,10],[7,9]]},
  {a:[[28,83,96],[5,70,4],[10,32,44]], b:[[39,19,65],[77,49,71],[80,45,76]]},
  {a:[[76,57,54],[76,8,78],[39,6,94]], b:[[59,92],[55,29]]}
].forEach(t=>{
  show('A',t.a)  
  show('B',t.b)
  show('A⊕B',f(t.a,t.b))
  show('B⊕A',f(t.b,t.a))  
  console.log('-----------------')
})
<pre id=O></pre>

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.