行列の四則演算 | package入門(rpnマイスター編) [講座] | 逆ポーランド電卓の実践ウェブ rpn hacks!

逆ポーランド電卓の実践ウェブ rpn hacks!

逆ポーランド電卓rpnの実践ウェブ   
rpn hacks! アールピーエヌ・ハックスサイトマップ

rpn | 講座 | package入門 | ポテンシャルを飛躍的に高めるrpnパッケージを学習。

HOME > 講座 > package入門 > rpnマイスター編 > 行列の四則演算 hatena yahoo buzzurl livedoor del.icio.us nifty newsing twitter facebook rss ソーシャルブックマーク

行列の四則演算

 以下は1995年から1999年までの1月から12月までの平均黒点数のデータです。data1.txtに格納されているとしましょう。

   24  29  31  14  14  15  14  14  11  21   9  10
   11   4   9   4   5  11   8  14   1   0  17  13
    5   7   8  15  18  12  10  24  51  23  39  41
   31  40  54  53  56  70  66  92  92  55  74  81
   62  66  68  63 106 137 113  93  71 116 133  84


横軸が1月から12月、縦軸が1995年から1999年までの5年間になります。次のデータは2001年から2004年までの同じく黒点数データです。こちらはdata2.txtに格納されているとします。

   90 112 138 125 121 124 170 130 109  99 106 104
   95  80 113 107  96 134  81 106 150 125 106 132
  114 107  98 120 120  88  99 116 109  97  95  80
   79  46  61  60  54  77  83  72  48  65  67  46
   37  45  49  39  41  43  51  40  27  48  43  17


この2つの行列データですが、単純に同じ升目同士を足したり、引いたり、掛けたり、割ったりしたいことがあります。行列の四則演算ですね。表計算でも面倒なセル設定が必要ですし、rpnを使うとこれも結構大変です。

行列データの四則演算の考え方

 そこで、rpnマイスターパッケージに用意したのは、同じ形の行列同士の四則演算プログラムです。具体的にはplus、minus、times、divideプログラムです。

計算の仕方は簡単で、行列同士を横に繋げて計算します。例えば行列1と行列2が以下のようになっているとします。

  行列1
  1 2 3
  4 5 6

  行列2
  6 5 4
  3 2 1


これらを横に繋げます。すると以下のようになります。

  行列3
  1 2 3 6 5 4
  4 5 6 3 2 1


この繋げた2つの行列データをplusやminusといった行列用の四則演算プログラムに渡すことで一気に計算してくれます。

  >rpn -c plus <行列3
  7 7 7
  7 7 7


このように行列1の1と行列2の6を足して7、行列1の2と行列2の5を足して7、…のように一発で計算してくれます。ただし、四則演算する行列同士は同じ形である必要があります。

行列データの「+-×÷」

 では、上記の黒点数のデータdata1.txtとdata2.txtを横に繋げて計算してみましょう。以下のようにdata1.txtとdata2.txtを横に繋げたデータを、そのままplusプログラムに渡します。

 行列データの「+」

  >rpn <data1.txt >tmp
  >rpn <data2.txt >>tmp
  >rpn 2 -c paste <tmp | rpn -c plus
  114 141 169 139 135 139 184 144 120 120 115 114
  106 84 122 111 101 145 89 120 151 125 123 145
  119 114 106 135 138 100 109 140 160 120 134 121
  110 86 115 113 110 147 149 164 140 120 141 127
  99 111 117 102 147 180 164 133 98 164 176 101


計算結果が出ています。面倒な手作業が一切不要で一発で計算できていますね。同じように引き算、掛け算、割り算を計算してみましょう。

 行列データの「-」

  >rpn 2 -c paste <tmp | rpn -c minus
  -66 -83 -107 -111 -107 -109 -156 -116 -98 -78 -97 -94
  -84 -76 -104 -103 -91 -123 -73 -92 -149 -125 -89 -119
  -109 -100 -90 -105 -102 -76 -89 -92 -58 -74 -56 -39
  -48 -6 -7 -7 2 -7 -17 20 44 -10 7 35
  25 21 19 24 65 94 62 53 44 68 90 67

 行列データの「×」

  >rpn 2 -c paste <tmp | rpn -c times
  2160 3248 4278 1750 1694 1860 2380 1820 1199 2079 954 1040
  1045 320 1017 428 480 1474 648 1484 150 0 1802 1716
  570 749 784 1800 2160 1056 990 2784 5559 2231 3705 3280
  2449 1840 3294 3180 3024 5390 5478 6624 4416 3575 4958 3726
  2294 2970 3332 2457 4346 5891 5763 3720 1917 5568 5719 1428

 行列データの「÷」

  >rpn 2 -c paste <tmp | rpn -c divide
  0.266667 0.258929 0.224638 0.112 … 0.100917 0.212121 0.0849057 0.0961538
  0.115789 0.05 0.079646 0.0373832 … 0.00666667 0 0.160377 0.0984848
  0.0438596 0.0654206 0.0816327 0.125 … 0.46789 0.237113 0.410526 0.5125
  0.392405 0.869565 0.885246 0.883333 … 1.91667 0.846154 1.10448 1.76087
  1.67568 1.46667 1.38776 1.61538 … 2.62963 2.41667 3.09302 4.94118


最後のdivideプログラムの結果は横に長すぎるため省略してあります。

ここで、引き算と割り算には注意が必要です。minusプログラムは向かって左の行列から右の行列を引いていることが分かると思います。data1.txtからdata2.txtを引いているわけですね。divideプログラムの割り算も同様なので、後の行列データに0があるとエラーが発生します。

情報普通の表記の「1÷2」も逆ポーランド表記の「1 2 /」も共に先の数値を後の数値で引いたり割ったりしているので、それに合わせてあるためです。

行列データの拡大・縮小と増減

 行列データの四則演算で行列の計算が一気に楽になりましたが、実際に行列のデータを扱っていると行列内の全部の数値を数倍したいとか数分の一にしたいということがあります。

rpnマイスターパッケージではそのような要求に応えるためにoffsetとscaleプログラムを用意しています。まずは一定数を行列データの全ての数値に乗じるscaleプログラムの使用例です。

  >rpn 2 -c scale <data1.txt
  48 58 62 28 28 30 28 28 22 42 18 20
  22 8 18 8 10 22 16 28 2 0 34 26
  10 14 16 30 36 24 20 48 102 46 78 82
  62 80 108 106 112 140 132 184 184 110 148 162
  124 132 136 126 212 274 226 186 142 232 266 168


data1.txtの全ての数値を2倍しています。次は行列内の全ての数値に1を加えるoffsetプログラムの使用例です。

  >rpn 1 -c offset <data1.txt
  25 30 32 15 15 16 15 15 12 22 10 11
  12 5 10 5 6 12 9 15 2 1 18 14
  6 8 9 16 19 13 11 25 52 24 40 42
  32 41 55 54 57 71 67 93 93 56 75 82
  63 67 69 64 107 138 114 94 72 117 134 85


説明の必要はありませんね。scaleプログラムを使うと行列データの全ての数値の符号反転ができますし(-1を掛ける)、offsetプログラムを使うと比率計算後に増減比率を計算できます(-1を加える)。

行列データの小数点の扱い

 次に小数点の扱いについて示します。divideの計算結果にあるように小数点以下が多くある場合は見づらいですし、実際にそこまでの小数は不要なことが多いです。そんなときは行列データの数値の小数を特定の桁数で一気に切り捨ててくれると便利です。

rpnマイスターパッケージのdecimalは指定された小数点以下を切り捨てるrpnプログラムです。以下の例では前出のdivideで計算した結果をデータとして、decimalプログラムに渡しています。

  >rpn 2 -c paste <tmp | rpn -c divide | rpn 2 -c decimal
  0.26 0.25 0.22 0.11 0.11 0.12 0.08 0.1 0.1 0.21 0.08 0.09
  0.11 0.05 0.07 0.03 0.05 0.08 0.09 0.13 0 0 0.16 0.09
  0.04 0.06 0.08 0.12 0.15 0.13 0.1 0.2 0.46 0.23 0.41 0.51
  0.39 0.86 0.88 0.88 1.03 0.9 0.79 1.27 1.91 0.84 1.1 1.76
  1.67 1.46 1.38 1.61 2.58 3.18 2.21 2.32 2.62 2.41 3.09 4.94


きれいに小数点の桁数2より下がカットされていますね。

警告pasteはユーティリティパッケージに同梱されています。

情報本講座で使用したプログラムは、rpnマイスターパッケージとして購入することができます。xypとnpdはrpnの姉妹ソフトウェアです。詳しくはプロダクトを参照ください。

rpnマイスターパッケージ

マイスター

ユーティリティー

カレンダー

警告文字で作られた図表や式が崩れることがあります。ブラウザによっては固定幅フォントをMSゴシックにするときれいに表示されます。それでも崩れる場合は図表や式をメモ帳にコピー後、閲覧下さい。

警告rpn標準版(2kリビジョン)はダブルクォートで囲ってください。

rpn 1 2 + ⇒ rpn "1 2 +"
rpn 1 -c foo ⇒ rpn "1" -c "foo"

ダブルクォートは省略できることが多いのですが、慣れない間は囲んだほうが無難です。なお、本ウェブサイトの記事ではrpn標準版(98リビジョン)を使用しているため囲っていません。詳しくは技術サポートの「rpn TIPS」を参照ください。

注意rpnの障害情報と対策はこちら