Trova la potenza della matrice


9

Problema

Creare un programma o una funzione in grado di calcolare il risultato di una matrice elevato alla n esima potenza. Il codice prenderà una matrice quadrata arbitraria A e un numero intero non negativo n , e restituirà una matrice con il valore A n .

restrizioni

Le funzioni integrate che calcolano la potenza della matrice e il prodotto della matrice non sono consentite.

Si applicano le regole standard per il code-golf.

Spiegazione

Data una matrice quadrata A , il valore di A n = AA ⋯ A (prodotto a matrice ripetuta di A con se stesso, n volte). Se n è positivo, viene utilizzato lo standard appena menzionato. Quando n è zero, la matrice identità con lo stesso ordine di A è il risultato.

Obbiettivo

Questo è code-golf e vince il codice più corto.

Casi test

Qui, A è la matrice di input, n è l'intero di input e r è la matrice di output in cui 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

3
Che dire di built-in per prodotto matrice o inversione di matrice?
Dennis,

@Dennis Stavo pensando di vietare anche quelli, ma sembrava troppo restrittivo.
miglia

2
Per le lingue senza inversione di matrice incorporata, questo mi sembra una sfida camaleontica perché invertire una matrice da zero sembra molto più difficile che prendere il prodotto ripetuto.
xnor

2
Sono d'accordo con @xnor. E se una lingua non ha inversione di matrice ma ha un potere di matrice? Può A^-1essere usato come sostituto di inv(A)?
Luis Mendo,

1
È exp(k*log(M))permesso? (Anche se potrebbe non funzionare a causa di rami non unici.)
xnor

Risposte:


4

Gelatina , 17 16 15 byte

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

Provalo online!

Permalink con output di griglia: test case 1 | test case 2 | test case 3 | test case 4 | test case 5

Come funziona

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.

5

MATL , 20 byte

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

Provalo online!

Spiegazione

Ciò evita la moltiplicazione della matrice eseguendola manualmente, utilizzando la moltiplicazione in termini di elementi con trasmissione seguita da somma vettoriale. In particolare, per moltiplicare le matrici Me N, entrambe le dimensioni s × s :

  1. Trasposizione M. Chiama la matrice risultante P.
  2. Consentire le dimensioni di Ntale N"giro" con un asse di rotazione lungo la prima dimensione, dando un array 3D s × 1 × s , diciamo Q.
  3. Moltiplica ogni elemento di Pvolte ogni elemento di Q, con trasmissione implicita. Ciò significa che Pviene replicato automaticamente s volte lungo la terza dimensione, e Qviene replicato s volte lungo la seconda, per renderli entrambi s × s × s , prima che avvenga la moltiplicazione effettiva dal punto di vista degli elementi.
  4. Somma lungo la prima dimensione per produrre un array 1 × s × s .
  5. Premere la dimensione singleton principale per produrre un risultato s × s .

Codice commentato:

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

Non riesce a 0 ....
CalculatorFeline

@CatsAreFluffy Grazie! Corretto
Luis Mendo,

3

APL, 32 31 caratteri

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

A sinistra argomento il potere di sollevare, a destra argomento la matrice. Il bit più difficile (che richiede più spazio) sta costruendo la matrice identità per il caso in cui l'esponente desiderato è 0. Il calcolo effettivo si basa sul fatto che il prodotto interno generalizzato ( .) con +e ×come operandi è effettivamente il prodotto matrice. Questo combinato con l' operatore di potenza ("ripeti") costituisce la carne della soluzione.


1: Sei LO Stefano che ha battuto Dan e Nick di un byte nel gioco dell'anno 2016 ?! 2. (1+≢⍵)↑1=> 1↑⍨1+≢⍵per salvare un byte.
Zacharý,

Si sono io.
lstefano,

2

Sage, 112 byte

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)))

Provalo online

Spiegazione:

La lambda interna ( lambda A,B:[[sum(map(mul,zip(a,b)))for b in zip(*B)]for a in A]) è un'implementazione diretta della moltiplicazione di matrici. La lambda esterna ( lambda A,n:reduce(...,[A]*n,identity_matrix(len(A)))) usa reduceper calcolare la potenza della matrice mediante la moltiplicazione della matrice iterata (usando la funzione di moltiplicazione della matrice fatta in casa sopra menzionata), con la matrice di identità come valore iniziale da supportare n=0.


2

Julia, 90 86 68 byte

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

Questa è una funzione ricorsiva che accetta una matrice ( Array{Int,2}) e un numero intero e restituisce una matrice.

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

Provalo online! (include tutto tranne l'ultimo caso di test, che è troppo lento per il sito)

Risparmiato 18 byte grazie a Dennis!


2

Python 2.7, 158 145 byte

La risposta peggiore qui, ma il mio miglior golf in Python ancora. Almeno è stato divertente imparare a fare la moltiplicazione di matrici.

golfed:

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]

Spiegazione:

#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]

1

JavaScript (ES6), 123 byte

(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

Avevo una versione da 132 byte che utilizzavo reducema stavo mappando acosì spesso che si è rivelato essere 9 byte più corto per scrivere una funzione di supporto per farlo per me. Funziona creando la matrice identità e moltiplicandola per tempi alunghi n. Esistono un numero di espressioni che restituiscono 0o 1per i == jma sembrano tutte lunghe 7 byte.



1

R, 49 byte

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

Funzione ricorsiva che richiede un matrix e il potere ndi elevarlo. Chiamate in modo ricorsivo %*%, che calcola il punto-prodotto. Il valore iniziale per la ricorsione è la matrice identità della stessa dimensione di m. Da allora m %*% m = m %*% m %*% I, questo funziona bene.


0

Python 2 , 131 byte

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))]

Provalo online!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.