The <valarray>
header declares types and functions for operating on arrays of numerical values. The intention is to provide types that could be optimized on certain hardware platforms for computationally-intensive programs. The consensus in the C++ user community seems to be that the standard failed to live up to the intentions. If you are writing numerical programs, take a look at the Blitz++ project (described in Appendix ###) and see if that meets your needs. Most programs do not need <valarray>
.
A valarray
is a one-dimensional array of numerical values. The array can grow at runtime. All the arithmetic operators and mathematical functions are overloaded to work with two valarray
arguments or with a valarray
and a scalar. You can also work with parts of an array: slices, generalized slices, masks, and indirect arrays.
A slice is a set of elements of a valarray
, with a starting index, a count, and a stride (an index interval). A generalized slice (gslice
) lets the stride count and length vary, which can be used to implement multidimensional arrays. A mask is a valarray
of flags, where the flags indicate whether the corresponding item is part of the masked array. An indirect array is an array of indices. Each of these concepts is explained further in this section.
The most important distinguishing feature of valarray
is that they do not allow aliasing, that is, an object cannot be an element of more than one valarray
. This enables additional optimizations that are not possible on ordinary arrays.
Because valarray is optmized for performance, no error-checking is performed. Referring to an index out of range or operating on arrays of different size result in undefined behavior--the same as with ordinary arrays. Unlike ordinary arrays, a convenient size()
method helps you ensure you do not make mistakes.
See the <cmath>
header for scalar mathematical functions and <numeric>
for a few numeric algorithms. See <complex>
for complex numbers.
Throught this section, examples show valarray
objects and subsets printed using operator<<
. Example 13-42 shows these functions.
Example 13-42: Printing a valarray or subset array.
// Print a valarray on one line, enclosed by curly braces, // e.g., "{ 1 2 3 }". template<typename T> void print_valarray(std::ostream& out, const std::valarray<T>& a) { out << '{'; for (size_t i = 0; i < a.size(); ++i) out << ' ' << a[i]; out << " }"; } // Print a slice_array, gslice_array, etc., by converting // to a valarray. Converting a valarray to a valarray is // wasteful, but harmless for these simple examples. template<template<typename T> class U, typename T> std::ostream& operator<<(std::ostream& out, const U<T>& x) { print_valarray(out, static_cast<std::valarray<T> >(x)); return out; }
Absolute value
template<typename T> valarray<T> abs(const valarray<T>& a);
Computes the absolute value of the elements of a
.
abs in <cmath>, abs in <cstdlib>
Inverse cosine
template<typename T> valarray<T> acos(const valarray<T>& a);
Computes the inverse cosine of the elements of a
.
acos in <cmath>
Inverse sine
template<typename T> valarray<T> asin(const valarray<T>& a);
Computes the inverse cosine of the elements of a
.
asin in <cmath>
Inverse tangent
template<typename T> valarray<T> atan(const valarray<T>& a);
Computes the inverse tangent of the elements of a
.
atan2 function template, atan in <cmath>
Inverse tangent of two arguments
template<typename T> valarray<T> atan2(const valarray<T>& b, const valarray<T>& a); template<typename T> valarray<T> atan2(const valarray<T>& b, const T& x); template<typename T> valarray<T> atan2(const T& y, const valarray<T>& a);
Computes the inverse tangent of y/x
., where y
is a scalar or an element of b
, and x
is a scalar or an element of a
.
atan function template, atan2 in <cmath>
Cosine
template<typename T> valarray<T> cos(const valarray<T>& a);
Computes the cosine of each element of a
.
cos in <cmath>
Hyperbolic cosine
template<typename T> valarray<T> cosh(const valarray<T>& a);
Computes the hyperbolic cosine of each element of a
.
cosh in <cmath>
Exponential
template<typename T> valarray<T> exp(const valarray<T>& a);
Computes the exponential ex for each element x
of a
.
exp in <cmath>
Generalized slice
class gslice { public: gslice(); gslice(size_t start, const valarray<size_t>& size, const valarray<size_t>& stride); size_t start() const; valarray<size_t> size() const; valarray<size_t> stride() const; };
The gslice
class describes a generalized slice of a valarray
. A generalized slice is a subset of the elements of a valarray
, characterized by a starting index, and a set of sizes and strides. The size
and stride
arrays must have the same size. Each size/stride pair denotes a set of elements at periodic indices. The number of elements is equal to the product of the values in the size
array. The elements are taken from a valarray
at each index i where
i = start
+ sigma kj × stride
j
and kj takes all the values in the range [0, size
[j]) and j is in the range [0, stride.size()
). The highst value of j varies fastest. With a single element in stride and size, gslice
is the same as plain slice
. Example 13-43 demonstrates gslice
more clearly. Pay particular attention to the final gslice
, where you can see how the indices advance, first with a stride of 3 (k1 ranges from 0 to 2), then with a stride of 2 (k0 ranges from 0 to 3).
Example 13-43: Generalized slicing of a valarray.
// Construct valarray objects from a few integers. std::valarray<size_t> va(size_t a0) { std::valarray<size_t> result(1); result[0] = a0; return result; } std::valarray<size_t> va(size_t a0, size_t a1) { std::valarray<size_t> result(2); result[0] = a0; result[1] = a1; return result; } int main() { valarray<int> a(24); for (size_t i = 0; i < a.size(); ++i) a[i] = i; cout << a << '\n'; // prints { 0 1 2 3 4 5 6 7 8 9 10 11 ... 20 21 22 23 } cout << a[slice(1, 4, 3)] << '\n'; // prints { 1 4 7 10 } cout << a[gslice(1, va(4), va(3))] << '\n'; // prints { 1 4 7 10 } const valarray<int> const_a(a); cout << const_a[gslice(2, va(4, 3), va(2, 3))] << '\n'; // prints { 2 5 8 4 7 10 6 9 12 8 11 14 } }
Notice also that the final gslice
requires a const
valarray
. That's because it contains degenerate slices, where an element (e.g., 8) appears more than once in the result. The aliasing rules of a valarray
prohibit multiple references to the same element, so if a const
valarray
were not used, the results would be undefined. By using a const
valarray
, the result is a copy of the sliced elements, so the two occurrences of element 8 are separate objects, not aliases for the same object, and disaster is averted.
A generalized slice is most often used to represent a multidimensional array. For example, you can treat a valarray of 24 elements as a 2 × 3 × 4 matrix. To extract a plane of the matrix, you can use a gslice
,. Figure 13-28 depicts the matrix and the plane. Example 13-44 shows the code.
Figure 13-28: A 3-D matrix stored in a valarray.
Example 13-44: Using gslice for multidimensional arrays.
valarray<int> a(24); for (size_t i = 0; i < a.size(); ++i) a[i] = i; cout << a[gslice(1, va(2, 3), va(12, 4))] << '\n';
To create an n-dimensional submatrix of an m-dimensional matrix, the size
and stride
arrays must both have length n. The size
array determines the dimensions of the result.
Use the subscript operator to take a generalized slice of a valarray
. You can assign a valarray
to a generalized slice, where the right-hand side of the assignment must have the same size as the size of the slice. You can also convert the slice to a valarray
, which copies only those elements of the slice to the new valarray
.
When you take a generalized slice of a valarray
, the result is a gslice_array
object, but the gslice_array
type is mostly transparent to the programmer. See gslice_array
, later in this section, for details.
gslice_array class template, slice class
Helper class for generalized slices
template <typename T> class gslice_array { public: typedef T value_type; void operator=(const valarray<T>&) const; void operator*=(const valarray<T>&) const; void operator/=(const valarray<T>&) const; void operator%=(const valarray<T>&) const; void operator+=(const valarray<T>&) const; void operator-=(const valarray<T>&) const; void operator^=(const valarray<T>&) const; void operator&=(const valarray<T>&) const; void operator|=(const valarray<T>&) const; void operator<<=(const valarray<T>&) const; void operator>>=(const valarray<T>&) const; void operator=(const T&); ~gslice_array(); private: gslice_array(); gslice_array(const gslice_array&); gslice_array& operator=(const gslice_array&); };
The gslice_array
class template represents a subset of the elements of a valarray
, called a generalized slice. To create an generalized slice, use valarray
's operator[]
with an argument of type gslice
.
For some operations, the gslice_array
object is transparent. In particular, you can assign a valarray
to a gslice_array
object (provided they have the same size), or you can construct a new valarray
from a gslice_array
.
If you want to perform other operations, such as non-assignment arithmetic, you must explicitly convert the gslice_array
to valarray
, as demonstrated in Example 13-45.
Example 13-45: Using gslice_array.
int main() { using namespace std; const int data[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; valarray<int> a(data, sizeof(data)/sizeof(data[0])); cout << a << '\n'; // prints { 1 2 3 4 5 6 7 8 } cout << a[gslice(1, va(2, 2), va(4, 2))] << '\n' << a[gslice(0, va(2, 2), va(4, 2))] << '\n'; // prints: // { 2 4 6 8 } // { 1 3 5 7 } // operator+ is not defined for gslice_array, so cast // to valarray to perform addition. cout << static_cast<valarray<int> >(a[gslice(1, va(2,2), va(4,2))]) + static_cast<valarray<int> >(a[gslice(0, va(2,2), va(4,2))]) << '\n'; // prints: { 3 7 11 15 } // Simple assignment does not require casting. a[gslice(0, va(2, 2), va(4, 2))] = 0; cout << a << '\n'; // prints: { 0 2 0 4 0 6 0 8 } // Computational assignment does not require casting. valarray<int> ten(10, 4); a[gslice(1, va(2, 2), va(4, 2))] *= ten; cout << a << '\n'; // prints: { 0 20 0 40 0 60 0 80 } }
The members of gslice_array
are straightforward. When using any of the assignment operators, the valarray
on the right-hand side must be the same size as the gslice_array
on the left-hand side. You can also assign a scalar to every element of the array. Note that the default constructor, copy constructor, and copy assignment operator are all private. The purpose is to restrict the use of gslice_array
except as a return value from valarray
's operator[]
.
gslice class, indirect_array class template, mask_array class template, slice_array class template, valarray class template
Helper class for indirect arrays
template <typename T> class indirect_array { public: typedef T value_type; void operator=(const valarray<T>&) const; void operator*=(const valarray<T>&) const; void operator/=(const valarray<T>&) const; void operator%=(const valarray<T>&) const; void operator+=(const valarray<T>&) const; void operator-=(const valarray<T>&) const; void operator^=(const valarray<T>&) const; void operator&=(const valarray<T>&) const; void operator|=(const valarray<T>&) const; void operator<<=(const valarray<T>&) const; void operator>>=(const valarray<T>&) const; void operator=(const T&); ~indirect_array(); private: indirect_array(); indirect_array(const indirect_array&); indirect_array& operator=(const indirect_array&); };
The indirect_array
class template represents a subset of the elements of a valarray
. To create an indirect subset, use valarray
's operator[]
with an argument of type valarray<size_t>
. The elements of the argument are the desired indices in the subset.
For some operations, the indirect_array
object is transparent. In particular, you can assign a valarray
to an indirect_array
object (provided they have the same size), or you can construct a new valarray
from an indirect_array
.
If you want to perform other operations, such as non-assignment arithmetic, you must explicitly convert the indirect_array
to valarray
, as demonstrated in Example 13-46.
Example 13-46: Using indirect_array:
int main() { using namespace std; const int data[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; valarray<int> a(data, sizeof(data)/sizeof(data[0])); cout << a << '\n'; // Specify the indices into a. const size_t p[] = { 2, 3, 5, 7 }; valarray<size_t> indices(p, sizeof(p)/sizeof(p[0])); cout << a[indices] << '\n'; // Add 10 to the elements at the desired indices. valarray<int> ten(10, 4); a[indices] += ten; cout << a << '\n'; // Must cast to perform ordinary arithmetic. cout << static_cast<valarray<int> >(a[indices]) * ten << '\n'; }
The members of indirect_array
are straightforward. When using any of the assignment operators, the valarray
on the right-hand side must be the same size as the indirect_array
on the left-hand side. You can also assign a scalar to every element of the array. Note that the default constructor, copy constructor, and copy assignment operator are all private. The purpose is to restrict the use of indirect_array
except as a return value from valarray
's operator[]
.
gslice_array class template, mask_array class template, slice_array class template, valarray class template
Natural logarithm
template<typename T> valarray<T> log(const valarray<T>& a);
Computes the natural (base e) logarithm of each element of a
.
log in <cmath>
Common logarithm
template<typename T> valarray<T> log10(const valarray<T>& a);
Computes the common (base 10) logarithm of each element of a
.
log10 in <cmath>
Helper class for mask arrays
template <typename T> class mask_array { public: typedef T value_type; void operator= (const valarray<T>&) const; void operator*= (const valarray<T>&) const; void operator/= (const valarray<T>&) const; void operator%= (const valarray<T>&) const; void operator+= (const valarray<T>&) const; void operator-= (const valarray<T>&) const; void operator^= (const valarray<T>&) const; void operator&= (const valarray<T>&) const; void operator|= (const valarray<T>&) const; void operator<<=(const valarray<T>&) const; void operator>>=(const valarray<T>&) const; void operator=(const T&); ~mask_array(); private: mask_array(); mask_array(const mask_array&); mask_array& operator=(const mask_array&); };
The mask_array
class template represents a subset of the elements of a valarray
. To create a mask subset, use valarray
's operator[]
with an argument of type valarray<bool>
. An element is included in the result set if the corresponding element in the argument is true
.
For some operations, the mask_array
object is transparent. In particular, you can assign a valarray
to an mask_array
object (provided they have the same size), or you can construct a new valarray
from an mask_array
.
If you want to perform other operations, such as non-assignment arithmetic, you must explicitly convert the mask_array
to valarray
, as demonstrated in Example 13-47.
Example 13-47: Using mask_array:
// Simple average. template<typename T> T avg(const std::valarray<T>& a) { return a.sum() / a.size(); } int main() { using namespace std; const int data[] = { 1, -3, 10, 42, -12, 13, -7, 69 }; valarray<int> a(data, sizeof(data)/sizeof(data[0])); cout << a << '\n'; // prints: { 1 -3 10 42 -12 13 -7 69 } // Print the values that are above average. cout << "avg=" << avg(a) << '\n'; cout << a[a > avg(a)] << '\n'; // prints: { 42 69 } // Force all negative values to be zero. Notice how // no cast is needed for the simple assignment. a[a < 0] = 0; cout << a << '\n'; // prints: { 1 0 10 42 0 13 0 69 } // Other operations, such as multiplication by a scalar // is defined only for valarray, so a cast is needed. cout << static_cast<valarray<int> >(a[a > 0]) * -1 << '\n'; // prints: { -1 -10 -42 -13 -69 } }
The members of mask_array
are straightforward. When using any of the assignment operators, the valarray
on the right-hand side must be the same size as the mask_array
on the left-hand side. You can also assign a scalar to every element of the array. Note that the default constructor, copy constructor, and copy assignment operator are all private. The purpose is to restrict the use of mask_array
except as a return value from valarray
's operator[]
.
gslice_array class template, indirect_array class template, slice_array class template, valarray class template
Multiplication
template<typename T> valarray<T> operator*(const valarray<T>& a, const valarray<T>& b); template<typename T> valarray<T> operator*(const valarray<T>& a, const T& y); template<typename T> valarray<T> operator*(const T& x, const valarray<T>& b);
Multiplies each x
*
y
, where x
is a scalar or an element of a
, and y
is a scalar or an element of b
. When multiplying two arrays, they must have the same size. The resulting array has the same size as the argument array(s).
Division
template<typename T> valarray<T> operator/(const valarray<T>& a, const valarray<T>& b); template<typename T> valarray<T> operator/(const valarray<T>& a, const T& y); template<typename T> valarray<T> operator/(const T& x, const valarray<T>& b);
Divides each x
/
y
, where x
is a scalar or an element of a
, and y
is a scalar or an element of b
. When dividing two arrays, they must have the same size. The resulting array has the same size as the argument array(s).
Addition
template<typename T> valarray<T> operator+(const valarray<T>& a, const valarray<T>& b); template<typename T> valarray<T> operator+(const valarray<T>& a, const T& y); template<typename T> valarray<T> operator+(const T& x, const valarray<T>& b);
Adds each x
+
y
, where x
is a scalar or an element of a
, and y
is a scalar or an element of b
. When adding two arrays, they must have the same size. The resulting array has the same size as the argument array(s).
Subtraction
template<typename T> valarray<T> operator-(const valarray<T>& a, const valarray<T>& b); template<typename T> valarray<T> operator-(const valarray<T>& a, const T& y); template<typename T> valarray<T> operator-(const T& x, const valarray<T>& b);
Subtracts each x
-
y
, where x
is a scalar or an element of a
, and y
is a scalar or an element of b
. When subtracting two arrays, they must have the same size. The resulting array has the same size as the argument array(s).
Bitwise and
template<typename T> valarray<T> operator&(const valarray<T>& a, const valarray<T>& b); template<typename T> valarray<T> operator&(const valarray<T>& a, const T& y); template<typename T> valarray<T> operator&(const T& x, const valarray<T>& b);
Performs bitwise and on each x
&
y
, where x
is a scalar or an element of a
, and y
is a scalar or an element of b
. When operating on two arrays, they must have the same size. The resulting array has the same size as the argument array(s). The type T
must be one for which operator
&
is defined.
Bitwise or
template<typename T> valarray<T> operator|(const valarray<T>& a, const valarray<T>& b); template<typename T> valarray<T> operator|(const valarray<T>& a, const T& y); template<typename T> valarray<T> operator|(const T& x, const valarray<T>& b);
Performs bitwise or on each x
|
y
, where x
is a scalar or an element of a
, and y
is a scalar or an element of b
. When operating on two arrays, they must have the same size. The resulting array has the same size as the argument array(s). The type T
must be one for which operator
|
is defined.
Bitwise exclusive or
template<typename T> valarray<T> operator^(const valarray<T>& a, const valarray<T>& b); template<typename T> valarray<T> operator^(const valarray<T>& a, const T& y); template<typename T> valarray<T> operator^(const T& x, const valarray<T>& b);
Performs bitwise exclusive or on each x
^
y
, where x
is a scalar or an element of a
, and y
is a scalar or an element of b
. When operating on two arrays, they must have the same size. The resulting array has the same size as the argument array(s). The type T
must be one for which operator
^
is defined.
Right shift
template<typename T> valarray<T> operator>>(const valarray<T>& a, const valarray<T>& b); template<typename T> valarray<T> operator>>(const valarray<T>& a, const T& y); template<typename T> valarray<T> operator>>(const T& x, const valarray<T>& b);
Performs right shift on each x
>>
y
, where x
is a scalar or an element of a
, and y
is a scalar or an element of b
. When operating on two arrays, they must have the same size. The resulting array has the same size as the argument array(s). The type T
must be one for which operator
>>
is defined.
Left shift
template<typename T> valarray<T> operator<<(const valarray<T>& a, const valarray<T>& b); template<typename T> valarray<T> operator<<(const valarray<T>& a, const T& y); template<typename T> valarray<T> operator<<(const T& x, const valarray<T>& b);
Performs left shift on each x
<<
y
, where x
is a scalar or an element of a
, and y
is a scalar or an element of b
. When operating on two arrays, they must have the same size. The resulting array has the same size as the argument array(s). The type T
must be one for which operator
<<
is defined.
Logical and
template<typename T> valarray<bool> operator&&(const valarray<T>& a, const valarray<T>& b); template<typename T> valarray<bool> operator&&(const valarray<T>& a, const T& y); template<typename T> valarray<bool> operator&&(const T& x, const valarray<T>& b);
Performs logical and on each x
&&
y
, where x
is a scalar or an element of a
, and y
is a scalar or an element of b
. When operating on two arrays, they must have the same size. The resulting array has the same size as the argument array(s). The type T
must be one for which operator
&&
is defined. As with any other overloaded operator
&&
, short cut evaluation is not supported.
Logical or
template<typename T> valarray<bool> operator||(const valarray<T>& a, const valarray<T>& b); template<typename T> valarray<bool> operator||(const valarray<T>& a, const T& y); template<typename T> valarray<bool> operator||(const T& x, const valarray<T>& b);
Performs logical or on each x
||
y
, where x
is a scalar or an element of a
, and y
is a scalar or an element of b
. When operating on two arrays, they must have the same size. The resulting array has the same size as the argument array(s). The type T
must be one for which operator
||
is defined and yields a bool
result or a result that can be converted to bool
. As with any other overloaded operator
||
, short cut evaluation is not supported.
Compare for equality
template<typename T> valarray<bool> operator==(const valarray<T>& a, const valarray<T>& b); template<typename T> valarray<bool> operator==(const valarray<T>& a, const T& y); template<typename T> valarray<bool> operator==(const T& x, const valarray<T>& b);
Compares each x
==
y
, where x
is a scalar or an element of a
, and y
is a scalar or an element of b
. When operating on two arrays, they must have the same size. The resulting array has the same size as the argument array(s). The type T
must be one for which operator
==
is defined and yields a bool
result or a result that can be converted to bool
.
Compare for inequality
template<typename T> valarray<bool> operator!=(const valarray<T>& a, const valarray<T>& b); template<typename T> valarray<bool> operator!=(const valarray<T>& a, const T& y); template<typename T> valarray<bool> operator!=(const T& x, const valarray<T>& b);
Compares each x
!=
y
, where x
is a scalar or an element of a
, and y
is a scalar or an element of b
. When operating on two arrays, they must have the same size. The resulting array has the same size as the argument array(s). The type T
must be one for which operator
!=
is defined and yields a bool
result or a result that can be converted to bool
.
Compare for less than
template<typename T> valarray<bool> operator<(const valarray<T>& a, const valarray<T>& b); template<typename T> valarray<bool> operator<(const valarray<T>& a, const T& y); template<typename T> valarray<bool> operator<(const T& x, const valarray<T>& b);
Compares each x
<
y
, where x
is a scalar or an element of a
, and y
is a scalar or an element of b
. When operating on two arrays, they must have the same size. The resulting array has the same size as the argument array(s). The type T
must be one for which operator
<
is defined and yields a bool
result or a result that can be converted to bool
.
Compare for less than or equal
template<typename T> valarray<bool> operator<=(const valarray<T>& a, const valarray<T>& b); template<typename T> valarray<bool> operator<=(const valarray<T>& a, const T& y); template<typename T> valarray<bool> operator<=(const T& x, const valarray<T>& b);
Compares each x
<=
y
, where x
is a scalar or an element of a
, and y
is a scalar or an element of b
. When operating on two arrays, they must have the same size. The resulting array has the same size as the argument array(s). The type T
must be one for which operator
<=
is defined and yields a bool
result or a result that can be converted to bool
.
Compare for greater than
template<typename T> valarray<bool> operator>(const valarray<T>& a, const valarray<T>& b); template<typename T> valarray<bool> operator>(const valarray<T>& a, const T& y); template<typename T> valarray<bool> operator>(const T& x, const valarray<T>& b);
Compares each x
>
y
, where x
is a scalar or an element of a
, and y
is a scalar or an element of b
. When operating on two arrays, they must have the same size. The resulting array has the same size as the argument array(s). The type T
must be one for which operator
>
is defined and yields a bool
result or a result that can be converted to bool
.
Compare for greater than or equal
template<typename T> valarray<bool> operator>=(const valarray<T>& a, const valarray<T>& b); template<typename T> valarray<bool> operator>=(const valarray<T>& a, const T& y); template<typename T> valarray<bool> operator>=(const T& x, const valarray<T>& b);
Compares each x
>=
y
, where x
is a scalar or an element of a
, and y
is a scalar or an element of b
. When operating on two arrays, they must have the same size. The resulting array has the same size as the argument array(s). The type T
must be one for which operator
>=
is defined and yields a bool
result or a result that can be converted to bool
.
Power
template<typename T> valarray<T> pow(const valarray<T>& a, const valarray<T>& b); template<typename T> valarray<T> pow(const valarray<T>& a, const T& y); template<typename T> valarray<T> pow(const T& x, const valarray<T>& b);
Computes the power x
y where x
is a scalar or an element of a
, and y
is a scalar or an element of b
.
pow in <cmath>
Sine
template<typename T> valarray<T> sin(const valarray<T>& a);
Computes the sine of the elements of a
.
sin in <cmath>
Hyperbolic sine
template<typename T> valarray<T> sinh(const valarray<T>& a);
Computes the hyperbolic sine of the elements of a
.
sinh in <cmath>
Slice of an array
class slice { public: slice(); slice(size_t, size_t, size_t); size_t start() const; size_t size() const; size_t stride() const; };
The slice
class describes a slice of a valarray
. A slice is a subset of the elements of a valarray
at periodic indices. The slice has a starting index, a size, and a stride, where the stride is the index interval, as shown in Figure 13-27.
Figure 13-27: Slicing a valarray.
Use the subscript operator to take a slice of a valarray
. You can assign a valarray
to a slice, where the right-hand side of the assignment must have the same size as the size of the slice. You can also convert the slice to a valarray
, which copies only those elements of the slice to the new valarray
.
When you take a slice of a valarray
, the result is a slice_array
object, but the slice_array
type is mostly transparent to the programmer. See slice_array
, later in this section, for details.
You can use a slice to treat a valarray as a two-dimensional matrix. A slice can specify a row or column of the matrix. For an n × m matrix, row r is slice
(r*m, m, 1), and column c is slice
(c, n, m), as you can see in Example 13-48.
Example 13-48: A simple 2D matrix class.
template<typename T> class matrix2D { public: matrix2D(std::size_t rows, std::size_t columns) : rows_(rows), cols_(columns), data_(rows * columns) {} std::size_t rows() const { return rows_; } std::size_t cols() const { return cols_; } std::valarray<T> row(size_t r) const { return data_[std::slice(r*cols(),cols(), 1)]; } std::valarray<T> col(size_t c) const { return data_[std::slice(c, rows(), cols())]; } std::slice_array<T> row(size_t r) { return data_[std::slice(r*cols(),cols(), 1)]; } std::slice_array<T> col(size_t c) { return data_[std::slice(c, rows(), cols())]; } T& operator()(size_t r, size_t c) { return data_[r*cols()+c]; } T operator()(size_t r, size_t c) const { return row(r)[c]; } matrix2D<T> transpose() { matrix2D<T> result(cols(), rows()); for (size_t i = 0; i < rows(); ++i) result.col(i) = static_cast<std::valarray<T> >(row(i)); return result; } private: std::size_t rows_; std::size_t cols_; std::valarray<T> data_; };
gslice class, slice_array class template
Helper class for slice
template <typename T> class slice_array { public: typedef T value_type; void operator=(const valarray<T>&) const; void operator*=(const valarray<T>&) const; void operator/=(const valarray<T>&) const; void operator%=(const valarray<T>&) const; void operator+=(const valarray<T>&) const; void operator-=(const valarray<T>&) const; void operator^=(const valarray<T>&) const; void operator&=(const valarray<T>&) const; void operator|=(const valarray<T>&) const; void operator<<=(const valarray<T>&) const; void operator>>=(const valarray<T>&) const; void operator=(const T&); ~slice_array(); private: slice_array(); slice_array(const slice_array&); slice_array& operator=(const slice_array&); };
The slice_array
class template represents a subset of the elements of a valarray
, taken at periodic indices, called a slice. To create a slice, use valarray
's operator[]
with an argument of type slice
.
For some operations, the slice_array
object is transparent. In particular, you can assign a valarray
to a slice_array
object (provided they have the same size), or you can construct a new valarray
from a slice_array
.
If you want to perform other operations, such as non-assignment arithmetic, you must explicitly convert the slice_array
to valarray
, as demonstrated in Example 13-49.
Example 13-49: Slicing a valarray.
int main() { using namespace std; const int data[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13 }; valarray<int> v(data, sizeof(data)/sizeof(data[0])); const int newdata[] = { 30, 70, 110 }; valarray<int> rpl(newdata, 3); v[slice(2, 3, 4)] = rpl; cout << v << '\n'; // prints: { 1 2 30 4 5 6 70 8 9 10 110 12 13} v[slice(3, 4, 2)] = -1; cout << v << '\n'; // prints: { 1 2 30 -1 5 -1 70 -1 9 -1 110 12 13} valarray<int> mult(3, 2); v[slice(8, 2, 3)] *= mult; cout << v << '\n'; // prints: { 1 2 30 -1 5 -1 70 -1 27 -1 110 36 13} cout << static_cast<valarray<int> >(v[slice(1, 5, 2)]) << '\n'; // prints: { 2 -1 -1 -1 -1} cout << static_cast<valarray<int> >(v[slice(4, 3, 2)]) + static_cast<valarray<int> >(v[slice(2, 3, 2)]) << '\n'; // prints: { 35 75 97} }
The members of slice_array
are straightforward. When using any of the assignment operators, the valarray
on the right-hand side must be the same size as the slice_array
on the left-hand side. You can also assign a scalar to every element of the array. Note that the default constructor, copy constructor, and copy assignment operator are all private. The purpose is to restrict the use of slice_array
except as a return value from valarray
's operator[]
.
gslice_array class template, indirect_array class template, mask_array class template, slice class, valarray class template
Square root
template<typename T> valarray<T> sqrt(const valarray<T>& a);
Computes the square root of the elements of a
.
sqrt in <cmath>
Tangent
template<typename T> valarray<T> tan(const valarray<T>& a);
Computes the tangent of the elements of a
.
tan in <cmath>
Hyperbolic tangent
template<typename T> valarray<T> tanh(const valarray<T>& a);
Computes the hyperbolic tangent of the elements of a
.
tanh in <cmath>
Array of values
template<typename T> class valarray { public: typedef T value_type; valarray(); explicit valarray(size_t); valarray(const T&, size_t); valarray(const T*, size_t); valarray(const valarray&); valarray(const slice_array<T>&); valarray(const gslice_array<T>&); valarray(const mask_array<T>&); valarray(const indirect_array<T>&); ~valarray(); valarray<T>& operator=(const valarray<T>&); valarray<T>& operator=(const T&); valarray<T>& operator=(const slice_array<T>&); valarray<T>& operator=(const gslice_array<T>&); valarray<T>& operator=(const mask_array<T>&); valarray<T>& operator=(const indirect_array<T>&); T operator[](size_t) const; T& operator[](size_t); valarray<T> operator[](slice) const; slice_array<T> operator[](slice); valarray<T> operator[](const gslice&) const; gslice_array<T> operator[](const gslice&); valarray<T> operator[](const valarray<bool>&) const; mask_array<T> operator[](const valarray<bool>&); valarray<T> operator[](const valarray<size_t>&) const; indirect_array<T> operator[](const valarray<size_t>&); valarray<T> operator+() const; valarray<T> operator-() const; valarray<T> operator~() const; valarray<bool> operator!() const; valarray<T>& operator*= (const T&); valarray<T>& operator/= (const T&); valarray<T>& operator%= (const T&); valarray<T>& operator+= (const T&); valarray<T>& operator-= (const T&); valarray<T>& operator^= (const T&); valarray<T>& operator&= (const T&); valarray<T>& operator|= (const T&); valarray<T>& operator<<=(const T&); valarray<T>& operator>>=(const T&); valarray<T>& operator*= (const valarray<T>&); valarray<T>& operator/= (const valarray<T>&); valarray<T>& operator%= (const valarray<T>&); valarray<T>& operator+= (const valarray<T>&); valarray<T>& operator-= (const valarray<T>&); valarray<T>& operator^= (const valarray<T>&); valarray<T>& operator|= (const valarray<T>&); valarray<T>& operator&= (const valarray<T>&); valarray<T>& operator<<=(const valarray<T>&); valarray<T>& operator>>=(const valarray<T>&); size_t size() const; T sum() const; T min() const; T max() const; valarray<T> shift (int) const; valarray<T> cshift(int) const; valarray<T> apply(T func(T)) const; valarray<T> apply(T func(const T&)) const; void resize(size_t sz, T c = T()); };
The valarray
class template represents an array of numeric values, with restrictions that permit an implementation to optimize performance. In particular, an object cannot be an element of more than one array. A subset, such as a generalized slice or indirect array, cannot specify a single element more than once, or else the behavior is undefined.
All the arithmetic operations and mathematical functions are declared for valarray
. The same rules apply to valarray
as to the underlying type, for example, you cannot use operator<<
on valarray<double>
because you cannot use operator<<
on scalars of type double
.
Examples of using valarray
can be found throughout this section.
Following are the members of valarray
:
valarray
()
valarray
.explicit
valarray
(size_t n)
valarray
of length n
, where all elements are initialized to T()
.
valarray
(const T& x, size_t n)
valarray
that contains n
copies of x
.
valarray
(const T* x, size_t n)
valarray
by copying n
elements from the array x
.
valarray
(const valarray& a)
valarray
by copying a
.
valarray
(const slice_array<T>& a)
valarray
(const gslice_array<T>& a)
valarray
(const mask_array<T>& a)
valarray
(const indirect_array<T>& a)
valarray
by copying the elements referenced by a
.valarray<T>
apply
(T func(T)) const
valarray<T>
apply
(T func(const T&)) const
func
for each element of the original array.valarray<T>
cshift
(int n) const
n
places. The return value is a new array that has the same size as the original, but the element at new index i comes from (i + n
) % size()
in the original.T
max
() const
operator<
.T
min
() const
operator<
.valarray<T>&
operator=
(const valarray<T>& a)
a
. If size()
!=
a.size()
, the behavior is undefined.valarray<T>&
operator=
(const T& x)
x
.valarray<T>&
operator=
(const slice_array<T>& a)
valarray<T>&
operator=
(const gslice_array<T>& a)
valarray<T>&
operator=
(const mask_array<T>& a)
valarray<T>&
operator=
(const indirect_array<T>& a)
a
. The value being assigned to an element must not depend on any other value in this array, that is, a
cannot be a subset of *this
or if it is, the element assigned to index i must depend only on index i and not on values at any other index.T
operator[]
(size_t i) const
T&
operator[]
(size_t i)
i
. The behavior is undefined for i
>=
size()
. The anti-aliasing rule means that for any two valarrays a
and b
, and for any valid indices i
and j
, &a[i]
!=
&b[j]
. All values in a single valarray
object are stored contiguously, just as in an ordinary array. References become invalid after a call to resize
.valarray<T>
operator[]
(slice) const
slice_array<T>
operator[]
(slice)
valarray<T>
operator[]
(const gslice&) const
gslice_array<T>
operator[]
(const gslice&)
valarray<T>
operator[]
(const valarray<bool>&) const
mask_array<T>
operator[]
(const valarray<bool>&)
valarray<T>
operator[]
(const valarray<size_t>&) const
indirect_array<T>
operator[]
(const valarray<size_t>&)
valarray
. A subset of a const
valarray
is a new valarray
. A subset of a non-const
valarray
is a helper object that maintains a reference to the original valarray
. See the descriptions of the helper classes, earlier in this section, for details. Briefly, the four kinds of subsets are as follows:slice
object specifies a simple slice, suitable for extracting a row or column of a 2-D array.gslice
is a generalized slice, which permits multidimensional matrices.mask_array
is created by specifying an array of bool
as the argument. Where an element is true, that element is part of the resulting subset.indirect_array
is created by specifying an array of indices (of type size_t
) as the argument. Each element specifies an index, and the element at that index is added to the resulting array.valarray<T>
operator+
() const
valarray<T>
operator-
() const
valarray<T>
operator~
() const
valarray<bool>
operator!
() const
valarray
where each new element is the result of applying the unary operator to the corresponding element in the original array.valarray<T>&
operator*=
(const T& x)
valarray<T>&
operator/=
(const T& x)
valarray<T>&
operator%=
(const T& x)
valarray<T>&
operator+=
(const T& x)
valarray<T>&
operator-=
(const T& x)
valarray<T>&
operator^=
(const T& x)
valarray<T>&
operator&=
(const T& x)
valarray<T>&
operator|=
(const T& x)
valarray<T>&
operator<<=
(const T& x)
valarray<T>&
operator>>=
(const T& x)
valarray
by applying the assignment operator to each element of the array. The return value is *this
.valarray<T>&
operator*=
(const valarray<T>& a)
valarray<T>&
operator/=
(const valarray<T>& a)
valarray<T>&
operator%=
(const valarray<T>& a)
valarray<T>&
operator+=
(const valarray<T>& a)
valarray<T>&
operator-=
(const valarray<T>& a)
valarray<T>&
operator^=
(const valarray<T>& a)
valarray<T>&
operator|=
(const valarray<T>& a)
valarray<T>&
operator&=
(const valarray<T>& a)
valarray<T>&
operator<<=
(const valarray<T>& a)
valarray<T>&
operator>>=
(const valarray<T>& a)
valarray
by applying the assignment operator to each element of the array and to the corresponding element of a
. The behavior is undefined if size()
!=
a.size()
. The return value is *this
.void
resize
(size_t sz, T x = T())
sz
and reinitializes every element of the array to x
.valarray<T>
shift
(int n) const
n
places. The return value is a new array with the same size as the original array, but the element at index i in the new array comes from index i + n
in the original array. If i + n
< 0 or >= size()
, the new element is set to T()
.size_t size() const
T
sum
() const
operator+=
. If the array is empty, the value is undefined.gslice class, gslice_array class template, indirect_array class template, mask_array class template, slice class, slice_array class template