valarray

最近サポートベクタマシンや、クラスタリングを適当に組んだりするときに、3次元以上の点を表すのにちょうどいいデータ構造として、valarrayを使っていた。valarrayは算術演算が定義された配列みたいなイメージで雰囲気で使っていたのだが、初期化周りのことが気になったので調べてみたら結構面白い使い方ができることがわかった。


とりあえずやる気なく参考にしたとこのURLをはっつけておく。
Spaghetti Source - 空間幾何の基本要素
Object not found!
invisiblefulmoon.net: The Leading Invisible Full Moon Site on the Net
invisiblefulmoon.net: The Leading Invisible Full Moon Site on the Net


ICPCで使うかもしれない関係で、忘れそうな部分を行数がかさばらないサンプルコードにしてみた。

#include <iostream>
#include <valarray>
using namespace std;

template<class T> void show_array(const valarray<T>& arr) {
  for (int i = 0; i < arr.size(); i++) cout<<arr[i]<<" ";
  cout<<endl;
}

int main() {
  const int SIZE = 8;
  int a[SIZE] = {1,1,2,3,5,8,13,21};
  valarray<int> fib(a,SIZE); //配列による初期化
  show_array(fib); /* 1 1 2 3 5 8 13 21 */
  
  // slice(size_t start, size_t length, size_t stride)
  valarray<int> slc = fib[slice(0,4,2)]; //slice_array//
  show_array(slc); /* 1 2 5 13 */
  
  valarray<int> signum(-1,SIZE/2); //vector初期化とは意味が逆なので注意
  show_array(signum); /* -1 -1 -1 -1 */
  signum.resize(SIZE,1); //resizeの順序はvectorと同じだが、全て初期化されてしまう
  show_array(signum); /* 1 1 1 1 1 1 1 1 */
  
  size_t idx[] = {0,2,7,3,6};
  valarray<size_t> index(idx,5);
  signum[index] = -1; //indirect_array//
  show_array(signum); /* -1 1 -1 -1 1 1 -1 -1 */
  
  fib *= signum;
  show_array(fib); /* -1 1 -2 -3 5 8 -13 -21 */
  fib[fib>0||abs(fib)>20] = 0; //mask_array//
  show_array(fib); /* -1 0 -2 -3 0 0 -13 0 */
  return 0;
}

まだブール型マスク、行列的に扱うgsliceとかいうようなのがあったけど使わないだろうから省略。