Encontre o poder da matriz

9

Problema

Criar um programa ou função que pode calcular o resultado de uma matriz elevada ao n º poder. Seu código utilizará uma matriz quadrada arbitrária A e um número inteiro não negativo n e retornará uma matriz com o valor A n .

Restrições

Funções internas que computam a potência da matriz e o produto da matriz não são permitidas.

O restante das regras padrão para código-golfe se aplica.

Explicação

Dada uma matriz quadrada A , o valor de A n = AA ⋯ A (produto da matriz repetida de A consigo mesmo, n vezes). Se n for positivo, o padrão mencionado acima é usado. Quando n é zero, a matriz de identidade com a mesma ordem de A é o resultado.

Objetivo

Este é o código-golfe e o código mais curto vence.

Casos de teste

Aqui, A é a matriz de entrada, n é o número inteiro de entrada er é a matriz de saída em que r = A n .

n = 0
A = 62 72
    10 34
r =  1  0
     0  1

n = 1
A = 23 61 47
    81 11 60
    42  9  0
r = 23 61 47
    81 11 60
    42  9  0

n = 2
A =  12  28 -26  3
     -3 -10 -13  0
     25  41   3 -4
    -20 -14  -4 29
r = -650 -1052  -766 227
    -331  -517   169  43
     332   469 -1158 -53
    -878  -990   574 797

n = 4
A = -42 -19  18 -38
    -33  26 -13  31
    -43  25 -48  28
     34 -26  19 -48
r = -14606833  3168904 -6745178  4491946
      1559282  3713073 -4130758  7251116
      8097114  5970846 -5242241 12543582
     -5844034 -4491274  4274336 -9196467

n = 5
A =  7  0 -3  8 -5  6 -6
     6  7  1  2  6 -3  2
     7  8  0  0 -8  5  2
     3  0  1  2  4 -3  4
     2  4 -1 -7 -4 -1 -8
    -3  8 -9 -2  7 -4 -8
    -4 -5 -1  0  5  5 -1
r =  39557  24398 -75256 131769  50575   14153  -7324
    182127  19109   3586 115176 -23305    9493 -44754
    146840  31906 -23476 190418 -38946   65494  26468
     42010 -21876  41060 -13950 -55148   19290   -406
     44130  34244 -35944  34272  22917  -39987 -54864
      1111  40810 -92324  35831 215711 -117849 -75038
    -70219   8803 -61496   6116  45247   50166   2109
milhas
fonte
3
E os embutidos para produtos de matriz ou inversão de matriz?
Dennis
@ Dennis Eu estava pensando em banir também, mas parecia muito restritivo.
miles
2
Para idiomas sem inversão de matriz integrada, isso me parece um desafio de camaleão, porque inverter uma matriz do zero parece muito mais difícil do que usar o produto iterado.
Xnor
2
Eu concordo com @xnor. E se uma linguagem não tem inversão matricial, mas tem poder matricial? Pode A^-1ser usado como substituto inv(A)?
18746 Luis Mendo
11
É exp(k*log(M))permitido? (Embora possa não funcionar por causa de ramificações não exclusivas.) #
228

Respostas:

4

Geléia , 17 16 15 bytes

Z×'³S€€
LṬ€z0Ç¡

Experimente online!

Permalinks com saída em grade: caso de teste 1 | caso de teste 2 | caso de teste 3 | caso de teste 4 | caso de teste 5

Como funciona

LṬ€z0Ç¡  Main link. Arguments: A (matrix), n (power)

L        Get the length l of A.
 Ṭ€      Turn each k in [1, ..., l] into a Boolean list [0, 0, ..., 1] of length k.
   z0    Zip; transpose the resulting 2D list, padding with 0 for rectangularity.
         This constructs the identity matrix of dimensions k×k.
     Ç¡  Execute the helper link n times.

Z×'³S€€  Helper link. Argument: B (matrix)

Z        Zip; transpose rows and columns of B.
   ³     Yield A.
 ×'      Spawned multiplication; element-wise mutiply each rows of zipped B (i.e.,
         each column of B) with each row of A.
         This is "backwards", but multiplication of powers of A is commutative.
    S€€  Compute the sum of each product of rows.
Dennis
fonte
5

MATL , 20 bytes

XJZyXyi:"!J2$1!*s1$e

Experimente online!

Explicação

Isso evita a multiplicação da matriz, fazendo-o manualmente, usando a multiplicação por elementos com broadcast seguida pela soma vetorizada. Especificamente, para multiplicar matrizes Me N, ambos de tamanho s × s :

  1. Transpor M. Chame a matriz resultante P.
  2. Permita as dimensões do Nque Né "girado" com um eixo de rotação ao longo da primeira dimensão, fornecendo uma matriz 3D s × 1 × s , digamos Q.
  3. Multiplique cada elemento de Pvezes cada elemento de Q, com transmissão implícita. Isso significa que Pé automaticamente replicado s vezes ao longo da terceira dimensão e Qé replicado s vezes ao longo da segunda, para torná-los ambos s × s × s , antes que ocorra a multiplicação por elementos.
  4. Soma ao longo da primeira dimensão para gerar uma matriz de 1 × s × s .
  5. Esprema a dimensão líder singleton para fora, para produzir uma s × s resultado.

Código comentado:

