Concepts / Introduction to the valarray Class

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.

  • Programming

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:

Formula

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?

  • {11, 22, 33}

  • {11, 12, 13}

  • {1, 2, 3, 10, 20, 30}

  • {10, 40, 90}

Reveal answer
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.

cpp
Output
11 22 33 
Notes on the code
  • 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.

cpp
Output
2 4 6 
1 2 3 
Notes on the code
  • 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.

cpp
Output
1 2 3 4 
Notes on the code
  • 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.

Aspectvectorvalarray
Main design goalGeneral mechanism for holding valuesNumerical computation
Fit with library architectureFits containers, iterators, and algorithmsVector-like template for numerical work
Mathematical operationsNot supported as vector operationsUsual arithmetic and common math functions
Generality versus optimizationMore general and flexibleLess 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 like

    After c = a + b, reading a still shows its original values.

    Why it fails

    Operations read their inputs and return new results rather than modifying the original arrays.

    Do this instead

    Store 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 like

    Expecting a + b with two 3-element arrays to produce a 6-element array.

    Why it fails

    The result combines values position by position, so it holds one value per position, not the concatenation of the inputs.

    Do this instead

    Think 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 like

    Writing a + b on two vector objects and expecting element-wise sums.

    Why it fails

    vector does not support mathematical vector operations because its design prioritizes generality.

    Do this instead

    Use 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 like

    Calling a function you have not seen in the course material and assuming it works on a whole valarray.

    Why it fails

    The source states that the most common functions are supported and does not give a complete list.

    Do this instead

    Check that a specific function is supported for valarray before relying on it.

Practice with Whole-Array Operations

EASY

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.

Related concepts

More concepts starting with I