Any operation that works on the underlying type, also works on the valarray in the same way.

A valarray is simply an array of values. It is templated on its value type, so for example a `stdext::valarray <float>`

is an array of floats and a `stdext::valarray <long>`

is an array of long integers.

Before you start using valarrays, remember to `#include <macvalarray.h>`

in your code to get the Altivec-optimized valarrays.

You can construct a valarray from a regular C array (or pointer):

`float af1 [] = {0, 1, 2, 3};`

`stdext::valarray <float> vf1 (af1, 4); // construct from first 4 elements of a1`

You can also construct a valarray with each element set to the same value:

`stdext::valarray <float> vf1 (10, 3.0f); // construct with 10 repeats of 3.0f`

Or you can construct a valarray with each element set to zero (really, the default-constructed value):

`stdext::valarray <float> vf1 (10); // construct with 10 repeats of 0.0f`

Once you’ve got a valarray, you can access it element by element, just like a regular C array:

`float f1 = vf1 [0]; // set f1 to the zeroth element of v1`

vf1 [0] = 2.0f; // set the zeroth element of v1 to 2.0f

But unlike their unsafe variants, a valarray knows its own size:

`size_t len = vf1.size (); // set len to the size of v1`

The valarray allows you to treat various subsets as if they were valarrays themselves.

So far so good. But what’s really cool is that any operation that works on the underlying type, also works on the valarray in the same way. For example:

`// do f1 = f2 * f3 + f4 for all the corresponding elements`

`vf1 = vf2 * vf3 + vf4;`

That includes various transcendentals as well:

`// do f1 = sin (f2) + cos (f3) for all the corresponding elements`

vf1 = sin (vf2) + cos (vf3);

Mixing and matching with the underlying value type is possible too:

`// do f1 = f2 * 2.0f - f3 for all the corresponding elements`

`vf1 = vf2 * 2.0f - vf3;`

You can summarize the entire valarray using `sum`

, `min`

or `max`

:

`float f1 = vf1.sum (); // set f1 to the sum of all values`

float f2 = vf1.min (); // set f2 to the minimum value

float f3 = vf1.max (); // set f3 to the maximum value

A powerful feature of the valarray allows you to treat various subsets of a valarray as if they were valarrays themselves. You use the different overloads of operator[] to do this.

For example, you can use a `stdext::valarray <bool>`

as a mask: a value in the original array is selected if the corresponding value in the mask is true, or not selected if it is false:

`bool b [] = {true, true, false, true, false, true};`

stdext::valarray <bool> vb (b, 6);

// set v1 to elements 0, 1, 3 and 5 of v2

vf1 = vf2 [vb];

You can use a `stdext::valarray <size_t>`

as an indirection: the original array is indexed by each value in the indirection, and that value is selected:

`size_t l [] = {2, 4, 7, 8};`

stdext::valarray <size_t> vl (sz, 4);

// set v1 to elements 2, 4, 7 and 8 of v2

vf1 = vf2 [vl];

A slice has a start index, a stride or increment in index and a length or count of indices to select. Slicing a valarray selects those elements in that sequence of indices.

`// construct a slice start = 2, stride = 3 and length = 4`

stdext::slice sl (2, 3, 4);

// set v1 to elements 2, 2+3, 2+3+3 and 2+3+3+3 of v2

vf1 = vf2 [sl];

With these building blocks, you can express some complicated concepts simply and succinctly.

For example, to calculate a dot product:

`float f1 = (vf1 * vf2).sum ();`

To select all the positive elements in a valarray:

`stdext::valarray <float> vf1 = vf2 [vf2 >= 0.0f];`