Encuentra el poder de la matriz


9

Problema

Crear un programa o función que puede calcular el resultado de una matriz elevada a la n º potencia. Su código tomará una matriz cuadrada arbitraria A y un número entero no negativo n , y devolverá una matriz con el valor A n .

Restricciones

Las funciones incorporadas que calculan la potencia de la matriz y el producto de la matriz no están permitidas.

Se aplica el resto de las reglas estándar para el código de golf.

Explicación

Dada una matriz cuadrada A , el valor de A n = AA ⋯ A (producto matricial repetido de A consigo mismo, n veces). Si n es positivo, se utiliza el estándar que se acaba de mencionar. Cuando n es cero, la matriz de identidad con el mismo orden de A es el resultado.

Objetivo

Este es el código de golf y gana el código más corto.

Casos de prueba

Aquí, A es la matriz de entrada, n es el entero de entrada y r es la matriz de salida donde 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
¿Qué pasa con las incorporaciones para el producto de matriz o la inversión de matriz?
Dennis

@ Dennis Estaba considerando prohibirlos también, pero me pareció demasiado restrictivo.
millas

2
Para los lenguajes sin inversión de matriz incorporada, esto me parece un desafío de camaleón porque invertir una matriz desde cero parece mucho más difícil que tomar el producto iterado.
xnor

2
Estoy de acuerdo con @xnor. ¿Y qué pasa si un idioma no tiene inversión matricial pero tiene poder matricial? ¿Se A^-1puede utilizar como sustituto de inv(A)?
Luis Mendo

1
Está exp(k*log(M))permitido? (Aunque podría no funcionar debido a ramas no únicas.)
xnor

Respuestas:


4

Jalea , 17 16 15 bytes

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

Pruébalo en línea!

Permalinks con salida de red: caso de prueba 1 | caso de prueba 2 | caso de prueba 3 | caso de prueba 4 | caso de prueba 5

Cómo 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.

5

MATL , 20 bytes

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

Pruébalo en línea!

Explicación

Esto evita la multiplicación de la matriz haciéndola manualmente, usando la multiplicación por elementos con difusión seguida de la suma vectorizada. Específicamente, para multiplicar matrices My N, ambas de tamaño s × s :

  1. Transponer M. Llama a la matriz resultante P.
  2. Permuta las dimensiones de Ntal que Nse "gira" con un eje de rotación a lo largo de la primera dimensión, dando una matriz 3D s × 1 × s , digamos Q.
  3. Multiplique cada elemento de Pveces cada elemento de Q, con difusión implícita. Esto significa que Pse replica automáticamente s veces a lo largo de la tercera dimensión, y Qse replica s veces a lo largo de la segunda, para hacer que ambos sean s × s × s , antes de que tenga lugar la multiplicación real por elementos.
  4. Suma a lo largo de la primera dimensión para obtener una matriz de 1 × s × s .
  5. Exprima la dimensión de singleton principal para producir un resultado s × s .

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

Falla para 0 ....
CalculatorFeline

@CatsAreFluffy ¡Gracias! Corregido
Luis Mendo

3

APL, 32 31 caracteres

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

Argumento a la izquierda, el poder para elevar, argumento a la derecha, la matriz. El bit más difícil (que consume más espacio) es construir la matriz de identidad para el caso en el que el exponente deseado es 0. El cálculo real se basa en el hecho de que el producto interno generalizado ( .) con +y ×como operandos es efectivamente el producto de la matriz. Esto combinado con el operador de potencia ("repetir") forma la carne de la solución.


1: ¿Eres EL Stefano que venció a Dan y Nick por un byte en el juego del año 2016? 2. (1+≢⍵)↑1=> 1↑⍨1+≢⍵para guardar un byte.
Zacharý

Sí, soy yo.
lstefano

2

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

Pruébalo en línea

Explicación:

El lambda interno ( lambda A,B:[[sum(map(mul,zip(a,b)))for b in zip(*B)]for a in A]) es una implementación sencilla de la multiplicación de matrices. El lambda externo ( lambda A,n:reduce(...,[A]*n,identity_matrix(len(A)))) se usa reducepara calcular la potencia de la matriz mediante la multiplicación matricial iterada (utilizando la función de multiplicación matricial casera mencionada anteriormente), con la matriz de identidad como valor inicial para soportar n=0.


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 es una función recursiva que acepta una matriz ( Array{Int,2}) y un entero y devuelve una matriz.

Sin 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

Pruébalo en línea! (incluye todos menos el último caso de prueba, que es demasiado lento para el sitio)

¡Ahorró 18 bytes gracias a Dennis!


2

Python 2.7, 158145 bytes

La peor respuesta aquí, pero mi mejor golf en Python todavía. Al menos fue divertido aprender a multiplicar matrices.

Golfizado:

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]

Explicación:

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

Tenía una versión de 132 bytes, reducepero solo estaba mapeando con atanta frecuencia que resultó ser 9 bytes más corto para escribir una función auxiliar que lo hiciera por mí. Funciona creando la matriz de identidad y multiplicándola por tiempos alargos n. Hay varias expresiones que devuelven 0o 1para i == jpero todas parecen tener 7 bytes de longitud.



1

R, 49 bytes

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

Función recursiva que toma un matrix y el poder npara elevarlo. Llamadas recurrentes %*%, que calculan el producto punto. El valor inicial de la recursión es la matriz de identidad del mismo tamaño que m. Desde entonces m %*% m = m %*% m %*% I, esto funciona bien.


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.