İki matrisin Kronecker toplamını hesaplayın


9

Aşağıdaki örneklerde Ave B2'ye 2 matris olacak ve matrisler bir indekslenmiştir.

Bir Kronecker ürünü aşağıdaki özelliklere sahiptir:

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)

Bir Kronecker toplamı aşağıdaki özelliklere sahiptir:

A⊕B = A⊗Ib + Ia⊗B

Iave Ibvardır kimlik matrisleri boyutlarında Ave Bsırasıyla. Ave Bkare matrislerdir. Not Ave Bfarklı boyutlarda olabilir.

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)

İki kare matris verilir Ave Biki matrisin Kronecker toplamı hesaplanır.

  • Matrislerin boyutu en azından olacaktır 2-by-2. Maksimum boyut, bilgisayarınızın / dilinizin varsayılan olarak üstesinden gelebileceği her şey olacaktır, ancak minimum 5-by-5giriş (5 MB çıkış).
  • Tüm giriş değerleri negatif olmayan tamsayılar olacaktır
  • Kronecker toplamını veya Kronecker ürünlerini hesaplayan yerleşik işlevlere izin verilmez
  • Genel olarak: G / Ç formatı, program ve fonksiyonlar, boşluklar vb. İle ilgili standart kurallar

Test senaryoları:

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

Yanıtlar:


2

Jöle , 26 21 20 19 bayt

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

Giriş iki 2D listenin bir listesidir, çıkış tek bir 2D listedir. Çevrimiçi deneyin! veya tüm test senaryolarını doğrulayın .

Nasıl çalışır

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

Çok fazla avro ... programınız zengin!
Luis Mendo

5

CJam, 40 39 38 bayt

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

Girdi biçimi, 2B listeler içeren Ave B2B listeler şeklinde bir listedir;

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

Çıktı biçimi, tek bir CJam tarzı 2B listedir.

Test odası. (Daha okunabilir çıkış formatı ile.)

açıklama

Bu kod, bileşik (veya infix) operatörlerinde yapılan bir alıştırmadır. Bunlar genellikle dizi manipülasyonu için kullanışlıdır, ancak bu zorluk bunlara olan ihtiyacı arttırmıştır. İşte hızlı bir genel bakış:

  • fyığında bir liste ve başka bir şey bekler ve diğer ikili öğeyi ikinci bağımsız değişken olarak ileterek , aşağıdaki ikili işleci liste üzerinde eşler . Örneğin [1 2 3] 2 f*ve 2 [1 2 3] f*her ikisi de verir [2 4 6]. Her iki öğe de listeyse, birincisi eşlenir ve ikincisi ikili işleci körelemek için kullanılır.
  • :iki kullanımı vardır: onu izleyen operatör tekli ise, bu basit bir harita. Örneğin [1 0 -1 4 -3] :zolan [1 0 1 4 3]yerlerde, zbir dizi modülünü alır. Bunu izleyen operatör ikili ise, bu olacaktır kat yerine operatörü. Ör [1 2 3 4] :+olduğunu 10.
  • .ikili bir işleci vectorize eder. İki listeyi bağımsız değişken olarak bekler ve operatörü karşılık gelen çiftlere uygular. Örneğin [1 2 3] [5 7 11] .*verir [5 14 33].

Not :kendisi her zaman tekli bir operatördür, oysa fve .kendilerini her zaman ikili operatörler bulunmaktadır. Bunlar keyfi olarak yuvalanabilirler (doğru özelliklere sahip olmaları koşuluyla). Ve biz de bunu yapacağız ...

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 ne yeryüzünde ... Umarım bu golf sonunda hayatta kalır, böylece sonunda
açıklarsınız

@FryAmTheEggman :ffff*, CJam'da şimdiye kadar kullandığım en uzun (bileşik) operatör olabilir ... Bir bayt için daha da çılgınca gidilebilir : 9Yb2/Q~f.{\{,,_ff=}&}::ffff*:::.+::~:..+p(ve evet, golf yaptığımda bir açıklama ekleyeceğim).
Martin Ender

4

J - 38 33 31 bayt

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

kullanım

   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

Matrislerden biri tekil ise, matris bölümünün kullanılması başarısız olacaktır. Örneğin, (2 2 $ 1 2 3 4) f (2 2 $ 1 1 1 1)bir etki alanı hatası ortaya çıkarır.
Dennis

@Dennis iyi yakalama, sadece rastgele değerlere karşı test yapıyordum ? 4 4 $ 100. x f&g y = (g x) f (g y)Burada beste veya başka bir şey kullanmanın bir yolu olup olmadığından emin değilim .
mil

2

Julia, 60 59 58 56 bayt

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

Çevrimiçi deneyin!

Nasıl çalışır

  • Matrisler için A ve B , map(a->a*B,A')Kronecker ürün hesaplar A⊗B .

    Sonuç, B boyutlarına sahip bir matris blokları vektörüdür .

    Matrisleri kolon-ana düzeninde depolandığından A (ile ') devrik yapmalıyız .

  • Yana bitsel DEĞİL ikinin tamamlayıcısı tatmin kimlik ile ~ n = - (n + 1) tüm tamsayılar için n , sahip olduğumuz - ~ -n = - (~ (-n)) = - ((- n) + 1) = 1 - n , yani - ~ -0 = 1 ve - ~ -1 = 0 .

    Bu şekilde anonim işlev i->map(a->a*B^i,A'^-~-i)için yukarıdaki ilk geçerli B⁰ (kimlik matrisi B 'nin boyutları) ve ¹ = A i = 0 , ve ve A⁰ zaman i 1 = .

  • sum(i->map(a->a*B^i,A'^-~-i),0:1)Kronecker toplamı A⊕B'yi A¹⊗B⁰ + A⁰⊗B¹ olarak hesaplayarak yukarıdaki anonim işlevle {0,1} 'in üzerinde toplamlar .

    Sonuç, B boyutlarına sahip bir matris blokları vektörüdür .

  • sum(A^0)A'nın boyutlarının kimlik matrisinin tüm girdilerinin toplamını hesaplar . Bir n × n matrisi A için bu, n verir .

  • Son olarak, A⊕B'yihvcat(sum(A^0),sum(i->map(a->a*B^i,A'^-~-i),0:1)...) oluşturan matris bloklarını birleştirir .

    İlk bağımsız değişken ile , n , hvcatbitiştirir n yatay matris blokları ve dikey olarak elde edilen (daha büyük) blok.


0

Ruby, 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)}}}

Test programında

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

Giriş olarak iki 2B dizi gerektirir ve bir 2B dizi döndürür.

Muhtemelen bunu yapmanın daha iyi yolları vardır: tekrardan kaçınmak için bir işlev kullanmak; tek bir döngü kullanarak ve çıktı yazdırmak. Onlara sonra bakacağım.


0

JavaScript (ES6), 109

Diğer zorluğun cevabı üzerine inşa edildi

(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

Ölçek

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>

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.