valarray容器

valarray容器

严格来说,在标准库中,有两种”非STL“(因为这两种容器中没有一种能够完全满足STL容器的要求)容器:bitset,valarray。之所以将bitset称为非STL容器,是因为其不允许对其成员进行直接寻址。

valarray是一个类-vector的容器。其大多数函数和运算符都将valarray作为一个整体来进行操作。

#include <valarray>

#include <iostream>

#include <cstddef>

using namespace std;

double f(double x) { return 2.0 * x - 1.0; }

template<class T>

void print(const char* lbl,const std::valarray<T>& a) {

  std::cout << lbl << ": ";

  for(std::size_t i = 0; i < a.size(); ++i)

    std::cout << a[i] << ' ';

  std::cout << std::endl;

}

int main() {

  double n[] = { 1.0, 2.0, 3.0, 4.0 };

  valarray<double> v(n, sizeof n / sizeof n[0]);

  print("v", v);

  valarray<double> sh(v.shift(1));//左移

  print("shift 1", sh);

  valarray<double> acc(v + sh);//相加

  print("sum", acc);

  valarray<double> trig(sin(v) + cos(acc));//数学函数

  print("trig", trig);

  valarray<double> p(pow(v, 3.0));//立方

  print("3rd power", p);

  valarray<double> app(v.apply(f));//为每一个元素应用一个函数

  print("f(v)", app);

  valarray<bool> eq(v == app);

  print("v == app?", eq);

  double x = v.min();

  double y = v.max();

  double z = v.sum();

  cout << "x = " << x << ", y = " << y

       << ", z = " << z  << endl;

} ///:~

从上面可以看出,valarray的操作有很多,很多常用的数学函数都集成在一起,很方便操作。此外,valarray还在如下一些操作。

apply  cshift  fill  free  max  min  operator T *  operator!  

operator%=  operator&=  operator>>=  operator<<=  operato r*=  

operator+  operator+=  operator-  operator-=  operator/=  operator=  

operator[ ]  operator^=  operator|=  operator~  resize  shift  size  

sum  valarray  value_type 

    explicit valarray(size_t n);

    valarray(const T& val, size_t n));

    valarray(const T *p, size_t n);

    valarray(const slice_array<T>& sa);

    valarray(const gslice_array<T>& ga);

    valarray(const mask_array<T>& ma);

    valarray(const indirect_array<T>& ia);

此外,还可以引用元素的一个子集,不仅可以提取信息,而且还可以更新这些信息。valarray的一个子集称为一个切片。如下所示:

class slice {

public:

    slice();

    slice(size_t st, size_t len, size_t str);//起始索引,长度,间隔

    size_t start() const;

    size_t size() const;

    size_t stride() const;

    };

class gslice {

public:

    gslice();

    gslice(size_t st,

        const valarray<size_t> len, const valarray<size_t> str);

    size_t start() const;

    const valarray<size_t> size() const;

    const valarray<size_t> stride() const;

    };

如下一个例子:

#include <valarray>

#include <iostream>

#include <cstddef>

using namespace std;

template<class T>

void print(const char* lbl,const std::valarray<T>& a) {

  std::cout << lbl << ": ";

  for(std::size_t i = 0; i < a.size(); ++i)

    std::cout << a[i] << ' ';

  std::cout << std::endl;

}

int main() {

  int data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };

  valarray<int> v(data, 12);

  valarray<int> r1(v[slice(0, 4, 3)]);//1,4,7,10

  print("slice(0,4,3)", r1);

  // Extract conditionally

  valarray<int> r2(v[v > 6]);

  print("elements > 6", r2);

  // Square first column

  v[slice(0, 4, 3)] *= valarray<int>(v[slice(0, 4, 3)]);

  print("after squaring first column", v);

  // Restore it

  int idx[] = { 1, 4, 7, 10 };

  valarray<int> save(idx, 4);

  v[slice(0, 4, 3)] = save;

  print("v restored", v);

  // Extract a 2-d subset: { { 1, 3, 5 }, { 7, 9, 11 } }

  valarray<size_t> siz(2);

  siz[0] = 2;

  siz[1] = 3;

  valarray<size_t> gap(2);

  gap[0] = 6;

  gap[1] = 2;

  valarray<int> r3(v[gslice(0, siz, gap)]);//siz显示是2×3矩阵,跨距是6和2

  print("2-d slice", r3);

} ///:~

A gslice object (for “generalized slice”) is like a slice, except that the 

counts and strides are themselves arrays, which means you can interpret a 

valarray as a multidimensional array. The example above extracts a 2 by 3 

array from v, where the numbers start at zero and the numbers for the first 

dimension are found six slots apart in v, and the others two apart, which 

effectively extracts the matrix

// Uses valarray to multiply matrices

#include <cassert>

#include <cstddef>

#include <cmath>

#include <iostream>

#include <iomanip>

#include <valarray>

using namespace std;

// Prints a valarray as a square matrix

template<class T>

void printMatrix(const valarray<T>& a, size_t n) {

  size_t siz = n*n;

  assert(siz <= a.size());

  for(size_t i = 0; i < siz; ++i) {

    cout << setw(5) << a[i];

    cout << ((i+1)%n ? ' ' : '\n');

  }

  cout << endl;

}

// Multiplies compatible matrices in valarrays

template<class T>

valarray<T>

matmult(const valarray<T>& a, size_t arows, size_t acols,

        const valarray<T>& b, size_t brows, size_t bcols) {

  assert(acols == brows);

  valarray<T> result(arows * bcols);

  for(size_t i = 0; i < arows; ++i)

    for(size_t j = 0; j < bcols; ++j) {

      // Take dot product of row a[i] and col b[j]

      valarray<T> row = a[slice(acols*i, acols, 1)];

      valarray<T> col = b[slice(j, brows, bcols)];

      result[i*bcols + j] = (row * col).sum();

    }

  return result;

}

int main() {

  const int n = 3;

  int adata[n*n] = {1,0,-1,2,2,-3,3,4,0};

  int bdata[n*n] = {3,4,-1,1,-3,0,-1,1,2};

  valarray<int> a(adata, n*n);

  valarray<int> b(bdata, n*n);

  valarray<int> c(matmult(a, n, n, b, n, n));

  printMatrix(c, n);

} ///:~

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值