XJ      % take matrix A. Copy to clipboard J
ZyXy    % generate identity matrix of the same size
i:      % take exponent n. Generate range [1 2 ... n] (possibly empty)
"       % for each element in that range
  !     %   transpose matrix with product accumulated up to now (this is step 1)
  J     %   paste A
  2$1!  %   permute dimensions: rotation along first-dimension axis (step 2)
  *     %   element-wise multiplication with broadcast (step 3)
  s     %   sum along first dimension (step 4)
  1$e   %   squeeze out singleton dimension, i.e. first dimension (step 5)
        % end for. Display
Luis Mendo
fonte
Falha para 0 ....
CalculatorFeline
@CatsAreFluffy Thanks! Corrigido
Luis Mendo
3

APL, 32 31 caracteres

{⍺=0:(⍴⍵)⍴1⍨1+≢⍵⋄+.×⍨⍣(⍺-1)⊣⍵}

Argumento da esquerda o poder de elevar para, argumento da direita a matriz. O bit mais difícil (que consome mais espaço) é criar a matriz de identidade para o caso em que o expoente desejado é 0. O cálculo real é baseado no fato de que o produto interno generalizado ( .) com +e ×como operandos é efetivamente o produto da matriz. Isso combinado com o operador de energia ("repetição") forma a carne da solução.

lstefano
fonte
1: Você é o Stefano que venceu Dan & Nick por um byte no jogo do ano de 2016 ?! 2. (1+≢⍵)↑1=> 1↑⍨1+≢⍵para salvar um byte.
Zacharý 31/07
Sim, sou eu.
lstefano 2/08
2

Sábio, 112 bytes

lambda A,n:reduce(lambda A,B:[[sum(map(mul,zip(a,b)))for b in zip(*B)]for a in A],[A]*n,identity_matrix(len(A)))

Experimente online

Explicação:

O lambda interno ( lambda A,B:[[sum(map(mul,zip(a,b)))for b in zip(*B)]for a in A]) é uma implementação direta da multiplicação de matrizes. O lambda externo ( lambda A,n:reduce(...,[A]*n,identity_matrix(len(A)))) usa reducepara calcular a potência da matriz por multiplicação de matriz iterada (usando a função de multiplicação de matriz caseira mencionada acima), com a matriz de identidade como o valor inicial a ser suportado n=0.

Mego
fonte
2

Julia, 90 86 68 bytes

f(A,n)=n<1?eye(A):[A[i,:][:]⋅f(A,n-1)[:,j]for i=m=1:size(A,1),j=m]

Esta é uma função recursiva que aceita uma matriz ( Array{Int,2}) e um número inteiro e retorna uma matriz.

Ungolfed:

function f(A, n)
    if n < 1
        # Identity matrix with the same type and dimensions as the input
        eye(A)
    else
        # Compute the dot product of the ith row of A and the jth column
        # of f called on A with n decremented
        [dot(A[i,:][:], f(A, n-1)[:,j]) for i = (m = 1:size(A,1)), j = m]
    end
end

Experimente online! (inclui todos, exceto o último caso de teste, que é muito lento para o site)

Economizou 18 bytes graças a Dennis!

Alex A.
fonte
2

Python 2.7, 158 145 bytes

A pior resposta aqui, mas o meu melhor golfe em Python ainda. Pelo menos foi divertido aprender a fazer multiplicação de matrizes.

Golfe:

def q(m,p):
 r=range(len(m))
 if p<1:return[[x==y for x in r]for y in r]
 o=q(m,p-1)
 return[[sum([m[c][y]*o[x][c]for c in r])for y in r]for x in r]

Explicação:

#accepts 2 arguments, matrix, and power to raise to
def power(matrix,exponent):
 #get the range object beforehand
 length=range(len(matrix))
 #if we are at 0, return the identity
 if exponent<1:
  #the Boolean statement works because Python supports multiplying ints by bools
  return [[x==y for x in length] for y in length]
 #otherwise, recur
 lower=power(matrix,exponent-1)
 #and return the product
 return [[sum([matrix[c][y]*lower[x][c] for c in length]) for y in length] for x in length]
Azul
fonte
1

JavaScript (ES6), 123 bytes

(n,a)=>[...Array(n)].map(_=>r=m(i=>m(j=>m(k=>s+=a[i][k]*r[k][j],s=0)&&s)),m=g=>a.map((_,n)=>g(n)),r=m(i=>m(j=>+!(i^j))))&&r

Eu tinha uma versão de 132 bytes em uso, reducemas estava apenas mapeando com atanta frequência que acabou sendo 9 bytes mais curto para escrever uma função auxiliar para fazer isso por mim. Funciona criando a matriz identidade e multiplicando-o por alonghand nvezes. Há várias expressões que retornam 0ou 1para, i == jmas todas parecem ter 7 bytes de comprimento.

Neil
fonte
1

Python 3 , 147 bytes

def f(a,n):
 r=range(len(a));r=[[i==j for j in r]for i in r]
 for i in range(n):r=[[sum(map(int.__mul__,x,y))for y in zip(*a)]for x in r]
 return r

Experimente online!

Freira Furada
fonte
1

R, 49 bytes

f=function(m,n)`if`(n,m%*%f(m,n-1),diag(nrow(m)))

Função recursiva que leva um matrix e o poder nde elevá-lo. Chamadas recursivamente %*%, que calculam o produto escalar. O valor inicial da recursão é a matriz de identidade do mesmo tamanho que m. Desde então m %*% m = m %*% m %*% I, isso funciona muito bem.

JAD
fonte
0

Python 2 , 131 bytes

f=lambda M,n:n and[[sum(map(int.__mul__,r,c))for c in zip(*f(M,n-1))]for r in M]or[[0]*i+[1]+[0]*(len(M)+~i)for i in range(len(M))]

Experimente online!

Arfie
fonte