Introduction to the valarray Class
valarray supports the usual arithmetic operations, so expressions such as a + b work on whole arrays and produce a new valarray.
Why Whole-Array Arithmetic Matters
Suppose you have a list of measurements and you want to scale every one of them, or combine two lists value by value. The first instinct in many programs is to write a loop, pick out each element, compute the result, and store it somewhere. The valarray class in C++ is built to make this kind of work read more directly. Its operations are written as though the whole collection were a single value, and the same operator that works on one number works on the whole collection.
This article looks at the two capabilities the course material highlights for valarray: the usual arithmetic operations, and the most common mathematical functions. Both are supported directly on valarray objects, so you can work with a whole array at once rather than handling every element by hand in your own code.
Position-by-Position Arithmetic
The usual arithmetic operations are supported for valarray objects. Addition, multiplication, and the other ordinary arithmetic operators can be applied to a valarray, and the result is again a valarray. The practical effect is that an expression such as a + b takes two arrays and produces a new array, without you writing the indexing loop yourself.
The easiest way to picture the result is position by position. If the two inputs each hold values at positions 0, 1, and 2, the sum holds the sum of the value at position 0 from each input, then the sum at position 1, and so on. Written as a rule for an element at index i, the result works like this:
Here a_{i} and b_{i} are the values at position i in the two arrays, and c_{i} is the value at the same position in the result. Every position is handled by the same rule, and the rule never names a particular position. That is the core idea: one expression describes the work for all positions at once.
The diagram shows the pairing. Position 0 of the result holds 11 because the 1 from a and the 10 from b were combined there, and the other positions follow the same rule. The arithmetic line in the program never names an individual position, which is the point of working on the whole array.
Predicting the Result of a + b
What do you think happens?
If a holds {1, 2, 3} and b holds {10, 20, 30}, what does c = a + b contain?
Reveal answer
{11, 22, 33}
Each position is combined with the value at the same position in the other array: 1 + 10 = 11, 2 + 20 = 22, and 3 + 30 = 33. The result is a new valarray of the same length, not a longer array holding both inputs.
11 22 33 - The header <valarray> provides the valarray template.
- a + b is written as one expression that acts on the whole array.
- The loop only prints the result; it is not needed to perform the addition.
Scalar Operands and the Original Array
The same pattern holds for scalar operations, where a single number such as 2 is combined with every element of the array. The number is applied at each position, so the scalar behaves as though it were matched against every value in turn. The result is a new valarray, and the original array keeps its values.
2 4 6
1 2 3 - a * 2 produces a new valarray d.
- The second loop prints a, which still holds 1, 2, 3.
Mathematical Functions on a Whole valarray
Beyond the basic operators, the most common mathematical functions are supported for valarray objects. A function of this kind takes the whole array and returns an array of results, one for each element. This lets you write a single call in place of a loop that visits each value.
1 2 3 4 - A single call to std::sqrt acts on every element.
- The input array holds perfect squares, so each root is a whole number.
The square root case is an illustration of the idea rather than a complete catalogue. The source material does not list every supported function, so when you need a specific function, check that it is available for valarray before relying on it.
Why vector Was Not Extended
The vector container was designed to be a general mechanism for holding values. It is meant to be flexible and to fit into the architecture of containers, iterators, and algorithms. Because of this design, vector does not support mathematical vector operations. A natural question follows: if vector is so useful for holding values, why not simply add mathematical operations to it? The source answers that question directly. Adding mathematical operations to vector would be easy, but its generality and flexibility preclude optimizations often considered essential for serious numerical work.
The standard library provides valarray, in the header <valarray>, as a vector-like template for numerical computation. The word vector-like is important. valarray shares the basic idea of a template that holds a sequence of values, but its purpose is different. Where vector aims at generality, valarray aims at numerical work that benefits from optimization. valarray is less general than vector and is more amenable to optimization, and that trade-off is the reason it exists as a separate template.
| Aspect | vector | valarray |
|---|---|---|
| Main design goal | General mechanism for holding values | Numerical computation |
| Fit with library architecture | Fits containers, iterators, and algorithms | Vector-like template for numerical work |
| Mathematical operations | Not supported as vector operations | Usual arithmetic and common math functions |
| Generality versus optimization | More general and flexible | Less general and more amenable to optimization |
Design trade-off between the two templates
Mistakes to Avoid
Common mistake Assuming that a + b changes a or b
What it looks likeAfter c = a + b, reading a still shows its original values.
Why it failsOperations read their inputs and return new results rather than modifying the original arrays.
Do this insteadStore the result in a new valarray, or assign it back explicitly if you want to overwrite an existing one.
Common mistake Expecting a valarray result to contain both inputs side by side
What it looks likeExpecting a + b with two 3-element arrays to produce a 6-element array.
Why it failsThe result combines values position by position, so it holds one value per position, not the concatenation of the inputs.
Do this insteadThink of the result as a new array with the same number of positions, where each value is the combination of the two values at that position.
Common mistake Assuming vector supports the same arithmetic as valarray
What it looks likeWriting a + b on two vector objects and expecting element-wise sums.
Why it failsvector does not support mathematical vector operations because its design prioritizes generality.
Do this insteadUse valarray when the work is numerical and element-wise, and keep vector for general value storage.
Common mistake Assuming every mathematical function is available for valarray
What it looks likeCalling a function you have not seen in the course material and assuming it works on a whole valarray.
Why it failsThe source states that the most common functions are supported and does not give a complete list.
Do this insteadCheck that a specific function is supported for valarray before relying on it.
Practice with Whole-Array Operations
Let x hold {2, 5, 8} and y hold {1, 1, 1}, both as valarray<int>. Predict the contents of z = x + y and w = x * 3, and state whether x changes after each operation.
Hints
- Combine the values at each position separately, just as you would for c_{i} = a_{i} + b_{i}.
- A scalar such as 3 is applied to every element of x.
- Operations return new results, so check x after each line.
Key Takeaways
- valarray supports the usual arithmetic operations, so an expression such as a + b works on whole arrays and produces a new valarray.
- Arithmetic works position by position: the result at each index combines the values found at that index, and scalars are applied to every element.
- Operations read their inputs and return new results; they do not modify the original arrays.
- The most common mathematical functions, such as square root, act on every element of a valarray in a single call.
- vector is a general container that does not support mathematical vector operations, while valarray is a vector-like template designed for numerical work, trading generality for amenability to optimization.