valarray的用法小记

来源:百度文库 编辑:神马文学网 时间:2024/05/03 06:05:17
[Header File]
* valarray Class
数值数组
* slice and gslice Class
对valarray进行分片
* slice_array, gslice_array, mask_array, and indirect_array Class
内部的辅助类,用于存储临时数据。这些类仅由valarray的特定操作间接产生,无法直接使用。
[Valarray Operations]
若组合的valarray的元素个数不同,则结果是未定义的。
[Valarray Subsets]
va[slice(2, 4, 3)]  // four elements with distance 3 starting from index 2
va[va>7]    // all elements with a value greater than 7
因为避免了“临时值”,所以只有保证目标子集和源子集的元素必须是不同的时,valarray的任何操作才保证正确。
有四种方法来定义valarray的子集:
1.Slices
2.General slices
3.Masked subsets
4.Indirect subsets
[Valarray Subset Problems]
在开始介绍子集之前,不得不谈一个通常的问题。valarray的子集的处理设计的并不好。你可以很容易的创建子集,但是你不能很容易的合并子集。不幸的是,你总是需要对valarray进行显示的类型转换。这是因为C++标准库并没有为valarray的子集提供与valarray相同的操作符。
例如,对于将两个子集相乘并赋值给第三个子集,你不能这样写:
// ERROR : conversions missing
va[slice(0, 4, 3)] = va[slice(1, 4, 3)] * va[slice(2, 4, 3)];
相反,你不得不使用新的类型转换编码:
va[slice(0, 4, 3)] =
static_cast >(va[slice(1, 4, 3)] *
static_cast >(va[slice(2, 4, 3)];
或者使用老的类型转换:
va[slice(0, 4, 3)] =
valarray(va[slice(1, 4, 3)]) *
valarray(va[slice(2, 4, 3)]);
或者使用模板函数:
template inline
valarray VA(const T &valarray_subset)
{
return valarray(valarray_subset);
}
va[slice(0, 4, 3)] = VA(va[slice(1, 4, 3)]) * VA(va[slice(2, 4, 3)];
然而上面存在着性能损失。你也可以使用简单的类型定义:
typedef valarray VAD;
va[slice(0, 4, 3)] = VAD(va[slice(1, 4, 3)]) * VAD(va[slice(2, 4, 3)];
[Slices]
slice定义了一个索引集合,具有三个属性:
1.开始索引
2.元素个数
3.元素之间的距离(步长)
注意:索引集合中索引的有效性由使用者保证。
步长可以为负数。例如:
slice(9, 5, -2)
指定的索引为:
9 7 5 3 1
若valarray是常量,则由slice指定的子集为一个新的valarray,否则该子集为原始valarray的引用(该功能由辅助类slice_array提供)。
[General Slices]
gslices可以处理多维数组的子集,具有三个属性:
1.开始索引
2.维度数组(高维到低维)
3.对应维度的元素之间的距离(步长)
与slice的使用方法基本类似。
[Masked Subsets]
Mask arrays提供了另外一种定义valarray子集的方法。你可以通过对valarray使用布尔操作产生mask array,mask array中的每个元素代表相应的valarray元素是否满足布尔条件。
[Indirect Subsets]
Indirect subsets提供了第四种定义valarray子集的方法(valarray[索引valarray])。