Loading [Contrib]/a11y/accessibility-menu.js
メインコンテンツに移動

Boost/Array

原理主義のページで作成した配列クラスは,じつはもっと良いものが提供されています.自作なんてさっさとやめて,本物を使いましょう.でも・・・ちょっと多機能すぎるんですよね.

  • 配列の添字の範囲を指定できる
  • 配列の一部分を別の配列として切り出すことができる

ありがたいのですけどね. 理解するのが面倒なんですよ. 利用例を示しておきましょう:

#include <boost/multi_array.hpp>
...
const int ndim=3;
using D3D=boost::multi_array<double, ndim>; //倍精度「3次元」配列をD3Dクラス
D3D MDA(boost::extents[3][4][2]);           //D3Dクラスの3x4x2インスタンスMDAを作成
//添字の開始位置を[0][0][0]からシフトさせることができる
boost::array<D3D::index,ndim> MDA_base = {{0, 1, -5}};
MDA.reindex(MDA_base);
//何ができたか調べる
std::cout << "dimension= " << MDA.num_dimensions() << std::endl;
//次元と添字の範囲を調べてみる
for(int k=0;k<MDA.num_dimensions();k++)
{
  std::cout << "dim-" << k << " min:size= " << MDA.index_bases()[k] << ":" << MDA.shape()[k] << std::endl;
}
std::cout << "total elements= " << MDA.num_elements() << std::endl;
//配列要素を設定
for(int i=0;i<MDA.shape()[0];i++)
for(int j=0;j<MDA.shape()[1];j++)
for(int k=0;k<MDA.shape()[2];k++)
{
  auto er=MDA.index_bases();            //原点をずらした場合
  int ir=er[0]+i,jr=er[1]+j,kr=er[2]+k; //シフトさせないとやばい
  auto val=MDA[ir][jr][kr]=(i+j*j+100*(k+1))*0.1;
  std::cout << "MDA[" << ir << "][" << jr << "][" << kr << "]= " << val << std::endl;
}
//全ての要素を一列アクセス
for(int i=0;i<MDA.num_elements();i++) std::cout << "MDA[" << i << "]= " << MDA.data()[i] << std::endl;

このusingというのは, 長い命令を書くのがだるい時に, 短縮名=正式名, として簡単に書ける,という命令です.

白亜紀(2011年ごろ)には,typedef 正式名=短縮名と書いてました.右辺の値が左辺で定まるomg文法だ!

実行結果は

dimension= 3
dim-0 min:size= 0:3
dim-1 min:size= 1:4
dim-2 min:size= -5:2
total elements= 24
MDA[0][1][-5]= 10
MDA[0][1][-4]= 20
MDA[0][2][-5]= 10.1
MDA[0][2][-4]= 20.1
...
  MDA[2][3][-4]= 20.6
MDA[2][4][-5]= 11.1
MDA[2][4][-4]= 21.1
MDA[0]= 10
MDA[1]= 20
MDA[2]= 10.1
MDA[3]= 20.1
MDA[4]= 10.4
MDA[5]= 20.4
MDA[6]= 10.9
MDA[7]= 20.9
MDA[8]= 10.1
MDA[9]= 20.1
MDA[10]= 10.2
...
  MDA[21]= 20.6
MDA[22]= 11.1
MDA[23]= 21.1

まあ詳細はGoogleにて