คำนวณผลรวม Kronecker ของสองเมทริกซ์


9

ในตัวอย่างด้านล่างAและBจะเป็นเมทริกซ์แบบ 2 ต่อ 2 และเมทริกซ์จะถูกจัดทำดัชนีแบบหนึ่ง

Kronecker ผลิตภัณฑ์มีคุณสมบัติดังต่อไปนี้:

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)

Kronecker รวมมีคุณสมบัติดังต่อไปนี้:

A⊕B = A⊗Ib + Ia⊗B

IaและIbเป็นเมทริกซ์เอกลักษณ์ที่มีขนาดAและBตามลำดับ AและBเป็นเมทริกซ์จตุรัส โปรดทราบว่าAและBสามารถมีขนาดแตกต่างกัน

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)

กำหนดเมทริกซ์สองตารางAและBคำนวณผลรวม Kronecker ของเมทริกซ์สองค่า

  • 2-by-2ขนาดของการฝึกอบรมจะมีอย่างน้อย ขนาดสูงสุดจะเป็นสิ่งที่คอมพิวเตอร์ / ภาษาของคุณสามารถจัดการได้ตามค่าเริ่มต้น แต่5-by-5อินพุตขั้นต่ำ(เอาต์พุต 5 MB)
  • ค่าอินพุตทั้งหมดจะเป็นจำนวนเต็มไม่เป็นลบ
  • ไม่อนุญาตให้ใช้ฟังก์ชันในตัวที่คำนวณผลรวม Kronecker หรือผลิตภัณฑ์ Kronecker
  • โดยทั่วไป: กฎมาตรฐานที่เกี่ยวข้องกับรูปแบบ I / O โปรแกรมและฟังก์ชั่นช่องโหว่ ฯลฯ

กรณีทดสอบ:

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

คำตอบ:


2

เยลลี่ , 26 21 20 19ไบต์

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

อินพุตเป็นรายการสองรายการ 2D เอาต์พุตเป็นรายการ 2D เดียว ลองออนไลน์! หรือตรวจสอบกรณีทดสอบทั้งหมด

มันทำงานอย่างไร

æ*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.

ยูโรจำนวนมาก ... โปรแกรมของคุณรวย!
Luis Mendo

5

CJam, 40 39 38 ไบต์

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

รูปแบบอินพุตเป็นรายการที่มีAและBเป็นรายการ 2D เช่น

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

รูปแบบผลลัพธ์เป็นรายการ 2D แบบ CJam เดียว

ชุดทดสอบ (พร้อมรูปแบบเอาต์พุตที่อ่านได้มากขึ้น)

คำอธิบาย

รหัสนี้เป็นแบบฝึกหัดในตัวดำเนินการผสม (หรือใส่) โดยทั่วไปสิ่งเหล่านี้มีประโยชน์สำหรับการจัดการอาเรย์ แต่ความท้าทายนี้ทำให้ความต้องการของพวกเขาแย่ลง นี่คือภาพรวมอย่างรวดเร็ว:

  • fคาดหวังรายการและอย่างอื่นในสแต็กและแมปตัวดำเนินการไบนารีต่อไปนี้เหนือรายการโดยส่งผ่านอิลิเมนต์อื่นเป็นอาร์กิวเมนต์ที่สอง เช่น[1 2 3] 2 f*และทั้งสองให้2 [1 2 3] f* [2 4 6]หากองค์ประกอบทั้งสองเป็นลิสต์องค์ประกอบแรกจะถูกแมปผ่านและองค์ประกอบที่สองจะถูกใช้เพื่อล้างข้อมูลโอเปอเรเตอร์ไบนารี
  • :มีสองใช้: หากผู้ประกอบการต่อไปนี้มันเป็น unary นี่เป็นแผนที่ง่าย ๆ เช่น[1 0 -1 4 -3] :zคือ[1 0 1 4 3]ที่zได้รับโมดูลัสของจำนวน หากโอเปอเรเตอร์ที่ตามมาเป็นไบนารี่จะเป็นการพับโอเปอเรเตอร์แทน เช่น[1 2 3 4] :+คือ10เป็น
  • .vectorises ตัวดำเนินการไบนารี คาดว่าจะมีสองรายการเป็นอาร์กิวเมนต์และใช้โอเปอเรเตอร์กับคู่ที่สอดคล้องกัน เช่นให้[1 2 3] [5 7 11] .*[5 14 33]

