매트릭스 파워를 구합니다


9

문제

받는 인상 행렬의 결과를 산출 할 수있는 프로그램이나 함수 작성 N 번째 전원. 코드는 임의의 정사각 행렬 A 와 음이 아닌 정수 n 을 취하고 값이 A n 인 행렬을 반환합니다 .

제한 사항

매트릭스 파워와 매트릭스 곱을 계산하는 내장 함수는 허용되지 않습니다.

코드 골프에 대한 나머지 표준 규칙이 적용됩니다.

설명

정사각형 행렬 주어 의 값 N = AA ⋯ (반복 매트릭스 제품 자체, N 회). 경우 n은 양수, 방금 언급 한 표준이 사용됩니다. 경우 n이 제로이고, 같은 순서를 가지는 행렬 A는 결과이다.

이것은 코드 골프이며 가장 짧은 코드가 승리합니다.

테스트 사례

여기에서 A 는 입력 행렬이고, n 은 입력 정수이며, rr = 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
매트릭스 제품 또는 매트릭스 반전을위한 내장 기능은 어떻습니까?
Dennis

@Dennis 나는 그것들도 금지하는 것을 고려하고 있었지만 너무 제한적 이라고 느꼈습니다 .
마일

2
내장 된 매트릭스 반전이없는 언어의 경우 , 매트릭스를 처음부터 거꾸로 뒤집는 것이 반복 된 제품을 가져 오는 것보다 훨씬 어렵 기 때문에 이것은 카멜레온 문제 입니다.
xnor

2
@xnor에 동의합니다. 언어에 행렬 반전이 없지만 행렬의 힘이있는 경우 어떻게해야합니까? A^-1의 대체품으로 사용할 수 있습니까 inv(A)?
Luis Mendo

1
되어 exp(k*log(M))허용? (독특하지 않은 가지 때문에 작동하지 않을 수도 있습니다.)
xnor

답변:


4

젤리 , 17 16 15 바이트

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

온라인으로 사용해보십시오!

그리드 출력을 가진 퍼머 링크 : 테스트 사례 1 | 테스트 사례 2 | 테스트 사례 3 | 테스트 사례 4 | 테스트 사례 5

작동 원리

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 바이트

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

온라인으로 사용해보십시오!

설명

이것은 브로드 캐스트에 벡터화 합이 오는 요소 별 곱셈을 사용하여 수동으로 행함으로써 행렬 곱셈을 피합니다. 특히 행렬 Ms × sN 크기 를 곱하기 위해 :

  1. 트랜스 M. 결과 행렬을 호출하십시오 P.
  2. s × 1 × s 3D 배열을 제공하는 첫 번째 치수를 따라 회전 축으로 "돌려" 있는 치수를 치환합니다 ( N예 :) .NQ
  3. 각 요소에의 P각 요소에 Q내재 된 브로드 캐스트를 곱하십시오 . 이는 실제 요소 별 곱셈이 발생하기 전에 s × s × s 로 만들기 위해 3 차원을 따라 sP자동으로 복제 되고 2 차원을 따라 s 번 복제 됩니다.Q
  4. 첫 번째 차원을 따라 합하여 1x s × s 배열을 만듭니다.
  5. s × s 결과를 얻으려면 선행 싱글 톤 치수를 짜십시오 .

주석이 달린 코드 :

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

0 ... 실패
CalculatorFeline

@CatsAreFluffy 감사합니다! 수정
Luis Mendo

3

APL, 32 31 자

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

왼쪽 거듭 제곱은 거듭 제곱하고 오른쪽 인수는 행렬입니다. 원하는 지수 실제 계산은 일반화 된 내적 (사실에 근거 0이고 가장 어려운 (대부분의 공간을 소비) 비트의 경우에 대한 행렬을 구축되어 .있음) +×피연산자 효과적으로 매트릭스 제품이다. 이것은 동력 연산자 ( "반복") 와 결합 하여 솔루션의 고기를 형성합니다.


1 : 2016 년 게임에서 Dan & Nick을 1 바이트로이긴 Stefano입니까?! 2. (1+≢⍵)↑1=> 1↑⍨1+≢⍵1 바이트를 저장합니다.
Zacharý

응 그게 나야.
lstefano

2

세이지, 112 바이트

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

온라인으로 사용해보십시오

설명:

내부 람다 ( lambda A,B:[[sum(map(mul,zip(a,b)))for b in zip(*B)]for a in A])는 행렬 곱셈의 간단한 구현입니다. 바깥 쪽 람다 ( lambda A,n:reduce(...,[A]*n,identity_matrix(len(A))))는 reduceID 행렬을 지원할 초기 값으로 반복 행렬 행렬 (앞서 만든 수제 행렬 곱셈 함수 사용)에 의해 행렬 전력을 계산하는 데 사용합니다 n=0.


2

줄리아, 90 86 68 바이트

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

이것은 행렬 ( Array{Int,2})과 정수 를 받아들이고 행렬을 반환하는 재귀 함수입니다 .

언 골프 드 :

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

온라인으로 사용해보십시오! (마지막 테스트 케이스를 제외한 모든 테스트 사이트를 포함하며 사이트에 비해 너무 느림)

Dennis 덕분에 18 바이트가 절약되었습니다!


2

파이썬 2.7, 158 바이트

여기서 최악의 대답이지만 파이썬에서 아직 최고의 골프입니다. 적어도 행렬 곱셈을 수행하는 방법을 배우는 것은 재미있었습니다.

골프 :

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]

설명:

#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

자바 스크립트 (ES6), 123 바이트

(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

나는 132 바이트 버전을 사용 reduce했지만 a너무 자주 매핑 하여 나를 위해 도우미 함수를 작성하는 데 9 바이트 더 짧았습니다. 항등 행렬을 만들고이를 a길게 곱하여 작동n . 반환한다는 표현이 될 것입니다 01에 대한 i == j하지만 그들은 모두 7 것 같다 바이트 길이는.



1

R, 49 바이트

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

matrix와 n그것을 끌어 올리는 힘 을 취하는 재귀 함수 . 을 재귀 적으로 호출 %*%하여 내적을 계산합니다. 재귀의 초기 값은와 크기가 같은 항등 행렬입니다 m. 이후 m %*% m = m %*% m %*% I로 이것은 잘 작동합니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.