Nos exemplos abaixo, A
e B
serão matrizes 2 por 2 e as matrizes são indexadas um.
Um produto Kronecker possui as seguintes propriedades:
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)
Uma soma Kronecker possui as seguintes propriedades:
A⊕B = A⊗Ib + Ia⊗B
Ia
e Ib
são as matrizes de identidade com as dimensões A
e B
respectivamente. A
e B
são matrizes quadradas. Observe que A
e B
pode ter tamanhos diferentes.
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)
Dadas duas matrizes quadradas A
e B
, calcule a soma Kronecker das duas matrizes.
- O tamanho das matrizes será pelo menos
2-by-2
. O tamanho máximo será o que seu computador / idioma puder manipular por padrão, mas será uma5-by-5
entrada mínima (saída de 5 MB). - Todos os valores de entrada serão números inteiros não negativos
- Funções internas que calculam a soma Kronecker ou produtos Kronecker não são permitidas
- Em geral: Regras padrão em relação ao formato de E / S, programa e funções, brechas etc.
Casos de teste:
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
code-golf
arithmetic
linear-algebra
matrix
Stewie Griffin
fonte
fonte
CJam,
403938 bytesO formato de entrada é uma lista que contém
A
eB
como listas 2D, por exemploO formato de saída é uma única lista 2D no estilo CJam.
Suíte de teste. (Com formato de saída mais legível.)
Explicação
Este código é um exercício para operadores compostos (ou infix). Geralmente são úteis para manipulação de array, mas esse desafio exacerbou a necessidade deles. Aqui está uma rápida visão geral:
f
espera uma lista e mais alguma coisa na pilha e mapeia o seguinte operador binário sobre a lista, passando o outro elemento como o segundo argumento. Por exemplo,[1 2 3] 2 f*
e2 [1 2 3] f*
ambos dão[2 4 6]
. Se ambos os elementos são listas, o primeiro é mapeado e o segundo é usado para curry o operador binário.:
tem dois usos: se o operador a seguir é unário, este é um mapa simples. Por exemplo,[1 0 -1 4 -3] :z
é[1 0 1 4 3]
, ondez
fica o módulo de um número. Se o operador que o segue for binário, o operador será dobrado . Por exemplo,[1 2 3 4] :+
é10
..
vetoriza um operador binário. Ele espera duas listas como argumentos e aplica o operador aos pares correspondentes. Por exemplo,[1 2 3] [5 7 11] .*
dá[5 14 33]
.Note-se que
:
em si é sempre um operador unário, enquanto quef
e.
em si são sempre operadores binários. Eles podem ser aninhados arbitrariamente (desde que tenham as aridades corretas). E é isso que vamos fazer ...fonte
:ffff*
pode ser o operador mais longo (composto) que já usei no CJam ... Por mais um byte, pode-se ficar ainda mais louco:9Yb2/Q~f.{\{,,_ff=}&}::ffff*:::.+::~:..+p
(e sim, adicionará uma explicação quando eu terminar de jogar golfe).J -
383331 bytesUso
fonte
(2 2 $ 1 2 3 4) f (2 2 $ 1 1 1 1)
gerará um erro de domínio.? 4 4 $ 100
. Não tenho certeza se existe uma maneira de usar a composição de díadex f&g y = (g x) f (g y)
ou outra coisa aqui.Julia,
60595856 bytesExperimente online!
Como funciona
Para as matrizes A e B ,
map(a->a*B,A')
calcula o produto Kronecker A⊗B .O resultado é um vector de blocos da matriz com as dimensões de B .
Temos que transpor A (com
'
), pois as matrizes são armazenadas na ordem principal da coluna.Como NOT bit a bit com complemento de dois satisfaz a identidade ~ n = - (n + 1) para todos os números inteiros n , temos que - ~ -n = - (~ (-n)) = - ((- n) + 1) = 1 - n , então - ~ -0 = 1 e - ~ -1 = 0 .
Dessa maneira, a função anônima
i->map(a->a*B^i,A'^-~-i)
aplica o mapa acima a B⁰ (a matriz de identidade com as dimensões de B ) e A¹ = A quando i = 0 , e B¹ e A⁰ quando i = 1 .sum(i->map(a->a*B^i,A'^-~-i),0:1)
soma acima de {0,1} com a função anônima acima, calculando a soma Kronecker A⊕B como A¹⊗B⁰ + A⁰⊗B¹ .O resultado é um vector de blocos da matriz com as dimensões de B .
sum(A^0)
calcula a soma de todas as entradas da matriz de identidade das dimensões de A. Para uma matriz n × n A , isso gera n .Finalmente,
hvcat(sum(A^0),sum(i->map(a->a*B^i,A'^-~-i),0:1)...)
concatena os blocos matriciais que formam A⊕B .Com o primeiro argumento n ,
hvcat
concatena n blocos de matriz horizontalmente e os blocos (maiores) resultantes verticalmente.fonte
Ruby, 102
No programa de teste
Requer duas matrizes 2D como entrada e retorna uma matriz 2D.
Provavelmente, existem maneiras melhores de fazer isso: usar uma função para evitar repetições; usando um único loop e imprimindo a saída. Irá analisá-los mais tarde.
fonte
JavaScript (ES6), 109
Construído sobre a resposta para o outro desafio
Teste
fonte