โปรดทราบว่า:ตัวเองอยู่เสมอผู้ประกอบการเอกภาคในขณะที่fและ.ตัวเองอยู่เสมอผู้ประกอบการไบนารี สิ่งเหล่านี้สามารถซ้อนกันได้ตามอำเภอใจ (หากมีสิ่งที่ถูกต้อง) และนั่นคือสิ่งที่เราจะทำ ...

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 เกิดอะไรขึ้นบนโลกนี้ ... ฉันหวังว่าการมีชีวิตรอดของการเล่นกอล์ฟจะช่วยให้คุณอธิบายได้ในที่สุด: P
FryAmTheEggman

@FryAmTheEggman :ffff*อาจจะยาวที่สุด (สารประกอบ) ผู้ประกอบการที่ฉันเคยใช้ใน CJam ... สำหรับหนึ่งมากขึ้นไบต์หนึ่งสามารถไปแม้ crazier แม้ว่า: 9Yb2/Q~f.{\{,,_ff=}&}::ffff*:::.+::~:..+p(และใช่จะเพิ่มคำอธิบายเมื่อฉันเล่นกอล์ฟเสร็จแล้ว)
Martin Ender

4

J - 38 33 31 ไบต์

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

การใช้

   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

การใช้ส่วนเมทริกซ์จะล้มเหลวหากเมทริกซ์ตัวใดตัวหนึ่งเป็นเอกพจน์ ตัวอย่างเช่น(2 2 $ 1 2 3 4) f (2 2 $ 1 1 1 1)จะเพิ่มข้อผิดพลาดของโดเมน
Dennis

@Dennis ? 4 4 $ 100จับที่ดีผมเป็นเพียงการทดสอบกับค่าสุ่ม ฉันไม่แน่ใจว่ามีวิธีที่จะใช้ประโยชน์จากการแต่ง dyad x f&g y = (g x) f (g y)หรืออย่างอื่นที่นี่
ไมล์

2

Julia, 60 59 58 56 ไบต์

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

ลองออนไลน์!

มันทำงานอย่างไร

  • สำหรับการฝึกอบรมและB , คำนวณสินค้า Kronecker A⊗Bmap(a->a*B,A')

    ผลลัพธ์คือเวกเตอร์ของบล็อคเมทริกซ์ที่มีขนาดเป็นB B

    เราต้องแปลงA (กับ') เนื่องจากเมทริกซ์ถูกเก็บไว้ในลำดับคอลัมน์หลัก

  • เนื่องจาก bitwise NOT ที่มีส่วนเติมเต็มของสองเป็นไปตามตัวตน~ n = - (n + 1)สำหรับจำนวนเต็มทั้งหมดnเราจึงมี- ~ -n = - (~ (-n)) = - ((- n) + 1) = 1 - nดังนั้น- ~ -0 = 1และ- ~ -1 = 0

    วิธีนี้ฟังก์ชั่นที่ไม่ระบุชื่อi->map(a->a*B^i,A'^-~-i)ใช้แผนที่ด้านบนเพื่อB⁰ (เมทริกซ์เอกลักษณ์Bมิติ 's) และเน = aเมื่อi = 0และและA⁰เมื่อi = 1

  • sum(i->map(a->a*B^i,A'^-~-i),0:1)จำนวนเงินกว่า{0,1}กับข้างต้นฟังก์ชั่นที่ไม่ระบุชื่อการคำนวณผลรวม Kronecker A⊕Bเป็นA¹⊗B⁰ + A⁰⊗B¹

    ผลที่ได้คือเวกเตอร์ของบล็อกเมทริกซ์ที่มีขนาดของ B

  • sum(A^0)คำนวณผลรวมของรายการทั้งหมดของเมทริกซ์เอกลักษณ์ของมิติข้อมูลของA สำหรับn × nเมทริกซ์อัตราผลตอบแทนนี้n

  • ในที่สุดhvcat(sum(A^0),sum(i->map(a->a*B^i,A'^-~-i),0:1)...)เชื่อมบล็อกเมทริกซ์ที่รวมกันเป็นA⊕B A⊕B

    ครั้งแรกกับการโต้แย้งn , hvcatconcatenates nบล็อกเมทริกซ์ในแนวนอนและส่งผล (ขนาดใหญ่) บล็อกแนวตั้ง


0

ทับทิม, 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)}}}

ในการทดสอบโปรแกรม

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

ต้องใช้สองอาร์เรย์ 2D เป็นอินพุตและส่งคืนอาร์เรย์ 2D

อาจมีวิธีที่ดีกว่าในการทำเช่นนี้: การใช้ฟังก์ชั่นเพื่อหลีกเลี่ยงการทำซ้ำ; ใช้วงเดียวและพิมพ์ผลลัพธ์ จะมองเข้าไปในภายหลัง


0

JavaScript (ES6), 109

สร้างตามคำตอบของความท้าทายอื่น ๆ

(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

ทดสอบ

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>

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.