行列ベクトルを計算する


14

少なくとも2つの要素の整数配列を指定して、配列のMatrix-Vector(以下で定義)を出力します。

Matrix-Vectorを計算するには、最初nにsize - input配列を回転させて、サイズの行列を作成しますn x n。配列の最初の要素は主対角線に続きます。これにより、マトリックス部分が形成されます。ベクトルの場合、入力配列を垂直に反転します。次に、通常の行列乗算を実行します。出力ベクトルは結果です。

例えば、

a = [1, 2, 3]

まず、配列を右に2回回転して、とを取得[3, 1, 2][2, 3, 1]、次にそれらをスタックして3x3行列を形成します

[[1, 2, 3]
 [3, 1, 2]
 [2, 3, 1]]

次に、配列を垂直に反転させてベクトルを形成します

[[1, 2, 3]    [[1]
 [3, 1, 2]  x  [2]
 [2, 3, 1]]    [3]]

通常の行列乗算を実行する

[[1, 2, 3]    [[1]    [[1+4+9]    [[14]
 [3, 1, 2]  x  [2]  =  [3+2+6]  =  [11]
 [2, 3, 1]]    [3]]    [2+6+3]]    [11]]

そして、出力は[14, 11, 11]or [[14], [11], [11]](フラット化するかどうかの選択)です。

例2

a = [2, 5, 8, 3]

[[2, 5, 8, 3]    [[2]    [[4+25+64+9]     [[102]
 [3, 2, 5, 8]  x  [5]  =  [6+10+40+24]  =  [80]
 [8, 3, 2, 5]     [8]     [16+15+16+15]    [62]
 [5, 8, 3, 2]]    [3]]    [10+40+24+6]]    [80]]

[102, 80, 62, 80]

ルール

  • 入力および出力は、言語のネイティブ整数型に適合すると想定できます。
  • 入力と出力は、任意の便利な形式で指定できます
  • 完全なプログラムまたは機能のいずれかが受け入れられます。関数の場合、出力する代わりに出力を返すことができます。
  • 可能であれば、他の人があなたのコードを試すことができるように、オンラインテスト環境へのリンクを含めてください!
  • 標準的な抜け穴は禁止されています。
  • これはので、通常のゴルフルールがすべて適用され、最短のコード(バイト単位)が勝ちます。

回答:


8

ゼリー、5バイト

ṙJṚæ.

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

説明

まず:

ここで、は行ベクトルで、はベクトルです。vkx

これは、行列の乗算が行と列の間の単なる内積であることを示しています。

次に、実際に回転右へ、そしてれる回転等、右にv1v0vkvk-1

別の角度から、されている回転左に、そしてれる回転左に、等v1vnvnv1

使い方

ṙJṚæ.   input: z (a list of length n)
ṙJ      [rot(z,1), rot(z,2), ..., rot(z,n)] (to the left)
  Ṛ     [rot(z,n), ..., rot(z,2), rot(z,1)]
   æ.   [rot(z,n).z , ..., rot(z,2).z , rot(z,1).z] (dot product)






2

Haskell、49バイト

f v=sum.zipWith(*)v.fst<$>zip(iterate tail$v++v)v

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

入力用 v=[1,2]

  • iterate tail$v++v リストを生成します [[1,2,1,2],[2,1,2],[1,2],[2],[],...]
  • fst<$>zip l vと同じでtake(length v)lあり、[[1,2,1,2],[2,1,2]]
  • sum.zipWith(*)v は各要素にマッピングされ、ベクトル行列の行積を生成します。

私の答えよりもずっと賢い!私は好きfst<$>zip l v非常に多くを。
ジェフェラード






1

J、14バイト

+/ .*~#\.1&|.]

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

説明

+/ .*~#\.1&|.]  Input: array M
      #\.       Length of each suffix, forms the range [len(M), ..., 2, 1]
             ]  Identity, get M
         1&|.   For each 'x' in the suffix lengths, rotate left M  by 'x'
+/ .*~          Dot product with M

これはとてもいいです。一つの質問。に1&|.結合1しない場合|.、モナドを作成しますか?しかし、その後、左と右の両方の引数でそのモナドを使用し、左の引数が適用される回数を決定します。何が起きてる?
ジョナ

@Jonahこれはの特別な形式です&。として使用される場合u n&f v、それは実行してい(n&f)^:u vます。ボンドの下部を参照して、解析の詳細を確認してください。
マイル

ああ、TIL。よく使うものですか?
ジョナ

@Jonah多くの場合、ゴルフに役立ちます。この場合、rankを使用して同じバイト数で実行できたかもしれませんが#\.|."{]、代替案を試す前に最初に思いついた最短を投稿しました。
マイル

1

APL、17バイト

(↑¯1⌽(⍳≢)⌽¨⊂)+.×⍪

説明:

(↑¯1⌽(⍳≢)⌽¨⊂)+.×⍪

 ↑                      matrix format of
  ¯1⌽                   right rotate by 1 of
     (⍳≢)               the 1..[length N]
         ⌽¨             rotations of
           ⊂            the enclosed input
             +.×        inner product with
                ⍪       1-column matrix of input



1

