【 J 言語】超簡単!行列積で九九表
毎度おなじみ J 言語の記事です。
*/~>:i.9
ASCII 文字が 8 つ並んでいますが、これは九九表を出力する J 言語のコードです。
1 2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81
J 言語の九九表といえばこれをよく目にすると思いますが、なんかこればっかりで面白くないので違う方法でやってみます。
\begin{pmatrix}
1 \\ 2 \\ \vdots \\ 9
\end{pmatrix}
\begin{pmatrix}
1 & 2 & \cdots & 9
\end{pmatrix}
=
\begin{pmatrix}
1 & 2 & \cdots & 9 \\
2 & 4 & \cdots & 18 \\
\vdots & \vdots & \ddots & \vdots \\
9 & 18 & \cdots & 81
\end{pmatrix}
今回は行列積を使って九九表を出します。
行列を作る
行列積を計算するにあたって、まずは積をとる 2 つの行列、 $\begin{pmatrix} 1 \\ 2 \\ \vdots \\ 9 \end{pmatrix}$ と $\begin{pmatrix} 1 & 2 & \cdots & 9 \end{pmatrix}$ を作ります。
J 言語で行列を作る方法はいろいろあります。
x $ y
Shape
i.9 NB. [0, 9) の整数列を作成
0 1 2 3 4 5 6 7 8
1+i.9 NB. すべての要素に 1 を加算
1 2 3 4 5 6 7 8 9
>:i.9 NB. すべての要素をインクリメント
1 2 3 4 5 6 7 8 9
i. y
Integers を使えば 0 からの整数列を生成できるので、 1 を足すと 1 からの整数列になります。
>: y
Increment を使って 1 加えることもできます。
しかし、ここで出来上がるのは 1 次元配列です。行列として計算するには 2 次元配列にする必要があります。
そこで使うのが 2 項の $
です。
単項の $ y
Shape Of は shape (配列の形)を調べるために使いますが、 2 項の x $ y
Shape は配列を指定した shape に整形することができます。
>:i.9 NB. これは 1 次元配列
1 2 3 4 5 6 7 8 9
$ >:i.9 NB. shape は 9
9
9 1 $ >:i.9 NB. 9×1 の 2 次元配列に整形
1
2
3
4
5
6
7
8
9
$ 9 1$>:i.9 NB. shape は 9 1
9 1
1 9 $ >:i.9 NB. 1×9 の 2 次元配列に整形
1 2 3 4 5 6 7 8 9
$ 1 9$>:i.9 NB. 出力の見た目は >:i.9 と変わっていないが shape は 1 9
1 9
,: y
Itemize
横に長いほうの行列は、 i. y
Integers で生成した 1 次元配列を要素として持つ 2 次元配列です。
このような配列は、 ,: y
Itemize を使うと x $ y
Shape を使うより簡単に作れます。
,: >:i.9 NB. >:i.9 を要素に持つ配列を作成
1 2 3 4 5 6 7 8 9
$ ,:>:i.9 NB. shape は 1 9
1 9
|: y
Transpose
縦に長いほうの行列は、横に長いほうの行列の転置行列です。
転置行列は |: y
Transpose を使って作ることができます。
|: ,:>:i.9 NB. ,:>:i.9 を転置
1
2
3
4
5
6
7
8
9
$ |: ,:>:i.9 NB. shape が反転している( 1 9 → 9 1 )
9 1
,. y
Ravel Items
縦に長いほうの行列は ,. y
Ravel Items を使うことでさらに簡単に作れます。
この動詞は要素が縦に並んだ 2 次元配列を作ります。
,. >:i.9 NB. 縦に要素を並べた 2 次元配列を作成
1
2
3
4
5
6
7
8
9
i. y
Integers
実は i. y
Integers に shape を示す配列を渡すと、その shape に整形した配列を生成します。
>:i.1 9 NB. [0, 9) の整数列を 1×9 の配列に並べてインクリメント
1 2 3 4 5 6 7 8 9
$ >:i.1 9 NB. shape は 1 9
1 9
>:i.9 1 NB. [0, 9) の整数列を 9×1 の配列に並べてインクリメント
1
2
3
4
5
6
7
8
9
$ >:i.9 1 NB. shape は 9 1
9 1
行列積
次は行列積の計算方法です。
x u . v y
Matrix Product (Conjunction)
J 言語には行列積演算子なるものがあります。それが .
←これです。
行列積はこの演算子(正確には接続詞 (conjunction) )を使って +/ . *
で求められます。
ここで +/.*
と詰めて書くと .
ではなく /.
と認識されるので、 /
と .
の間のスペースが必須なことに注意です。( .
と *
の間のスペースは任意です。)
]a=: 2 3 $ 2 _3 8 _8 _2 _3
2 _3 8
_8 _2 _3
]b=: 3 3 $ _8 2 _4 8 _4 _2 4 6 6
_8 2 _4
8 _4 _2
4 6 6
a +/ . * b NB. a と b の行列積
_8 64 46
36 _26 18
九九表
最後に上で紹介したものを組み合わせます。
(>:i.9 1) +/ . * >:i.1 9
1 2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81
完成です。
J 言語は「配列型プログラミング言語」というだけあって、行列演算は得意分野です。
コードゴルフ
やはり最後は短くしたくなります。
共通部分をくくりだすことで、 J 言語らしく短く書くことができます。
(,.>:i.9) +/ . * ,:>:i.9 NB. 共通部分が増えるように ,. と ,: を使って行列を作る
NB. ↓ '>:i.9' をくくりだす
(,.+/ .*,:)>:i.9
Author And Source
この問題について(【 J 言語】超簡単!行列積で九九表), 我々は、より多くの情報をここで見つけました https://qiita.com/Raclamusi/items/8a9d711d595fc2e6abfb著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .