2017年5月21日

C++ で MatB(':', 0) = MatA(':', 0); を実装する

概要
  この投稿では,C++ で行列の行や列のコピーを簡便に記述するために,演算子のオーバーロードを組み合わせ, MatB(':', コピー先の列数) = MatA(':', コピー元の列数);MatB(コピー先の行数, ':') = MatA(コピー元の行数, ':'); のような記法を目標とする.これは,Python などの高級言語に似せた記法である (※要確認).
要求仕様
行列の列コピーを MatB(':', コピー先の列数) = MatA(':', コピー元の列数); と記述できるようにする.
行列の行コピーを MatB(コピー先の行数, ':') = MatA(コピー元の行数, ':'); と記述できるようにする.
実装方法
  まず,'()' 演算子をオーバーロードして,必要な列のコピー (ColCopy) にデータを,ColCopy クラスとして返却 (return) する. 次に,ColCopyクラスでオーバーロードされた '=' 演算子が,'=' の左右の ColCopy クラスから,データを受け取り,データをコピーする. (ColCopy クラスを経由するのは,受け取るクラスによって '=' 演算子動作を変更するためである.) '=' 演算子の左辺は this ポインタで,右辺は '引数として' それぞれ取得される.
ソースコード
  下記に示す通り,要求仕様を満たすコードを実装した.

古い実装 (この投稿の実装): github.com/admiswalker/~/MatrixStore_Ver00.00_01
新しい実装: github.com/admiswalker/MatrixStore    
実行結果
./main.cpp
実行結果
$ ./exe
MatA =
0.000000         1.000000        2.000000
3.000000         4.000000        5.000000
6.000000         7.000000        8.000000

MatB =
1.000000         0.000000        0.000000
4.000000         0.000000        0.000000
7.000000         0.000000        0.000000

MatB =
0.000000         1.000000        2.000000
4.000000         0.000000        0.000000
6.000000         7.000000        8.000000
まとめ
  演算子のオーバーロードによって,要求仕様を満たす演算を実装した.
今後の課題
  値の受け渡しが煩雑になっているため,ベンチマークを取ると,処理にオーバーヘッドが発生している可能性がある. また,MatB('0:1', 0) = MatA('0:1', 1); のような記述も実装可能ではあるが,この場合,文字列処理が発生するため,処理が遅くなる可能性がある. ただし,こうしたオーバーヘッドは,呼び出し回数が少ない場合は,それほど大きな問題にはならないはずである. 現在 ':' 記号の受け渡しを想定しているが,実際のところコンパイラでは型の確認しか行えないので, 記述を統一する意味では,実行時のエラーチェックが必要となる.(ただし,実際にこれを実装すると,オーバーヘッドとなる.) しかしながら,上記の MatB('0:1', 0) = MatA('0:1', 1); のような処理を実装するのであれば,いずれにしても確認を行う必要に駆られる.

0 件のコメント:

コメントを投稿