マトリックスパワーを見つける


9

問題

n した行列の結果を計算できるプログラムまたは関数を作成します。コードは任意の正方行列Aと非負の整数nを取り、値A nの行列を返します。

制限事項

行列のべき乗と行列の積を計算する組み込み関数は許可されていません。

コードゴルフの残りの標準ルールが適用されます。

説明

正方行列Aが与えられた場合、A n = AA⋯AAとそれ自身のn回の繰り返し行列積)の値。nが正の場合、前述の標準が使用されます。nがゼロの場合、同じ次数のAの単位行列が結果になります。

ゴール

これはコードゴルフであり、最も短いコードが優先されます。

テストケース

ここで、Aは入力行列、nは入力整数、rは出力行列で、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
行列積または行列反転の組み込みについてはどうですか?
Dennis

@Dennis私もそれらを禁止することを検討していましたが、制限が厳しすぎると感じました。
マイル

2
組み込みの行列反転がない言語の場合、行列をゼロから反転することは、反復された製品を使用するよりもはるかに難しいように思われるため、これはカメレオンの課題として私を襲います。
xnor 2016

2
@xnorに同意します。そして、言語に逆行列はないが行列の力がある場合はどうなりますか?のA^-1代わりとして使用できますinv(A)か?
Luis Mendo 2016

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

オンラインでお試しください!

説明

これは、要素ごとの乗算にブロードキャストとそれに続くベクトル化された合計を使用して手動で行うことにより、行列の乗算を回避します。具体的には、行列Mとを乗算するNには、サイズs × sの両方を使用します。

  1. 転置M。結果の行列を呼び出しPます。
  2. 最初の次元に沿った回転軸で「回転」するNようなの次元を並べ替え、s ×1× sの 3D配列を提供します。NQ
  3. 乗算の各要素P回の各要素Q暗黙の放送で、。これは、実際の要素ごとの乗算が行われる前に、3番目の次元に沿ってP自動的にsQ複製され、2番目に沿ってs回複製されて、両方がs × s × sになることを意味します。
  4. 最初の次元に沿って合計すると、1× 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バイト倒したTHE Stefanoですか?2. (1+≢⍵)↑1=> 1↑⍨1+≢⍵1バイトを保存します。
ザカリー

はい、それは私です。
lstefano 2017

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))))はreduce、(前述の自家製の行列乗算関数を使用して)反復する行列乗算によって行列のべき乗を計算するために使用し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

オンラインでお試しください!(最後のテストケースを除くすべてを含みます。これはサイトにとって遅すぎます)

デニスのおかげで18バイト節約されました!


2

Pythonの2.7、158の 145バイト

ここで最悪の答えですが、Pythonでの私の最高のゴルフはまだです。少なくとも、行列の乗算方法を学ぶのは楽しいものでした。

ゴルフ:

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

JavaScript(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時間掛けることによって機能します。0または1を返す式はいくつかありますが、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.