、11バイト

mΣ§‡*´ṀKoṫ¢

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

説明

mΣ§‡*´ṀKoṫ¢  Implicit input, e.g. [1,2,3]
          ¢  Cycle: [1,2,3,1,2,3,...
        oṫ   Tails: [[1,2,3,1,2,3...],[2,3,1,2,3...],[3,1,2,3...]...
     ´ṀK     Replace each element of input with input: [[1,2,3],[1,2,3],[1,2,3]]
   ‡*        Vectorized multiplication (truncated with respect to shortest list)
  §          applied to the last two results: [[1,4,9],[2,6,3],[3,2,6]]
mΣ           Sum of each row: [14,11,11]

1

オクターブ-67 48バイト

このコードを19バイト削減したLuis Mendoに感謝します!

注:このコードはOctaveでのみ実行できます。MATLABは、変数を作成すると同時にそれらを作成する式を評価できる関数内の式をサポートしていません。

n=numel(a=input(''));a(mod((x=0:n-1)-x',n)+1)*a'

MATLABの元のコードはここにありますが、MATLABのどのバージョンでも実行できます。このコードは67バイトです。

a=input('');n=numel(a)-1;a(mod(bsxfun(@minus,0:n,(0:n)'),n+1)+1)*a'

説明

  1. a=input('');-標準入力を介してユーザーから(行)ベクトルを受け取ります。ベクトルをオクターブ形式(つまり[1,2,3])で入力する必要があります。
  2. n=numel(...); -入力ベクトル内の要素の総数を取得します。
  3. x=0:n-1- 0最大で増加する行ベクトルを作成しますn-1で1。
  4. (x=0:n-1)-x'-ブロードキャストを実行して、n x nマトリックスを作成し、各行iが0からn-1行の各要素をでi減算した要素になるようにしiます。
  5. mod(..., n)+1-負の値は、n各行iに0から要素によって左にn-1 循環的にシフトされるベクトルが含まれるように、折り返しiます。MATLAB / Octaveがベクトルまたは行列のインデックス作成を1として開始するときに1を追加します。
  6. a(...)- n x n(4)を使用して、(4)の各値で指定された入力ベクトルの正しいインデックスにアクセスするマトリックスを作成し、必要なマトリックスを実現します。
  7. (...)*a' -転置/反転により行列ベクトル乗算を実行します a前に、して列ベクトルになるように。

実行例

>> n=numel(a=input(''));a(mod((x=0:n-1)-x',n)+1)*a'
[1,2,3]

ans =

         14.00
         11.00
         11.00

>> n=numel(a=input(''));a(mod((x=0:n-1)-x',n)+1)*a'
[2,5,8,3]

ans =

        102.00
         80.00
         62.00
         80.00

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


の代わりに暗黙的な展開を使用できますbsxfunnなしで定義すると-1、数バイトも節約されます。あなたはオクターブに制限している場合、あなたは割り当てることができますaし、0:nその場で変数にし、いくつかの続き。また、もっと頻繁にここに来てください!! :-D
ルイスメンドー

@LuisMendoああそう。Octaveには暗黙的な拡張がすでにサポートされていることを忘れています。また、input関数内で変数を保存することは素晴らしいトリックです。それをサポートできるとは思いませんでした。私自身の経験から、CまたはC ++でのみ見ました。ありがとう!
rayryeng-モニカの復活

1
@LuisMendoあなたの提案した変更をすぐに編集として配置します。私は忙しかったのですが、このエントリは確かにバイトカウントで勝つことはないので、これを優先していません。
rayryeng-モニカの復活

@LuisMendoが変更されました。どうもありがとうございました:)上記の説明を変えていたので、コードを理解しました。
rayryeng-モニカの復活

助けてくれてうれしい:
ルイスメンドー

0

Javascript 79バイト

入力配列を取り、行列ベクトルの配列を出力します

a=>(b=[...a],a.map(x=>([...b].reduce((m,n,i)=>m+=n*a[i],0,b.push(b.shift())))))

説明

a=>(
    b=[...a],                    // copy the input into b
    a.map(x=>(                   // transform a into a new array
        [...b].reduce(           // copy b into a new array and reduce
            (m,n,i)=>m+=n*a[i],  // memo += the element in the array * the ith
                                 // element in a
            0,                   // start memo at 0
            b.push(b.shift())    // shift the first element in b to the end
                                 // not used by reduce, but performing this op
                                 // here saves a few bytes
        )
    ))
)

0

Clojure、80バイト

#(map(fn[_ c](apply +(map * c %)))%(iterate(fn[c](into[(last c)](butlast c)))%))

iterate無限のシーケンスを生成しますが、(take (count %) (iterate ...))停止する代わりに%の追加の引数として使用しmapます。




0

Common Lisp、78バイト

(lambda(x)(loop as i on(append x x)as y in x collect(reduce'+(mapcar'* i x))))

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

二重のあるサブリスト上の配列(この場合、Lispのリスト)及び反復i(使用xを通じて、y反復を停止します)。次に、の各要素を乗算した結果を合計して、結果の次の要素を計算しますxの各要素をi(再び短いリストが終了すると停止を)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.