Trouvez la puissance de la matrice

9

Problème

Créez un programme ou une fonction qui peut calculer le résultat d'une matrice élevée à la n ème puissance. Votre code prendra une matrice carrée arbitraire A et un entier non négatif n , et renverra une matrice avec la valeur A n .

Restrictions

Les fonctions intégrées qui calculent la puissance matricielle et le produit matriciel ne sont pas autorisées.

Les autres règles standard du code-golf s'appliquent.

Explication

Étant donné une matrice carrée A , la valeur de A n = AA ⋯ A (produit matriciel répété de A avec lui-même, n fois). Si n est positif, la norme qui vient d'être mentionnée est utilisée. Lorsque n est zéro, la matrice d'identité avec le même ordre de A est le résultat.

Objectif

C'est le code-golf et le code le plus court l'emporte.

Cas de test

Ici, A est la matrice d'entrée, n est l'entier d'entrée et r est la matrice de sortie où 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
miles
la source
3
Qu'en est-il des fonctions intégrées pour le produit matriciel ou l'inversion matricielle?
Dennis
@Dennis J'envisageais de les interdire également, mais c'était trop restrictif.
miles
2
Pour les langues sans inversion de matrice intégrée, cela me semble être un défi de caméléon car inverser une matrice à partir de zéro semble beaucoup plus difficile que de prendre le produit itéré.
xnor
2
Je suis d'accord avec @xnor. Et que se passe-t-il si une langue n'a pas d'inversion matricielle mais a une puissance matricielle? Peut A^-1être utilisé comme substitut inv(A)?
Luis Mendo
1
Est exp(k*log(M))autorisé? (Bien que cela puisse ne pas fonctionner en raison de branches non uniques.)
xnor

Réponses:

4

Gelée , 17 16 15 octets

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

Essayez-le en ligne!

Permaliens avec sortie réseau: cas de test 1 | cas de test 2 | cas de test 3 | cas de test 4 | cas de test 5

Comment ça fonctionne

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
la source
5

MATL , 20 octets

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

Essayez-le en ligne!

Explication

Cela évite la multiplication de la matrice en le faisant manuellement, en utilisant la multiplication par élément avec diffusion suivie d'une somme vectorisée. Plus précisément, pour multiplier les matrices Met N, toutes deux de taille s × s :

  1. Transposer M. Appelez la matrice résultante P.
  2. Permutez les dimensions de Ncelles qui Nsont "tournées" avec un axe de rotation le long de la première dimension, donnant un tableau 3D s × 1 × s , par exemple Q.
  3. Multipliez chaque élément de Pfois chaque élément de Q, avec une diffusion implicite. Cela signifie qu'il Pest automatiquement répliqué s fois le long de la troisième dimension, et Qest répliqué s fois le long de la seconde, pour les rendre tous les deux s × s × s , avant que la multiplication réelle par élément n'ait lieu.
  4. Additionnez le long de la première dimension pour obtenir un tableau 1 × s × s .
  5. Pressez la première dimension singleton pour produire un résultat s × s .

Code commenté:

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
la source
Échoue pour 0 ....
CalculatorFeline
@CatsAreFluffy Merci! Corrigé
Luis Mendo
3

APL, 32 31 caractères

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

Argument de gauche le pouvoir d'élever, argument de droite la matrice. Le bit le plus difficile (le plus consommateur d'espace) est la construction de la matrice d'identité pour le cas où l'exposant souhaité est 0. Le calcul réel est basé sur le fait que le produit interne généralisé ( .) avec +et ×comme opérandes est effectivement le produit matriciel. Ceci combiné avec l' opérateur de puissance ("répéter") forme la viande de la solution.

lstefano
la source
1: Êtes-vous LE Stefano qui a battu Dan et Nick d'un octet dans le jeu de l'année 2016?! 2. (1+≢⍵)↑1=> 1↑⍨1+≢⍵pour enregistrer un octet.
Zacharý
Oui c'est moi.
lstefano
2

Sauge, 112 octets

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

Essayez-le en ligne

Explication:

La lambda intérieure ( lambda A,B:[[sum(map(mul,zip(a,b)))for b in zip(*B)]for a in A]) est une implémentation simple de la multiplication matricielle. La lambda externe ( lambda A,n:reduce(...,[A]*n,identity_matrix(len(A)))) utilise reducepour calculer la puissance de la matrice par multiplication de matrice itérée (en utilisant la fonction de multiplication de matrice maison susmentionnée), avec la matrice d'identité comme valeur initiale à prendre en charge n=0.

Mego
la source
2

Julia, 90 86 68 octets

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

Il s'agit d'une fonction récursive qui accepte une matrice ( Array{Int,2}) et un entier et renvoie une matrice.

Non golfé:

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

Essayez-le en ligne! (inclut tout sauf le dernier cas de test, qui est trop lent pour le site)

Enregistré 18 octets grâce à Dennis!

Alex A.
la source
2

Python 2.7, 158 145 octets

La pire réponse ici, mais mon meilleur golf en Python à ce jour. Au moins, c'était amusant d'apprendre à faire la multiplication matricielle.

Golfé:

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]

Explication:

#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]
Bleu
la source
1

JavaScript (ES6), 123 octets

(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

J'avais une version de 132 octets en utilisant reducemais j'étais juste en train de mapper asi souvent qu'il s'est avéré être 9 octets plus court pour écrire une fonction d'aide pour le faire pour moi. Fonctionne en créant la matrice d'identité et en la multipliant par des temps alongs n. Il existe un certain nombre d'expressions qui renvoient 0ou 1pour i == jmais elles semblent toutes faire 7 octets de long.

Neil
la source
1

Python 3 , 147 octets

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

Essayez-le en ligne!

Leaky Nun
la source
1

R, 49 octets

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

Fonction récursive qui prend un matrix et le pouvoir nde l'élever. Appels récursifs %*%, qui calculent le produit scalaire. La valeur initiale de la récursivité est la matrice d'identité de la même taille que m. Depuis m %*% m = m %*% m %*% I, cela fonctionne très bien.

JAD
la source
0

Python 2 , 131 octets

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

Essayez-le en ligne!

Arfie
la source