```
______________________________________________________________________

26   Numerics library                         [lib.numerics]

______________________________________________________________________

1 This clause describes components that C++ programs may use to  perform
seminumerical operations.

2 The  following subclauses describe components for complex number types
(_lib.complex_), numeric arrays (_lib.numarray_), generalized  numeric
algorithms (_lib.numeric.ops_), and facilities included from the ISO C
library (_lib.c.math_).

26.1  Complex numbers                                    [lib.complex]

--<complex>

2 Table 1:

+----------------------------------------------------------------------------+
|                Type                                 Name(s)                |
+----------------------------------------------------------------------------+
|Macro:                                 __STD_COMPLEX                        |
+----------------------------------------------------------------------------+
|Classes:                               double_complex                       |
|float_complex                          long_double_complex                  |
+----------------------------------------------------------------------------+
|Operator functions:                                                         |
|operator!= (double_complex) [3]        operator-= (float_complex)           |
|operator!= (float_complex) [3]         operator-= (long_double_complex)     |
|operator!= (long_double_complex) [3]   operator/  (double_complex) [3]      |
|operator*  (double_complex) [3]        operator/  (float_complex) [3]       |
|operator*  (float_complex) [3]         operator/  (long_double_complex) [3] |
|operator*  (long_double_complex) [3]   operator/= (double_complex)          |
|operator*= (double_complex)            operator/= (float_complex)           |
|operator*= (float_complex)             operator/= (long_double_complex)     |
|operator*= (long_double_complex)       operator<< (double_complex)          |
|operator+  (double_complex) [4]        operator<< (float_complex)           |
|operator+  (float_complex) [4]         operator<< (long_double_complex)     |
|operator+  (long_double_complex) [4]   operator== (double_complex) [3]      |
|operator+= (double_complex)            operator== (float_complex) [3]       |
|operator+= (float_complex)             operator== (long_double_complex) [3] |
|operator+= (long_double_complex)       operator>> (double_complex)          |
|operator-  (double_complex) [4]        operator>> (float_complex)           |
|operator-  (float_complex) [4]         operator>> (long_double_complex)     |
|operator-  (long_double_complex) [4]                                        |
|operator-= (double_complex)                                                 |
+----------------------------------------------------------------------------+

+---------------------------------------------------------+
|           Type                        Name(s)           |
+---------------------------------------------------------+
|Functions:                                               |
|abs  (double_complex)         norm (double_complex)      |
|abs  (float_complex)          norm (float_complex)       |
|abs  (long_double_complex)    norm (long_double_complex) |
|arg  (double_complex)         polar(double_complex)      |
|arg  (float_complex)          polar(float_complex)       |
|arg  (long_double_complex)    polar(long_double_complex) |
|conj  (double_complex)        pow  (double_complex)      |
|conj  (float_complex)         pow  (float_complex)       |
|conj  (long_double_complex)   pow  (long_double_complex) |
|cos  (double_complex)         real (double_complex)      |
|cos  (float_complex)          real (float_complex)       |
|cos  (long_double_complex)    real (long_double_complex) |
|cosh (double_complex)         sin  (double_complex)      |
|cosh (float_complex)          sin  (float_complex)       |
|cosh (long_double_complex)    sin  (long_double_complex) |
|exp  (double_complex)         sinh (double_complex)      |
|exp  (float_complex)          sinh (float_complex)       |
|exp  (long_double_complex)    sinh (long_double_complex) |
|imag (double_complex)         sqrt (double_complex)      |
|imag (float_complex)          sqrt (float_complex)       |
|imag (long_double_complex)    sqrt (long_double_complex) |
|log  (double_complex)         _double_complex            |
|log  (float_complex)          _float_complex             |
|log  (long_double_complex)                               |
+---------------------------------------------------------+

3 The header <complex> defines a macro, three types, and numerous  func­
tions for representing and manipulating complex numbers.

4 The macro is:
__STD_COMPLEX

5 whose definition is unspecified.

26.1.1  Complex numbers types                      [lib.complex.types]

26.1.1.1  Class float_complex                      [lib.float.complex]
class float_complex {
public:
float_complex(float re_arg = 0, im_arg = 0);
float_complex& operator+=(float_complex rhs);
float_complex& operator-=(float_complex rhs);
float_complex& operator*=(float_complex rhs);
float_complex& operator/=(float_complex rhs);
private:
//      float re, im;   exposition only
};

1 The  class float_complex describes an object that can store the Carte­
sian components, of type float, of a complex number.

2 For the sake of exposition, the maintained data is presented here as:

--float re, the real component;

--float im, the imaginary component.

26.1.1.1.1  float_complex constructor         [lib.float.complex.cons]
float_complex(float re_arg = 0, im_arg = 0);

1 Constructs an object of class float_complex, initializing re to re_arg
and im to im_arg.

26.1.1.1.2  operator+=                                   [lib.op+=.fc]
float_complex& operator+=(float_complex rhs);

1 Adds  the  complex value rhs to the complex value *this and stores the
sum in *this.  The function returns *this.

26.1.1.1.3  operator-=                                   [lib.op-=.fc]
float_complex& operator-=(float_complex rhs);

1 Subtracts the complex value rhs  from  the  complex  value  *this  and
stores the difference in *this.  The function returns *this.

26.1.1.1.4  operator*=                                   [lib.op*=.fc]
float_complex& operator*=(float_complex rhs);

1 Multiplies the complex value rhs by the complex value *this and stores
the product in *this.  The function returns *this.

26.1.1.1.5  operator/=                                   [lib.op/=.fc]
float_complex& operator/=(float_complex rhs);

1 Divides the complex value rhs into the complex value *this and  stores
the quotient in *this.  The function returns *this.

26.1.1.2  float_complex operations             [lib.float.complex.ops]

26.1.1.2.1  _float_complex                      [lib.float.complex.dc]
float_complex _float_complex(const double_complex& rhs);
float_complex _float_complex(const long_double_complex& rhs);

1 Returns float_complex((float)real(rhs), (float)imag(rhs)).

26.1.1.2.2  operator+                                  [lib.op+.fc.fc]
float_complex operator+(float_complex lhs);

1 Returns float_complex(lhs).
float_complex operator+(float_complex lhs, float_complex rhs);
float_complex operator+(float_complex lhs, float rhs);
float_complex operator+(float lhs, float_complex rhs);

2 Returns float_complex(lhs) += rhs.

26.1.1.2.3  operator-                                  [lib.op-.fc.fc]
float_complex operator-(float_complex lhs);

1 Returns float_complex(-real(lhs),-imag(lhs)).
float_complex operator-(float_complex lhs, float_complex rhs);
float_complex operator-(float_complex lhs, float rhs);
float_complex operator-(float lhs, float_complex rhs);

2 Returns float_complex(lhs) -= rhs.

26.1.1.2.4  operator*                                  [lib.op*.fc.fc]
float_complex operator*(float_complex lhs, float_complex rhs);
float_complex operator*(float_complex lhs, float rhs);
float_complex operator*(float lhs, float_complex rhs);

1 Returns float_complex(lhs) *= rhs.

26.1.1.2.5  operator/                                  [lib.op/.fc.fc]
float_complex operator/(float_complex lhs, float_complex rhs);
float_complex operator/(float_complex lhs, float rhs);
float_complex operator/(float lhs, float_complex rhs);

1 Returns float_complex(lhs) /= rhs.

26.1.1.2.6  operator==                                [lib.op==.fc.fc]
bool operator==(float_complex lhs, float_complex >rhs);

1 Returns real(lhs) == real(rhs) && imag(lhs) == imag(rhs).
bool operator==(float_complex lhs, float rhs);

2 Returns real(lhs) == rhs && imag(lhs) == 0.
bool operator==(float lhs, float_complex rhs);

3 Returns lhs == real(rhs) && imag(rhs) == 0.

26.1.1.2.7  operator!=                                [lib.op!=.fc.fc]
bool operator!=(float_complex lhs, float_complex rhs);

1 Returns real(lhs) != real(rhs) || imag(lhs) != imag(rhs).
bool operator!=(float_complex lhs, float rhs);

2 Returns real(lhs) != rhs || imag(lhs) != 0.
bool operator!=(float lhs, float_complex rhs);

3 Returns lhs != real(rhs) || imag(rhs) != 0.

26.1.1.2.8  operator>>                                    [lib.ext.fc]
istream& operator>>(istream& is, float_complex& x);

1 Evaluates the expression:

is >> ch && ch == '('
&& is >> re >> ch && ch == ','
&& is >> im >> ch && ch == ')';

2 where  ch  is an object of type char and re and im are objects of type
float.    If   the   result   is   nonzero,   the   function   assigns
float_complex(re, im) to x.

3 Returns is.

26.1.1.2.9  operator<<                                    [lib.ins.fc]
ostream& operator<<(ostream& os, float_complex x);

1 Returns os << '(' << real(x) << ',' << imag(x) << ')'.

26.1.1.3  Class double_complex                    [lib.double.complex]
class double_complex {
public:
double_complex(re_arg = 0, im_arg = 0);
double_complex(const float_complex& rhs);
double_complex& operator+=(double_complex rhs);
double_complex& operator-=(double_complex rhs);
double_complex& operator*=(double_complex rhs);
double_complex& operator/=(double_complex rhs);
private:
//    double re, im;    exposition only
};

1 The class double_complex describes an object that can store the Carte­
sian components, of type double, of a complex number.

2 For the sake of exposition, the maintained data is presented here as:

--double re, the real component;

--double im, the imaginary component.

26.1.1.3.1  double_complex constructors      [lib.double.complex.cons]
double_complex(double re_arg = 0, im_arg = 0);

1 Constructs  an  object  of  class  double_complex,  initializing re to
re_arg and im to im_arg.
double_complex(float_complex& rhs);

2 Constructs an object of class double_complex, initializing re to (dou­
ble)real(rhs) and im to (double)imag(rhs).

26.1.1.3.2  operator+=                                   [lib.op+=.dc]
double_complex& operator+=(double_complex rhs);

1 Adds  the  complex value rhs to the complex value *this and stores the
sum in *this.

2 Returns *this.

26.1.1.3.3  operator-=                                   [lib.op-=.dc]
double_complex& operator-=(double_complex rhs);

1 Subtracts  the  complex  value  rhs  from  the complex value *this and
stores the difference in *this.

2 Returns *this.

26.1.1.3.4  operator*=                                   [lib.op*=.dc]
double_complex& operator*=(double_complex rhs);

1 Multiplies the complex value rhs by the complex value *this and stores
the product in *this.

2 Returns *this.

26.1.1.3.5  operator/=                                   [lib.op/=.dc]
double_complex& operator/=(double_complex rhs);

1 Divides  the complex value rhs into the complex value *this and stores
the quotient in *this.

2 Returns *this.

26.1.1.4  double_complex operations           [lib.double.complex.ops]

26.1.1.4.1  _double_complex                   [lib.double.complex.ldc]
double_complex _double_complex(const long_double_complex& rhs);

1 Returns double_complex((double)real(rhs), (double)imag(rhs)).

26.1.1.4.2  operator+                                  [lib.op+.dc.dc]
double_complex operator+(double_complex lhs);

1 Returns double_complex(lhs).
double_complex operator+(double_complex lhs, double_complex rhs);
double_complex operator+(double_complex lhs, double rhs);
double_complex operator+(double lhs, double_complex rhs);

2 Returns double_complex(lhs) += rhs.

26.1.1.4.3  operator-                                  [lib.op-.dc.dc]
double_complex operator-(double_complex lhs);

1 Returns double_complex(-real(lhs),-imag(lhs)).
double_complex operator-(double_complex lhs, double_complex rhs);
double_complex operator-(double_complex lhs, double rhs);
double_complex operator-(double lhs, double_complex rhs);

2 Returns double_complex(lhs) -= rhs.

26.1.1.4.4  operator*                                  [lib.op*.dc.dc]
double_complex operator*(double_complex lhs, double_complex rhs);
double_complex operator*(double_complex lhs, double rhs);
double_complex operator*(double lhs, double_complex rhs);

1 Returns double_complex(lhs) *= rhs.

26.1.1.4.5  operator/                                  [lib.op/.dc.dc]
double_complex operator/(double_complex lhs, double_complex rhs);
double_complex operator/(double_complex lhs, double rhs);
double_complex operator/(double lhs, double_complex rhs);

1 Returns double_complex(lhs) /= rhs.

26.1.1.4.6  operator==                                [lib.op==.dc.dc]
bool operator==(double_complex lhs, double_complex rhs);

1 Returns real(lhs) == real(rhs) && imag(lhs) == imag(rhs).
bool operator==(double_complex lhs, double rhs);

2 Returns real(lhs) == rhs && imag(lhs) == 0.
bool operator==(double lhs, double_complex rhs);

3 Returns lhs == real(rhs) && imag(rhs) == 0.

26.1.1.4.7  operator!=                                [lib.op!=.dc.dc]
bool operator!=(double_complex lhs, double_complex rhs);

1 Returns real(lhs) != real(rhs) || imag(lhs) != imag(rhs).
bool operator!=(double_complex lhs, double rhs);

2 Returns real(lhs) != rhs || imag(lhs) != 0.
bool operator!=(double lhs, double_complex rhs);

3 Returns lhs != real(rhs) || imag(rhs) != 0.

26.1.1.4.8  operator>>                                    [lib.ext.dc]
istream& operator>>(istream& is, double_complex& x);

1 Evaluates the expression:
is >> ch && ch == '('
&& is >> re >> ch && ch == ','
&& is >> im >> ch && ch == ')';

2 where ch is an object of type char and re and im are objects  of  type
double.    If  the  result  is  nonzero,  the  function  assigns  dou­
ble_complex(re, im) to x.

3 The function returns is.

26.1.1.4.9  operator<<                                    [lib.ins.dc]
ostream& operator<<(ostream& os, double_complex x);

1 Returns os << '(' << real(x) << ',' << imag(x) << ')'.

26.1.1.5  Class long_double_complex          [lib.long.double.complex]
class long_double_complex {
public:
long_double_complex(re_arg = 0, im_arg = 0);
long_double_complex(const float_complex& rhs);
long_double_complex(const double_complex& rhs);
long_double_complex& operator+=(long_double_complex rhs);
long_double_complex& operator-=(long_double_complex rhs);
long_double_complex& operator*=(long_double_complex rhs);
long_double_complex& operator/=(long_double_complex rhs);
private:
//      long double re, im;     exposition only
};

1 The class long_double_complex describes an object that can  store  the
Cartesian components, of type long double, of a complex number.

2 For the sake of exposition, the maintained data is presented here as:

--long double re, the real component;

--long double im, the imaginary component.

26.1.1.5.1  long_double_complex         [lib.long.double.complex.cons]
constructors
long_double_complex(long double re_arg = 0, im_arg = 0);

1 Constructs an object of class long_double_complex, initializing re  to
re_arg and im to im_arg.
long_double_complex(float_complex& rhs);

2 Constructs  an object of class long_double_complex, initializing re to
(long double)real(rhs) and im to (long double)imag(rhs).
long_double_complex(double_complex& rhs);

3 Constructs an object of class long_double_complex, initializing re  to
(long double)real(rhs) and im to (long double)imag(rhs).

26.1.1.5.2  operator+=                                  [lib.op+=.ldc]
long_double_complex& operator+=(long_double_complex rhs);

1 Adds  the  complex value rhs to the complex value *this and stores the
sum in *this.

2 Returns *this.

26.1.1.5.3  operator-=                                  [lib.op-=.ldc]
long_double_complex& operator-=(long_double_complex rhs);

1 Subtracts  the  complex  value  rhs  from  the complex value *this and
stores the difference in *this.

2 Returns *this.

26.1.1.5.4  operator*=                                  [lib.op*=.ldc]
long_double_complex& operator*=(long_double_complex rhs);

1 Multiplies the complex value rhs by the complex value *this and stores
the product in *this.

2 Returns *this.

26.1.1.5.5  operator/=                                  [lib.op/=.ldc]
long_double_complex& operator/=(long_double_complex rhs);

1 Divides  the complex value rhs into the complex value *this and stores
the quotient in *this.

2 Returns *this.

26.1.1.6  long_double_complex            [lib.long.double.complex.ops]
operations

26.1.1.6.1  operator+                                [lib.op+.ldc.ldc]
long_double_complex operator+(long_double_complex lhs);

1 Returns long_double_complex(lhs).
long_double_complex operator+(long_double_complex lhs,
long_double_complex rhs);
long_double_complex operator+(long_double_complex lhs,
long double rhs);
long_double_complex operator+(long double lhs,
long_double_complex rhs);

2 Returns long_double_complex(lhs) += rhs.

26.1.1.6.2  operator-                                [lib.op-.ldc.ldc]
long_double_complex operator-(long_double_complex lhs);

1 Returns long_double_complex(-real(lhs),-imag(lhs)).
long_double_complex operator-(long_double_complex lhs,
long_double_complex rhs);
long_double_complex operator-(long_double_complex lhs,
long double rhs);
long_double_complex operator-(long double lhs,
long_double_complex rhs);

2 Returns long_double_complex(lhs) -= rhs.

26.1.1.6.3  operator*                                [lib.op*.ldc.ldc]
long_double_complex operator*(long_double_complex lhs,
long_double_complex rhs);

1 Returns long_double_complex(lhs) *= rhs.
long_double_complex operator*(long_double_complex lhs,
long double rhs);

2 Returns long_double_complex(lhs) *= long_double_complex(rhs).
long_double_complex operator*(long double lhs,
long_double_complex rhs);

3 Returns long_double_complex(lhs) *= rhs.

26.1.1.6.4  operator/                                [lib.op/.ldc.ldc]
long_double_complex operator/(long_double_complex lhs,
long_double_complex rhs);
long_double_complex operator/(long_double_complex lhs,
long double rhs);
long_double_complex operator/(long double lhs,
long_double_complex rhs);

1 Returns long_double_complex(lhs) /= rhs.
bool operator==(long_double_complex lhs, long_double_complex rhs);

2 Returns real(lhs) == real(rhs) && imag(lhs) == imag(rhs).
bool operator==(long_double_complex lhs, long double rhs);

3 Returns real(lhs) == rhs && imag(lhs) == 0.
bool operator==(long double lhs, long_double_complex rhs);

4 Returns lhs == real(rhs) && imag(rhs) == 0.

26.1.1.6.5  operator!=                              [lib.op!=.ldc.ldc]
bool operator!=(long_double_complex lhs, long_double_complex rhs);

1 Returns real(lhs) != real(rhs) || imag(lhs) != imag(rhs).
bool operator!=(long_double_complex lhs, long double rhs);

2 Returns real(lhs) != rhs || imag(lhs) != 0.
bool operator!=(long double lhs, long_double_complex rhs);

3 Returns lhs != real(rhs) || imag(rhs) != 0.

26.1.1.6.6  operator>>                                   [lib.ext.ldc]
istream& operator>>(istream& is, long_double_complex& x);

1 Evaluates the expression:
is >> ch && ch == '('
&& is >> re >> ch && ch == ','
&& is >> im >> ch && ch == ')';

2 where  ch  is an object of type char and re and im are objects of type
long  double.   If  the  result  is  nonzero,  the  function   assigns

long_double_complex(re, im) to x.

3 The function returns is.

26.1.1.6.7  operator<<                                   [lib.ins.ldc]
ostream& operator<<(ostream& os, long_double_complex x);

1 Returns os << '(' << real(x) << ',' << imag(x) << ')'.

26.1.2  Complex number operations                    [lib.complex.ops]

26.1.2.1  abs                                                [lib.abs]
float       abs(float_complex x);
double      abs(double_complex x);
long double abs(long_double_complex x);

1 Returns the magnitude of x.

26.1.2.2  arg                                                [lib.arg]
float       arg(float_complex x);
double      arg(double_complex x);
long double arg(long_double_complex x);

1 Returns the phase angle of x.

26.1.2.3  conj                                              [lib.conj]
float_complex       conj(float_complex x);
double_complex      conj(double_complex x);
long_double_complex conj(long_double_complex x);

1 Returns the conjugate of x.

26.1.2.4  cos                                                [lib.cos]
float_complex       cos(float_complex x);
double_complex      cos(double_complex x);
long_double_complex cos(long_double_complex x);

1 Returns the cosine of x.

26.1.2.5  cosh                                              [lib.cosh]
float_complex       cosh(float_complex x);
double_complex      cosh(double_complex x);
long_double_complex cosh(long_double_complex x);

1 Returns the hyperbolic cosine of x.

26.1.2.6  exp                                                [lib.exp]
float_complex       exp(float_complex x);
double_complex      exp(double_complex x);
long_double_complex exp(long_double_complex x);

1 Returns the exponential of x.

26.1.2.7  imag                                              [lib.imag]
float       imag(float_complex x);
double      imag(double_complex x);
long double imag(long_double_complex x);

1 Returns the imaginary part of x.

26.1.2.8  log                                                [lib.log]
float_complex       log(float_complex x);
double_complex      log(double_complex x);
long_double_complex log(long_double_complex x);

1 Returns the logarithm of x.

26.1.2.9  norm                                              [lib.norm]
float       norm(float_complex x);
double      norm(double_complex x);
long double norm(long_double_complex x);

1 Returns the squared magnitude of x.

26.1.2.10  polar                                     [lib.polar.ld.ld]
float_complex polar(float rho, float theta);
double_complex polar(double rho, double theta);
long_double_complex polar(long double rho, long double theta);

1 Returns the complex value corresponding to a complex number whose mag­
nitude is rho and whose phase angle is theta.

26.1.2.11  pow                                               [lib.pow]
float_complex       pow(float_complex x, float_complex y);
float_complex       pow(float_complex x, float_complex y);
float_complex       pow(float_complex x, float y);
float_complex       pow(float_complex x, int y);
float_complex       pow(float x, float_complex y);
double_complex      pow(double_complex x, double_complex y);
double_complex      pow(double_complex x, double y);
double_complex      pow(double_complex x, int y);
double_complex      pow(double x, double_complex y);
long_double_complex pow(long_double_complex x, long_double_complex y);
long_double_complex pow(long_double_complex x, long double y);
long_double_complex pow(long_double_complex x, int y);
long_double_complex pow(long double x, long_double_complex y);

1 Returns x raised to the power y.

26.1.2.12  real                                             [lib.real]
float       real(float_complex x);
double      real(double_complex x);
long double real(long_double_complex x);

1 Returns the real part of x.

26.1.2.13  sin                                               [lib.sin]
float_complex       sin(float_complex x);
double_complex      sin(double_complex x);
long_double_complex sin(long_double_complex x);

1 Returns the sine of x.

26.1.2.14  sinh                                             [lib.sinh]
float_complex       sinh(float_complex x);
double_complex      sinh(double_complex x);
long_double_complex sinh(long_double_complex x);

1 Returns the hyperbolic sine of x.

26.1.2.15  sqrt                                             [lib.sqrt]
float_complex       sqrt(float_complex x);
double_complex      sqrt(double_complex x);
long_double_complex sqrt(long_double_complex x);

1 Returns the square root of x.

26.2  Numeric arrays                                    [lib.numarray]

--<valarray>

2 Table 2:

+------------------------------------------------------------------------+
|          Type                                Name(s)                   |
+------------------------------------------------------------------------+
|Template classes:                                                       |
+------------------------------------------------------------------------+
|Template operators:                                                     |
|operator!= (valarray) [3]   operator<< (valarray) [3]                   |
|operator%  (valarray) [3]   operator<<=(valarray) [2]                   |
|operator%= (valarray) [2]   operator<= (valarray) [3]                   |
|operator&  (valarray) [3]   operator== (valarray) [3]                   |
|operator&& (valarray) [3]   operator>  (valarray) [3]                   |
|operator&= (valarray) [2]   operator>= (valarray) [3]                   |
|operator*  (valarray) [3]   operator>> (valarray) [3]                   |
|operator*= (valarray) [2]   operator>>=(valarray) [2]                   |
|operator+  (valarray) [3]   operator^  (valarray) [3]                   |
|operator+= (valarray) [2]   operator^= (valarray) [2]                   |
|operator-  (valarray) [3]   operator|  (valarray) [3]                   |
|operator-= (valarray) [2]   operator|= (valarray) [2]                   |
|operator/  (valarray) [3]   operator|| (valarray) [3]                   |
|operator/= (valarray) [2]                                               |
|operator<  (valarray) [3]                                               |
+------------------------------------------------------------------------+
|Template functions:                                                     |
|abs  (valarray)             cosh (valarray)             sinh (valarray) |
|acos (valarray)             exp  (valarray)             sqrt (valarray) |
|asin (valarray)             log  (valarray)             tan  (valarray) |
|atan (valarray)             log10(valarray)             tanh (valarray) |
|atan2(valarray) [3]         pow  (valarray) [3]                         |
|cos  (valarray)             sin  (valarray)                             |
+------------------------------------------------------------------------+
|Classes:                    gslice                      slice           |
+------------------------------------------------------------------------+

3 The  header  <valarray>  defines  five  template  classes   (valarray,
slice_array,   gslice_array,   mask_array,  and  indirect_array),  two
classes (slice and gslice), and a series of  related  function  signa­
tures for representing and manipulating arrays of values.1)

4 The valarray array classes are defined to be free of certain forms  of
aliasing, thus allowing operations on these classes to be optimized.

_________________________
1)   If   any   of  the  names  valarray,  slice_array,  gslice_array,
mask_array, indirect_array, slice or  gslice  are  introduced  into  a
translation  unit  by any means other than inclusion of the <valarray>
header file, the resulting behavior is undefined.

5 These  library functions are permitted to throw an bad_alloc exception
if there are not sufficient resources available to carry out the oper­
ation.  Note that the exception is not mandated.

+-------                 BEGIN BOX 1                -------+
The  descriptions  of valarray and the associated classes which follow
lack any discussion of possible exceptions.
+-------                  END BOX 1                 -------+

6 The templates and classes defined in  <valarray>  have  the  following
public interfaces:
template <class T> class valarray;       // An array of type T
class slice;                             // a BLAS-like slice out of an array
template <class T> class slice_array;
class gslice;                            // a generalized slice out of an array
template <class T> class gslice_array;
template <class T> class indirect_array; // an indirected array

26.2.1  Template class valarray<T>             [lib.template.valarray]
template<class T> class valarray {
public:
inline valarray();
inline valarray(enum Uninitialized, 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 indirect_array<T>&);
inline ~valarray();
valarray& operator=(const valarray&);
valarray& operator=(const slice_array<T>&);
valarray& operator=(const gslice_array<T>&);
valarray& operator=(const indirect_array<T>&);
inline size_t length() const;
inline operator T*();
inline operator const T*() const;
inline const T    operator[](size_t);
inline T&         operator[](size_t);
const valarray    operator[](slice) const;
slice_array<T>    operator[](slice);
const valarray    operator[](const gslice&) const;
gslice_array<T>   operator[](const gslice&);
const valarray    operator[](const valarray<bool>&) const;
const valarray    operator[](const valarray<int>&) const;
indirect_array<T> operator[](const valarray<int>&);

const valarray operator+() const;
const valarray operator-() const;
const valarray operator~() const;
const valarray 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&);

+-------                 BEGIN BOX 2                -------+
The  friend  specifiers  are over-specification.  I have left them in,
pending discussion, because they are a concise summary  of  non-member
operators applicable to this class.
+-------                  END BOX 2                 -------+

friend const valarray<T> operator* (const valarray<T>&, const T&);
friend const valarray<T> operator* (const T&, const valarray<T>&);
friend const valarray<T> operator/ (const valarray<T>&, const T&);
friend const valarray<T> operator/ (const T&, const valarray<T>&);
friend const valarray<T> operator% (const valarray<T>&, const T&);
friend const valarray<T> operator% (const T&, const valarray<T>&);
friend const valarray<T> operator+ (const valarray<T>&, const T&);
friend const valarray<T> operator+ (const T&, const valarray<T>&);
friend const valarray<T> operator- (const valarray<T>&, const T&);
friend const valarray<T> operator- (const T&, const valarray<T>&);
friend const valarray<T> operator^ (const valarray<T>&, const T&);
friend const valarray<T> operator^ (const T&, const valarray<T>&);
friend const valarray<T> operator& (const valarray<T>&, const T&);
friend const valarray<T> operator& (const T&, const valarray<T>&);
friend const valarray<T> operator| (const valarray<T>&, const T&);
friend const valarray<T> operator| (const T&, const valarray<T>&);
friend const valarray<T> operator<<(const valarray<T>&, const T&);
friend const valarray<T> operator<<(const T&, const valarray<T>&);
friend const valarray<T> operator>>(const valarray<T>&, const T&);
friend const valarray<T> operator>>(const T&, const valarray<T>&);
friend const valarray<T> operator&&(const valarray<T>&, const T&);
friend const valarray<T> operator&&(const T&, const valarray<T>&);
friend const valarray<T> operator||(const valarray<T>&, const T&);
friend const valarray<T> operator||(const T&, const valarray<T>&);

valarray<T>& operator*= (const valarray<T>& ab);
valarray<T>& operator/= (const valarray<T>& ab);
valarray<T>& operator%= (const valarray<T>& ab);
valarray<T>& operator+= (const valarray<T>& ab);
valarray<T>& operator-= (const valarray<T>& ab);
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>&);
friend const valarray<T> operator* (const valarray<T>&, const valarray<T>&);
friend const valarray<T> operator/ (const valarray<T>&, const valarray<T>&);
friend const valarray<T> operator% (const valarray<T>&, const valarray<T>&);
friend const valarray<T> operator+ (const valarray<T>&, const valarray<T>&);
friend const valarray<T> operator- (const valarray<T>&, const valarray<T>&);
friend const valarray<T> operator^ (const valarray<T>&, const valarray<T>&);
friend const valarray<T> operator| (const valarray<T>&, const valarray<T>&);
friend const valarray<T> operator& (const valarray<T>&, const valarray<T>&);
friend const valarray<T> operator<<(const valarray<T>&, const valarray<T>&);
friend const valarray<T> operator>>(const valarray<T>&, const valarray<T>&);
friend const valarray<T> operator&&(const valarray<T>&, const valarray<T>&);
friend const valarray<T> operator||(const valarray<T>&, const valarray<T>&);
friend const valarray<bool> operator==(const valarray<T>&, const T&);
friend const valarray<bool> operator==(const T&, const valarray<T>&);
friend const valarray<bool> operator==(const valarray<T>&, const valarray<T>&);
friend const valarray<bool> operator!=(const valarray<T>&, const T&);
friend const valarray<bool> operator!=(const T&, const valarray<T>&);
friend const valarray<bool> operator!=(const valarray<T>&, const valarray<T>&);
friend const valarray<bool> operator< (const T&, const valarray<T>&);
friend const valarray<bool> operator< (const T&, const valarray<T>&);
friend const valarray<bool> operator< (const valarray<T>&, const valarray<T>&);
friend const valarray<bool> operator> (const valarray<T>&, const T&);
friend const valarray<bool> operator> (const T&, const valarray<T>&);
friend const valarray<bool> operator> (const valarray<T>&, const valarray<T>&);
friend const valarray<bool> operator<=(const valarray<T>&, const T&);
friend const valarray<bool> operator<=(const T&, const valarray<T>&);
friend const valarray<bool> operator<=(const valarray<T>&, const valarray<T>&);
friend const valarray<bool> operator>=(const valarray<T>&, const T&);
friend const valarray<bool> operator>=(const valarray<T>&, const T&);
friend const valarray<bool> operator>=(const T&, const valarray<T>&);
friend const valarray<bool> operator>=(const valarray<T>&, const valarray<T>&);
const T sum() const;
void fill(const T&);
const T min() const;
const T max() const;

friend const valarray<T> abs  (const valarray<T>&);
friend const valarray<T> acos (const valarray<T>&);
friend const valarray<T> asin (const valarray<T>&);
friend const valarray<T> atan (const valarray<T>&);
friend const valarray<T> atan2(const valarray<T>&, const valarray<T>&);
friend const valarray<T> atan2(const valarray<T>&, const T&);
friend const valarray<T> atan2(const T&, const valarray<T>&);
friend const valarray<T> cos  (const valarray<T>&);
friend const valarray<T> cosh (const valarray<T>&);
friend const valarray<T> exp  (const valarray<T>&);
friend const valarray<T> log  (const valarray<T>&);
friend const valarray<T> log10(const valarray<T>&);
friend const valarray<T> pow  (const valarray<T>&, const valarray<T>&);
friend const valarray<T> pow  (const valarray<T>&, const T&);
friend const valarray<T> pow  (const T&, const valarray<T>&);
friend const valarray<T> sin  (const valarray<T>&);
friend const valarray<T> sinh (const valarray<T>&);
friend const valarray<T> sqrt (const valarray<T>&);
friend const valarray<T> tan  (const valarray<T>&);
friend const valarray<T> tanh  (const valarray<T>&);
const valarray<T> shift(int) const;
const valarray<T> apply(T func(T)) const;
const valarray<T> apply(T func(const T&)) const;
void free();
private:
// implementation dependent
};

1 The template class valarray<T> is a one-dimensional smart array,  with
elements  numbered  sequentially from zero.  It is a representation of
the mathematical concept of an ordered set of values.  The illusion of
higher  dimensionality  may  be produced by the familiar idiom of com­
puted indices, together with the powerful subsetting capabilities pro­
vided by the generalized subscript operators.2)

2 An  implementation  is  permitted  to  qualify  any  of  the functions
declared in <valarray> as inline.

3 A specialization of valarray for a type T has well-defined behavior if
and only if the type T satisfies the following requirements:3)

--T  is  not  an  abstract  class (it has no pure virtual member func­
tions);

_________________________
2)  The  intent  is  to specify an array template that has the minimum
functionality necessary to address aliasing ambiguities and  the  pro­
liferation  of  temporaries.  Thus, the valarray template is neither a
matrix class nor a field class.  However, it is a very useful building
block for designing such classes.
3)  In  other words, valarray<T> should only be instantiated for value
types.  These include built-in arithmetic types, pointers, the library
class complex, and instantiations of valarray for value types.

--T is not a reference type;

--T is not cv-qualified;

--If T is a class, it has a public default constructor;

--If T is a class, it has a public copy constructor with the signature
T::T(const T&)

--If T is a class, it has a public destructor;

--If T is a class, it has a public assignment operator whose signature
is either
T& T::operator=(const T&)
or
T& T::operator=(T)

--If T is a class, its assignment operator, copy and default construc­
tors,  and destructor must correspond to each other in the following
sense: Initialization of raw storage using the default  constructor,
followed by assignment, is semantically equivalent to initialization
of raw storage  using  the  copy  constructor.   Destruction  of  an
object, followed by initialization of its raw storage using the copy
constructor, is semantically equivalent to assignment to the  origi­
nal object.  This rule states that there must not be any subtle dif­
ferences in the semantics of initialization versus assignment.  This
gives  an  implementation considerable flexibility in how arrays are
initialized.

For example, an implementation is allowed to initialize  a  valarray
by  allocating  storage using the new operator (which implies a call
to the default constructor for each element) and then assigning each
element  its  value.  Or the implementation can allocate raw storage
and use the copy constructor to initialize  each  element.   If  the
distinction between initialization and assignment is important for a
class, or if it fails to satisfy any of the other conditions  listed
above,  the  programmer  should use dynarray instead of valarray for
that class;

--If T is a class, it does not overload unary operator&.

4 In addition, many member and friend functions of  valarray<T>  can  be
successfully  instantiated  and  will exhibit well-defined behavior if
and only if T satisfies additional  requirements  specified  for  each
such member or friend function.

5 For  example,  it  is legitimate to instantiate valarray<complex>, but
operator > will not be successfully instantiated for valarray<complex>
operands, since complex does not have any ordering operators.

26.2.1.1  valarray constructors                    [lib.valarray.cons]
valarray::valarray();

1 Constructs an object of class valarray<T>, 4) which  has  zero  length
until  it  is passed into a library function as a modifiable lvalue or
through  a  non-constant  this  pointer.   This default constructor is
essential, since arrays of valarray are likely to prove useful.  There
must  also  be  a way to change the size of an array after initializa­
tion; this is supplied by the semantics of the assignment operator.
valarray::valarray(enum Uninitialized, size_t);

2 The array created by this constructor has a length equal to the  value
of the second argument.  The first argument is not used.  The elements
of the array are constructed using the  default  constructor  for  the
instantiating  type  T.   The extra argument is needed to prevent this
constructor from being used by the compiler to silently convert  inte­
gers to valarray objects.
valarray::valarray(const T&, size_t);

3 The array created by this constructor has a length equal to the second
argument.  The elements of the array are initialized with the value of
the first argument.
valarray::valarray(const T*, size_t);

4 The array created by this constructor has a length equal to the second
argument n.  The values of the elements of the array  are  initialized
with  the  first  n  values  pointed to by the first argument.  If the
value of the second argument is greater  than  the  number  of  values
pointed  to  by  the  first argument, the behavior is undefined.  This
constructor is the preferred method for converting  a  C  array  to  a
valarray object.
valarray::valarray(const valarray&);

5 The array created by this constructor has the same length as the argu­
ment array.  The elements are initialized with the values of the  cor­
responding elements of the argument array.  This copy constructor cre­
ates a distinct array rather than an alias.  Implementations in  which
arrays share storage are permitted, but they must implement a copy-on-
reference mechanism to ensure that arrays are conceptually distinct.
valarray::valarray(const slice_array<T>&);
valarray::valarray(const gslice_array<T>&);
valarray::valarray(const indirect_array<T>&);

6 These conversion constructors convert one of the four  reference  tem­
plates to a valarray.

_________________________
4) For  convenience,  such  objects  are  referred  to  as  ``arrays''
throughout the remainder of subclause _lib.numarray_.

26.2.1.2  valarray destructor                       [lib.valarray.des]
valarray::~valarray();

26.2.1.3  valarray assignment                       [lib.valarray.op=]
valarray& valarray::operator=(const valarray&);

1 The  assignment  operator modifies the length of the *this array to be
equal to that of the argument array.  Each element of the *this  array
is  then  assigned the value of the corresponding element of the argu­
ment array.  Assignment is the usual way to change the  length  of  an
array  after  initialization.   Assignment results in a distinct array
rather than an alias.
valarray& valarray::operator=(const slice_array<T>&);
valarray& valarray::operator=(const gslice_array<T>&);
valarray& valarray::operator=(const indirect_array<T>&);

2 These operators allow the results of a generalized subscripting opera­
tion to be assigned directly to a valarray.

26.2.1.4  valarray length access                [lib.valarray::length]
size_t valarray::length() const;

1 This function returns the number of elements in the this array.

26.2.1.5  valarray pointer conversion               [lib.valarray.ptr]
valarray::operator T*();
valarray::operator const T*() const;

1 A  non-constant array may be converted to a pointer to the instantiat­
ing type.  A constant array may be  converted  to  a  pointer  to  the
instantiating type, qualified by const.

2 It is guaranteed that
&a[0] == (T*)a
for  any  non-constant valarray<T> a.  The pointer returned for a non-
constant array (whether or not it points to a type qualified by const)
is  valid  for the same duration as a reference returned by the size_t
subscript operator.  The pointer returned  for  a  constant  array  is
valid for the lifetime of the array.5)

26.2.1.6  valarray element access                [lib.valarray.access]
const T operator[](size_t) const;
T& operator[](size_t);

1 When applied to a constant array, the subscript operator  returns  the
value  of  the  corresponding element of the array.  When applied to a
non-constant array, the subscript operator returns a reference to  the
corresponding element of the array.

_________________________
5) This form of access is essential for reusability and cross-language
programming.

2 Thus, the expression
(a[i] = q, a[i]) == q
evaluates as true for any non-constant valarray<T> a, any T q, and for
any size_t i such that the value of i is less than the length of a.

3 The expression
&a[i+j] == &a[i] + j
evaluates  as true for all size_t i and size_t j such that i+j is less
than the length of the non-constant array a.

4 Likewise, the expression
&a[i] != &b[j]
evaluates as true for any two non-constant arrays a and b and for  any
size_t  i  and size_t j such that i is less than the length of a and j
is less than the length of b.  This property indicates an  absence  of
aliasing and may be used to advantage by optimizing compilers.6)

5 The  reference  returned  by the subscript operator for a non-constant
array is guaranteed to be valid until  the  array  to  whose  data  it
refers  is  passed into any library function as a modifiable lvalue or
through a non-const this pointer.

6 Computed assigns [such as valarray& valarray::operator+=(const  valar­
ray&)]  do  not by themselves invalidate references to array data.  If
the subscript operator is invoked with a size_t argument  whose  value
is not less than the length of the array, the behavior is undefined.

26.2.1.7  valarray subset operations                [lib.valarray.sub]
const valarray    operator[](slice) const;
slice_array<T>    operator[](slice);
const valarray    operator[](const gslice&) const;
gslice_array<T>   operator[](const gslice&);
const valarray    operator[](const valarray<bool>&) const;
const valarray    operator[](const valarray<int>&) const;
indirect_array<T> operator[](const valarray<int>&);

1 Each  of  these  operations  returns  a subset of the this array.  The
const- qualified versions return this subset as a new  valarray.   The
non-const  versions return a class template object which has reference
semantics to the original array.

26.2.1.8  valarray unary operators                [lib.valarray.unary]
const valarray valarray::operator+() const;
const valarray valarray::operator-() const;
const valarray valarray::operator~() const;
const valarray valarray::operator!() const;

_________________________
6)  Compilers  may  take  advantage of inlining, constant propagation,
loop fusion, tracking of pointers obtained from operator new, and oth­
er techniques to generate efficient valarrays.

1 Each of these operators may only be instantiated for a type T to which
the  indicated  operator  can  be  applied and for which the indicated
operator returns a value which is of type &T or which may be unambigu­
ously converted to type T.

2 Each  of these operators returns an array whose length is equal to the
length of the this array.  Each element of the returned array is  ini­
tialized  with  the  result  of applying the indicated operator to the
corresponding element of the this array.

26.2.1.9  valarray binary operators         [lib.valarray.binary.scal]
with scalars
const valarray operator* (const valarray&, const T&);
const valarray operator/ (const valarray&, const T&);
const valarray operator% (const valarray&, const T&);
const valarray operator+ (const valarray&, const T&);
const valarray operator- (const valarray&, const T&);
const valarray operator^ (const valarray&, const T&);
const valarray operator& (const valarray&, const T&);
const valarray operator| (const valarray&, const T&);
const valarray operator<<(const valarray&, const T&);
const valarray operator>>(const valarray&, const T&);
const valarray operator&&(const valarray&, const T&);
const valarray operator||(const valarray&, const T&);
const valarray operator* (const T&, const valarray&);
const valarray operator/ (const T&, const valarray&);
const valarray operator% (const T&, const valarray&);
const valarray operator+ (const T&, const valarray&);
const valarray operator- (const T&, const valarray&);
const valarray operator^ (const T&, const valarray&);
const valarray operator& (const T&, const valarray&);
const valarray operator| (const T&, const valarray&);
const valarray operator<<(const T&, const valarray&);
const valarray operator>>(const T&, const valarray&);
const valarray operator&&(const T&, const valarray&);
const valarray operator||(const T&, const valarray&);

1 Each of these operators may only be instantiated for a type T to which
the indicated operator can be applied  and  for  which  the  indicated
operator  returns a value which is of type T or which can be unambigu­
ously converted to type T.

2 Each of these operators returns an array whose length is equal to  the
length  of  the array argument.  Each element of the returned array is
initialized with the result of applying the indicated operator to  the
corresponding element of the array argument and the scalar argument.

26.2.1.10  valarray computed assigns       [lib.valarray.cassign.scal]
with scalars

valarray& valarray::operator*= (const T&);
valarray& valarray::operator/= (const T&);
valarray& valarray::operator%= (const T&);
valarray& valarray::operator+= (const T&);
valarray& valarray::operator-= (const T&);
valarray& valarray::operator^= (const T&);
valarray& valarray::operator&= (const T&);
valarray& valarray::operator|= (const T&);
valarray& valarray::operator<<=(const T&);
valarray& valarray::operator>>=(const T&);

1 Each of these operators may only be instantiated for a type T to which
the indicated operator can be applied.

2 Each of these operators applies the indicated operation to  each  ele­
ment of the this array and the scalar argument.

3 The this array is then returned by reference.

4 The appearance of an array on the left hand side of a computed assign­
ment does not invalidate references or pointers to the elements of the
array.

26.2.1.11  valarray binary operations         [lib.valarray.bin.array]
with other arrays
const valarray operator* (const valarray&, const valarray&);
const valarray operator/ (const valarray&, const valarray&);
const valarray operator% (const valarray&, const valarray&);
const valarray operator+ (const valarray&, const valarray&);
const valarray operator- (const valarray&, const valarray&);
const valarray operator^ (const valarray&, const valarray&);
const valarray operator& (const valarray&, const valarray&);
const valarray operator| (const valarray&, const valarray&);
const valarray operator<<(const valarray&, const valarray&);
const valarray operator>>(const valarray&, const valarray&);
const valarray operator&&(const valarray&, const valarray&);
const valarray operator||(const valarray&, const valarray&);

1 Each of these operators may only be instantiated for a type T to which
the  indicated  operator  can  be  applied and for which the indicated
operator returns a value which is of type T or which can be  unambigu­
ously converted to type T.

2 Each  of these operators returns an array whose length is equal to the
lengths of the argument arrays.  Each element of the returned array is
initialized  with the result of applying the indicated operator to the
corresponding elements of the argument arrays.

3 If the argument arrays do not have the same length,  the  behavior  is
undefined.

26.2.1.12  valarray computed               [lib.valarray.assign.array]
assignments with other arrays
valarray& valarray::operator*= (const valarray&);
valarray& valarray::operator/= (const valarray&);
valarray& valarray::operator%= (const valarray&);
valarray& valarray::operator+= (const valarray&);
valarray& valarray::operator-= (const valarray&);
valarray& valarray::operator^= (const valarray&);
valarray& valarray::operator&= (const valarray&);
valarray& valarray::operator|= (const valarray&);
valarray& valarray::operator<<=(const valarray&);
valarray& valarray::operator>>=(const valarray&);

1 Each of these operators may only be instantiated for a type T to which
the  indicated  operator can be applied.  Each of these operators per­
forms the indicated operation on each of its elements and  the  corre­
sponding element of the argument array.

2 The this array is then returned by reference.

3 If  the this array and the argument array do not have the same length,
the behavior is undefined.  The appearance of an  array  on  the  left
hand  side  of a computed assignment does not invalidate references or
pointers.

26.2.1.13  valarray comparison operators      [lib.valarray.comp.scal]
with scalars
const valarray<bool> operator==(const valarray&, const T&);
const valarray<bool> operator!=(const valarray&, const T&);
const valarray<bool> operator< (const valarray&, const T&);
const valarray<bool> operator> (const valarray&, const T&);
const valarray<bool> operator<=(const valarray&, const T&);
const valarray<bool> operator>=(const valarray&, const T&);
const valarray<bool> operator==(const T&, const valarray&);
const valarray<bool> operator!=(const T&, const valarray&);
const valarray<bool> operator< (const T&, const valarray&);
const valarray<bool> operator> (const T&, const valarray&);
const valarray<bool> operator<=(const T&, const valarray&);
const valarray<bool> operator>=(const T&, const valarray&);

1 Each of these operators may only be instantiated for a type T to which
the indicated operator can be applied  and  for  which  the  indicated
operator  returns  a value which is of type bool or which can be unam­
biguously converted to type bool.

2 Each of these operators returns a bool array whose length is equal  to
the  length of the array argument.  Each element of the returned array
is initialized with the result of applying the indicated  operator  to
the corresponding element of the this array and the scalar argument.

26.2.1.14  valarray comparison               [lib.valarray.comp.array]
operators with other arrays
const valarray<bool> operator==(const valarray&, const valarray&);
const valarray<bool> operator!=(const valarray&, const valarray&);
const valarray<bool> operator< (const valarray&, const valarray&);
const valarray<bool> operator> (const valarray&, const valarray&);
const valarray<bool> operator<=(const valarray&, const valarray&);
const valarray<bool> operator>=(const valarray&, const valarray&);

1 Each of these operators may only be instantiated for a type T to which
the indicated operator can be applied  and  for  which  the  indicated
operator  returns  a value which is of type bool or which can be unam­
biguously converted to type bool.

2 Each of these operators returns a bool array whose length is equal  to
the length of the array arguments.  Each element of the returned array
is initialized with the result of applying the indicated  operator  to
the corresponding elements of the argument arrays.

3 If  the  two array arguments do not have the same length, the behavior
is undefined.

26.2.1.15  valarray sum function                    [lib.valarray.sum]
const T valarray::sum() const;
This function may only be instantiated for a type T  to  which  opera­
tor+=  can  be applied.  This function returns the sum of all the ele­
ments of the array.

1 If the array has length 0, the behavior is undefined.   If  the  array
has  length  1,  sum  returns  the value of element 0.  Otherwise, the
returned value is calculated by applying operator+= to a  copy  of  an
element of the array and all other elements of the array in an unspec­
ified order.

26.2.1.16  valarray fill function                  [lib.valarray.fill]
void valarray::fill(const T&);
This function assigns the value of the argument to all the elements of
the  this  array.  The length of the array is not changed, nor are any
pointers or references to the elements of the array invalidated.

26.2.1.17  valarray transcendentals           [lib.valarray.transcend]

const valarray abs  (const valarray&);
const valarray acos (const valarray&);
const valarray asin (const valarray&);
const valarray atan (const valarray&);
const valarray atan2(const valarray&, const valarray&);
const valarray atan2(const valarray&, const T&);
const valarray atan2(const T&, const valarray&);
const valarray cos  (const valarray&);
const valarray cosh (const valarray&);
const valarray exp  (const valarray&);
const valarray log  (const valarray&);
const valarray log10(const valarray&);
const valarray pow  (const valarray&, const valarray&);
const valarray pow  (const valarray&, const T&);
const valarray pow  (const T&, const valarray&);
const valarray sin  (const valarray&);
const valarray sinh (const valarray&);
const valarray sqrt (const valarray&);
const valarray tan  (const valarray&);
const valarray tanh (const valarray&);

1 Each of these functions may only be instantiated for a type T to which
a  unique function with the indicated name can be applied.  This func­
tion must return a value which is of type T or which can be  unambigu­
ously converted to type T.

26.2.1.18  valarray min and max functions        [lib.valarray.minmax]
const T min(const valarray&);
const T max(const valarray&);

1 These  functions may only be instantiated for a type T to which opera­
tor> and operator< may be applied and for which operator>  and  opera­
tor<  return  a  value which is of type bool or which can be unambigu­
ously converted to type bool.

2 These functions return the minimum or maximum value found in the argu­
ment array.

3 The  value  returned  for  an  array of length 0 is undefined.  For an
array of length 1, the value of element 0 is returned.  For all  other
array  lengths,  the  determination is made using operator> and opera­
tor<, in a manner analogous to the application of operator+=  for  the
sum function.

26.2.1.19  valarray shift function                [lib.valarray.shift]
const valarray valarray::shift(int) const;

1 This  function  returns an array whose length is identical to the this
array, but whose element values are shifted the number of places indi­
cated by the argument.

2 For  example,  if the argument has the value 2, the first two elements
of the result will be constructed using the default  constructor;  the
third  element  of  the result will be assigned the value of the first

element of the argument; etc.

+-------                 BEGIN BOX 3                -------+
Should  a cshift (circular shift) function also be defined?  This is a
common operation in Fortran.
+-------                  END BOX 3                 -------+

26.2.1.20  valarray mapping functions               [lib.valarray.map]
const valarray valarray::apply(T func(T)) const;
const valarray valarray::apply(T func(const T&)) const;

1 These functions return an array whose length  is  equal  to  the  this
array.   Each  element  of  the  returned  array is assigned the value
returned by applying the argument function to the  corresponding  ele­
ment of the this array.

26.2.1.21  valarray free function                  [lib.valarray.free]
void valarray::free();

1 This function sets the length of an array to zero.7)

26.2.2  Class slice                                  [lib.class.slice]
class slice {
public:
slice();
slice(int, int, int);
int start() const;
int length() const;
int stride() const;
private:
//    implementation defined
};

1 The slice class represents a BLAS-like slice from an  array.   Such  a
slice is specified by a starting index, a length, and a stride.8)

26.2.2.1  slice constructors                          [lib.cons.slice]
slice::slice();
slice::slice(int start, int length, int stride);
slice::slice(const slice&);

1 The  default  constructor for slice creates a slice which specifies no
elements.  A default constructor is provided only to permit the decla­
ration  of  arrays  of  slices.   The constructor with arguments for a
slice takes a start, length, and stride parameter.

2 For example,
slice(3, 8, 2)
_________________________
7)  An  implementation  may reclaim the storage used by the array when
this function is called.
8) C++ programs may instantiate this class.

constructs a slice which selects elements 3, 5,  7,  ...  17  from  an
array.

26.2.2.2  slice access functions                    [lib.slice.access]
int slice::start() const;
int slice::length() const;
int slice::stride() const;

1 These  functions  return  the  start, length, or stride specified by a
slice object.

26.2.3  Template class slice_array          [lib.template.slice.array]
template <class T> class slice_array {
public:
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 fill(const T&);
private:
slice_array();
slice_array(const slice_array&);
slice_array& operator=(const slice_array&);
//   remainder implementation defined
};

1 The slice_array template is a helper template used by the  slice  sub­
script operator
slice_array<T> valarray<T>::operator[](slice);
It  has  reference  semantics  to  a subset of an array specified by a
slice object.

2 For example, the expression
a[slice(1, 5, 3)] = b;
has the effect of assigning the elements of b to a slice of  the  ele­
ments  in  a.  For the slice shown, the elements selected from a be 1,
4, ..., 13.

3 Note that programmers may not instantiate slice_array, since  all  its
constructors are private.  It is intended purely as a helper class and
should be transparent to the user.

26.2.3.1  slice_array constructors                [lib.cons.slice.arr]
slice_array::slice_array();
slice_array::slice_array(const slice_array&);

1 Note  that the slice_array template has no public constructors.  These
constructors are declared to be private.  These constructors need  not
be defined.

26.2.3.2  slice_array assignment                [lib.slice.arr.assign]
void operator=(const valarray<T>&) const;
slice_array& operator=(const slice_array&);

1 The  second  of these two assignment operators is declared private and
need not be defined.  The first has reference semantics, assigning the
values  of  the  argument  array  elements to selected elements of the
valarray<T> object to which the slice_array object refers.

26.2.3.3  slice_array computed             [lib.slice.arr.comp.assign]
assignment
void slice_array::operator*= (const valarray<T>&) const;
void slice_array::operator/= (const valarray<T>&) const;
void slice_array::operator%= (const valarray<T>&) const;
void slice_array::operator+= (const valarray<T>&) const;
void slice_array::operator-= (const valarray<T>&) const;
void slice_array::operator^= (const valarray<T>&) const;
void slice_array::operator&= (const valarray<T>&) const;
void slice_array::operator|= (const valarray<T>&) const;
void slice_array::operator<<=(const valarray<T>&) const;
void slice_array::operator>>=(const valarray<T>&) const;

1 These  computed  assignments  have  reference  semantics, applying the
indicated operation to the elements of the argument array and selected
elements  of  the  valarray<T>  object to which the slice_array object
refers.

26.2.3.4  slice_array fill function               [lib.slice.arr.fill]
void fill(const T&);

1 This function has reference semantics,  assigning  the  value  of  its
argument  to  the  elements  of  the  valarray<T>  object to which the
slice_array object refers.

26.2.4  The gslice class                            [lib.class.gslice]
class gslice {
public:
gslice();
gslice(int s, const valarray<int>& l, const valarray<int>& d);
int start() const;
valarray<int> length() const;
valarray<int> stride() const;
private:
//  implementation defined
};

1 This class represents a generalized slice out of an array.   A  gslice
is  defined by a starting offset (s), a set of lengths (lj), and a set
of strides (dj).  The number of  lengths  must  equal  the  number  of
strides.

2 A  gslice  represents  a  mapping from a set of indices (ij), equal in
number to the number of strides, to a single index k.   It  is  useful
for  building  multidimensional  array classes using the valarray tem­
plate, which is one-dimensional.  The  set  of  one-dimensional  index
values specified by a gslice are
k = s + sum_over_j(ijdj)
where  the multidimensional indices ij range in value from 0 to lij-1.

3 For example, the gslice specification
start  = 3
length = {2, 4, 3}
stride = {19, 4, 1}
yields the sequence of one-dimensional indices
k = 3 + (0,1) x 19 = (0,1,2,3) x 4 + (0,1,2) x 1
which are ordered as shown in the following table:
(i0, i1, i2, k) =
(0, 0, 0, 3),
(0, 0, 1, 4),
(0, 0, 2, 5),
(0, 1, 0, 7),
(0, 1, 1, 8),
(0, 1, 2, 9),
(0, 2, 0, 11),
(0, 2, 1, 12),
(0, 2, 2, 13),
(0, 3, 0, 15),
(0, 3, 1, 16),
(0, 3, 2, 17),
(1, 0, 0, 22),
(1, 0, 1, 23),
...
(1, 3, 2, 36)
That is, the highest-ordered index turns fastest.

4 It is possible to have  degenerate  generalized  slices  in  which  an

5 For  example,  if  the  stride  parameters in the previous example are
changed to {1, 1, 1}, the first few elements of the resulting sequence
of indices will be
(0, 0, 0, 3),
(0, 0, 1, 4),
(0, 0, 2, 5),
(0, 1, 0, 4),
(0, 1, 1, 5),
(0, 1, 2, 6),
...

6 If a degenerate slice is used as the argument to the non-const version
of operator[](const gslice&), the resulting behavior is undefined.

26.2.4.1  gslice constructors                        [lib.gslice.cons]
gslice::gslice();
gslice::gslice(int start, const valarray<int>& lengths, const valarray<int>& strides);
gslice::gslice(const gslice&);

1 The  default constructor creates a gslice which specifies no elements.
The constructor with arguments builds a gslice based on  a  specifica­
tion of start, lengths, and strides, as explained in the previous sec­
tion.

26.2.4.2  gslice access functions                  [lib.gslice.access]
int start() const;
valarray<int> length() const;
valarray<int> stride() const;
These  access  functions  return  the  representation  of  the  start,
lengths, or strides specified for the gslice.

26.2.5  Template class gslice_array        [lib.template.gslice.array]
template <class T> class gslice_array {
public:
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 fill(const T&);
private:
gslice_array();
gslice_array(const gslice_array&);
gslice_array& operator=(const gslice_array&);
//  remainder implementation defined
};

1 This  template is a helper template used by the slice subscript opera­
tor
gslice_array<T> valarray<T>::operator[](const gslice&);
It has reference semantics to a subset of  an  array  specified  by  a
gslice object.

2 Thus, the expression
a[gslice(1, length, stride)] = b
has  the  effect of assigning the elements of b to a generalized slice
of the elements in a.

3 Note that programmers may not instantiate gslice_array, since all  its
constructors are private.  It is intended purely as a helper class and
should be transparent to the user.

26.2.5.1  gslice_array constructors            [lib.gslice.array.cons]
gslice_array::gslice_array();
gslice_array::gslice_array(const gslice_array&);

1 The gslice_array template has no public constructors.  It declares the
above  constructors  to  be  private.   These constructors need not be
defined.

26.2.5.2  gslice_array assignment            [lib.gslice.array.assign]
void operator=(const valarray<T>&) const;
gslice_array& operator=(const gslice_array&);

1 The second of these two assignment operators is declared  private  and
need not be defined.  The first has reference semantics, assigning the
values of the argument array elements  to  selected  elements  of  the
valarray<T> object to which the gslice_array refers.

26.2.5.3  gslice_array computed         [lib.gslice.array.comp.assign]
assignment
void gslice_array::operator*= (const valarray<T>&) const;
void gslice_array::operator/= (const valarray<T>&) const;
void gslice_array::operator%= (const valarray<T>&) const;
void gslice_array::operator+= (const valarray<T>&) const;
void gslice_array::operator-= (const valarray<T>&) const;
void gslice_array::operator^= (const valarray<T>&) const;
void gslice_array::operator&= (const valarray<T>&) const;
void gslice_array::operator|= (const valarray<T>&) const;
void gslice_array::operator<<=(const valarray<T>&) const;
void gslice_array::operator>>=(const valarray<T>&) const;

1 These computed assignments  have  reference  semantics,  applying  the
indicated operation to the elements of the argument array and selected
elements of the valarray<T> object to which  the  gslice_array  object
refers.

26.2.5.4  gslice_array fill function           [lib.gslice.array.fill]
void fill(const T&);

1 This  function  has  reference  semantics,  assigning the value of its
argument to the elements  of  the  valarray<T>  object  to  which  the
gslice_array object refers.

template <class T> class mask_array {
public:
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 fill(const T&);
private:
//  remainder implementation defined
};

1 This template is a helper template used by the mask subscript operator
It  has  reference  semantics  to  a subset of an array specified by a
has the effect of assigning the elements of b to the  masked  elements
in a (those for which the corresponding element in mask is true.

2 Note  that C++ programs may not declare instances of mask_array, since
all its constructors are private.  It is intended purely as  a  helper
class, and should be transparent to the user.

1 The  mask_array  template has no public constructors.  It declares the
above constructors to be private.   These  constructors  need  not  be
defined.

void operator=(const valarray<T>&) const;

1 The  second  of these two assignment operators is declared private and
need not be defined.  The first has reference semantics, assigning the
values  of  the  argument  array  elements to selected elements of the
valarray<T> object to which it refers.

assignment

1 These  computed  assignments  have  reference  semantics, applying the
indicated operation to the elements of the argument array and selected
elements of the valarray<T> object to which the mask object refers.

void fill(const T&);
This  function  has  reference  semantics,  assigning the value of its
argument to the elements  of  the  valarray<T>  object  to  which  the

26.2.7  Template class                   [lib.template.indirect.array]
indirect_array
template <class T> class indirect_array {
public:
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 fill(const T&);
private:
indirect_array();
indirect_array(const indirect_array&);
indirect_array& operator=(const indirect_array&);
//  remainder implementation defined
};

1 This template is a helper template  used  by  the  indirect  subscript
operator
indirect_array<T> valarray<T>::operator[](const valarray<int>&);
It  has  reference  semantics  to a subset of an array specified by an
indirect_array.  Thus the expression
a[indirect] = b;
has the effect of assigning the elements of b to  the  elements  in  a
whose indices appear in indirect.

2 Note that C++ programs may not declare  instances  of  indirect_array,
since  all  its  constructors are private.  It is intended purely as a
helper class, and should be transparent to the user.

26.2.7.1  indirect_array constructors        [lib.indirect.array.cons]
indirect_array::indirect_array();
indirect_array::indirect_array(const indirect_array&);
The indirect_array template has no public constructors.  The construc­
tors  listed  above  are  private.   These  constructors  need  not be
defined.

26.2.7.2  indirect_array assignment        [lib.indirect.array.assign]
void operator=(const valarray<T>&) const;
indirect_array& operator=(const indirect_array&);

1 The second of these two assignment operators is declared  private  and
need not be defined.  The first has reference semantics, assigning the
values of the argument array elements  to  selected  elements  of  the
valarray<T> object to which it refers.

2 If  the  indirect_array specifies an element in the valarray<T> object
to which it refers more than once, the behavior is undefined.

3 For example,
int addr = {2, 3, 1, 4, 4};
valarray<double> a(0., 10), b(1., 5);
array[indirect] = b;
results in undefined behavior since element 4 is  specified  twice  in
the indirection.

26.2.7.3  indirect_array              [lib.indirect.array.comp.assign]
computed assignment
void indirect_array::operator*= (const valarray<T>&) const;
void indirect_array::operator/= (const valarray<T>&) const;
void indirect_array::operator%= (const valarray<T>&) const;
void indirect_array::operator+= (const valarray<T>&) const;
void indirect_array::operator-= (const valarray<T>&) const;
void indirect_array::operator^= (const valarray<T>&) const;
void indirect_array::operator&= (const valarray<T>&) const;
void indirect_array::operator|= (const valarray<T>&) const;
void indirect_array::operator<<=(const valarray<T>&) const;
void indirect_array::operator>>=(const valarray<T>&) const;

1 These computed assignments  have  reference  semantics,  applying  the
indicated operation to the elements of the argument array and selected
elements of the valarray<T> object to which the indirect_array  object
refers.

2 If  the  indirect_array specifies an element in the valarray<T> object
to which it refers more than once, the behavior is undefined.

26.2.7.4  indirect_array fill function       [lib.indirect.array.fill]
void fill(const T&);

1 This function has reference semantics,  assigning  the  value  of  its
argument  to the elements of the valarray<T> object to which the indi­
rect_array object refers.

26.3  Generalized numeric operations                 [lib.numeric.ops]

--<stl numerics (TBD)>

2 Table 3:

Table 3--Header <stl numerics (TBD)> synopsis

+--------------------------------------------+
|         Type                  Name(s)      |
+--------------------------------------------+
|Template functions:                         |
|accumulate [2]            inner_product [2] |
+--------------------------------------------+

26.3.1  Accumulate                                    [lib.accumulate]
template <class InputIterator, class T>
T accumulate(InputIterator first, InputIterator last, T init);

template <class InputIterator, class T, class BinaryOperation>
T accumulate(InputIterator first, InputIterator last, T init,
BinaryOperation binary_op);

1 Initializes the accumulator acc with the initial value init  and  then
modifies  it with acc = acc + *i or acc = binary_op(acc, *i) for every
iterator i in the range [first, last) in order.9) binary_op is assumed
not to cause side effects.

26.3.2  Inner product                              [lib.inner.product]

_________________________
9) accumulate is similar to the APL reduction operator and Common Lisp
reduce  function,  but it avoids the difficulty of defining the result
of reduction on an empty sequence by always requiring an initial  val­
ue.

template <class InputIterator1, class InputIterator2, class T>
T inner_product(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, T init);

template <class InputIterator1, class InputIterator2, class T,
class BinaryOperation1, class BinaryOperation2>
T inner_product(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, T init,
BinaryOperation1 binary_op1, BinaryOperation2 binary_op2);

1 Computes its result by initializing the accumulator acc with the  ini­
tial value init and then modifying it with
acc = acc + (*i1) * (*i2)
or
acc = binary_op1(acc, binary_op2(*i1, *i2))
for  every  iterator  i1 in the range [first, last) and iterator i2 in
the range [first2, first2 + (last - first))  in order.

2 binary_op1 and binary_op2 shall not cause side effects.

26.3.3  Partial sum                                  [lib.partial.sum]
template <class InputIterator, class OutputIterator>
OutputIterator partial_sum(InputIterator first, InputIterator last,
OutputIterator result);

template <class InputIterator, class OutputIterator, class BinaryOperation>
OutputIterator partial_sum(InputIterator first, InputIterator last,
OutputIterator result, BinaryOperation binary_op);

1 Assigns to every iterator i in the range [result,  result  +  (last  -
first)) a value correspondingly equal to
((...(*first + *(first + 1)) + ...) + *(first + (i - result)))
or
binary_op(binary_op(..., binary_op(*first, *(first + 1)),...), *(first + (i - result)))

2 Returns result + (last - first).

3 Complexity:  Exactly  (last - first) - 1 applications of binary_op are
performed.

4 binary_op is expected not to have any side  effects.   result  may  be
equal to first.

template <class InputIterator, class OutputIterator>
OutputIterator result);

template <class InputIterator, class OutputIterator, class BinaryOperation>
OutputIterator result, BinaryOperation binary_op);

1 Assigns  to  every  element  referred  to  by  iterator i in the range
[result + 1, result + (last - first)) a value correspondingly equal to

*(first   +  (i  -  result))  -  *(first  +  (i  -  result)  -  1)  or
binary_op(*(first + (i - result)), *(first  +  (i  -  result)  -  1)).
result gets the value of *first.

2 binary_op  shall  not  have  any side effects.  result may be equal to
first.

3 Returns result + (last - first).

4 Complexity: Exactly (last - first) - 1 applications of  binary_op  are
performed.

26.4  C Library                                           [lib.c.math]

--<cmath>

--<cstdlib> abs(), div(), rand(), srand()

2 Table 4:

+-----------------------------------------+
| Type                Name(s)             |
+-----------------------------------------+
|Macro:   HUGE_VAL                        |
+-----------------------------------------+
|Functions:                               |
|acos     ceil       fabs    ldexp   pow  |
|asin     cos        floor   log     sin  |
|atan     cosh       fmod    log10   sinh |
|atan2    exp        frexp   modf    sqrt |
+-----------------------------------------+

3 Table 5:

+----------------------------+
| Type          Name(s)      |
+----------------------------+
|Macros:   RAND_MAX          |
+----------------------------+
|Types:    div_t      ldiv_t |
+----------------------------+
|Functions:                  |
|abs       labs       srand  |
|div       ldiv       rand   |
+----------------------------+

4 The contents are the same as the Standard C library.