Showing posts with label Numerical Library. Show all posts
Showing posts with label Numerical Library. Show all posts

Friday, October 4, 2024

valarray - helper classes

Overview
The standard library provides valarray class is similar to a vector but mathematical functions can be applied directly to all the elements. It also allows to get different cross section of the elements in the valarray including  multidimensional using helper classes.

Details
The overloaded [] operator of valarray allows enables extraction and manipulation of its elements in different cross section using a set of helper classes listed below.

NameDescription
slice
A definition to a single dimension collection of elements to a valarray.
slice_arrayA collection of elements in the valarray referred by the slice.
gsliceA definition to a multi dimension collection of elements to a valarray.
gslice_arrayA collection of elements in the valarray referred by the slice.
mask_arrayvalarray<bool> object that refers to individual elements in a valarray.
indirect_arrayvalarray<size_t> object that contain indices to individual elements in a valarray.

The following discusses each of these in detail.

slice
slice class represents a valarray slice selector similar to BLAS slice. It does not contain nor refers to any element - it only describes a selection of elements to be used as an index in valarray::operator[].

slice is defined by the following:
NameDescription
startindex of the first element in the selection.
sizenumber of elements in the selection.
stridespan that separates the elements selected.

The elements in a slice are  computed as below.
(start + 0 * stride), (start + 1 * stride), ..., (start + (size - 1) * stride).

slice class defines following members.
NameDescription
slice(size_t start, size_t size, size_t stride)Constructor
size_t start()returns start.
size_t size()returns size.
size_t stride()returns stride.

slice_array
Represents an intermediate type returned by valarray's subscript operator (operator[]) when used with slices.
It references the elements in the valarray object that are selected by the slice, and overloads the assignment and compound assignment operators, allowing direct access to the elements in the selection.
The type is convertible to a valarray, producing a new object with copies of the referred elements.

The following members are defined.
template <class T> class slice_array {
public:
  typedef T value_type;
  void operator=   (const valarray<T>&) const;
  void operator*=  (const valarray<T>&) const;
  void operator/=  (const valarray<T>&) const;
  void operator%=  (const valarray<T>&) const;
  void operator+=  (const valarray<T>&) const;
  void operator-=  (const valarray<T>&) const;
  void operator^=  (const valarray<T>&) const;
  void operator&=  (const valarray<T>&) const;
  void operator|=  (const valarray<T>&) const;
  void operator<<= (const valarray<T>&) const;
  void operator>>= (const valarray<T>&) const;
  void operator=(const T&) const;

  slice_array() = delete;
  slice_array(const slice_array&);
  const slice_array& operator= (const slice_array&) const;
  ~slice_array();
};

The following diagram depicts slice and slice_array pictorially.


The following examples demonstrates getting diagonal elements in a 3x3 matrix.
valarray<int> m {1,2,3,4,5,6,7,8,9};
//diag:{1,5,9}
auto diag = valarray(m[slice(0,3,4)]);

gslice
gslice class represents a valarray generalized slice selector (a multidimensional slice). It does not contain nor refers to any element - it only describes a selection of elements to be used as an index in valarray::operator[].

gslice is defined by the following :
NameDescription
startindex of the first element in the selection.
sizean array that defines the number of elements in each dimension
stridean array that defines the number of positions between successive elements in each dimension

The elements in a slice are  computed as kj=s+Σj(ijdj)
where s is starting point, ij  is list of strides, dis list of lengths.

For example, consider the following 3D matrix. 

Suppose we want to extract all the diagonal elements in all the three pages, a gslice with 
start = 0, strides = {16,16,5} and lengths = {3,1,4} can be used.

As shown below, the matrix represents 12 (3*1*4) diagonal elements. They are computed as below:

0 + 0*16 + 0*16 + 0*5( 0), 0 + 0*16 + 0*16 + 1*5( 5), 0 + 0*16 + 0*16 + 2*5(10)0 + 0*16 + 0*16 + 3*5(15)
0 + 0*16 + 1*16 + 0*5(16), 0 + 0*16 + 1*16 + 1*5(21), 0 + 0*16 + 1*16 + 2*5(26)0 + 0*16 + 1*16 + 3*5(31)
0 + 1*16 + 1*16 + 0*5(32), 0 + 1*16 + 1*16 + 1*5(37), 0 + 1*16 + 1*16 + 2*5(42)0 + 1*16 + 1*16 + 3*5(47)

gslice defines following members.
NameDescription
gslice(size_t start, valarray<size_t> size, valarray<size_tstride)Constructor
size_t start()returns start.
valarray<size_t> size()returns size.
valarray<size_t> stride()returns stride.

gslice_array
Represents an intermediate type returned by valarray's subscript operator (operator[]) when used with gslices.
It references the elements in the valarray object that are selected by the gslice, and overloads the assignment and compound assignment operators, allowing direct access to the elements in the selection.
The type is convertible to a valarray, producing a new object with copies of the referred elements.

The following members are defined.
template <class T> class gslice_array {
public:
  typedef T value_type;
  void operator=   (const valarray<T>&) const;
  void operator*=  (const valarray<T>&) const;
  void operator/=  (const valarray<T>&) const;
  void operator%=  (const valarray<T>&) const;
  void operator+=  (const valarray<T>&) const;
  void operator-=  (const valarray<T>&) const;
  void operator^=  (const valarray<T>&) const;
  void operator&=  (const valarray<T>&) const;
  void operator|=  (const valarray<T>&) const;
  void operator<<= (const valarray<T>&) const;
  void operator>>= (const valarray<T>&) const;
  void operator=(const T&) const;

  gslice_array() = delete;
  gslice_array(const gslice_array&);
  const gslice_array& operator= (const gslice_array&) const;
  ~gslice_array();
};

The following diagram depicts slice and gslice_array pictorially.

The following examples demonstrates getting diagonal elements in a 3D 4x4  matrix.
valarray<int> m(4*4*3);
int n = 0;
for (auto i=0; i<3; ++i) 
    for (auto k=0; k<4; ++k) 
        for (auto j=0; j<4; ++j) 
            m[n++]=(k+1)*100+(j+1)*10+(i+1);

//m:{111 121 131 141 211 221 231 241 311 321 331 341 411 421 431 441}
//m:{112 122 132 142 212 222 232 242 312 322 332 342 412 422 432 442}
//m:{113 123 133 143 213 223 233 243 313 323 333 343 413 423 433 443 }
//d:{111 221 331 441 112 222 332 442 113 223 333 443}
auto d = valarray(m[gslice(0,{3,1,4},{16,16,5})]);

mask_array
Represents an intermd="mask_array"ediate type returned by valarray's subscript operator (operator[]) when used with masks.
It references the elements in the valarray object that are selected by the an array of masks stored in a valarray<bool>  and overloads the assignment and compound assignment operators, allowing direct access to the elements in the selection.
The type is convertible to a valarray, producing a new object with copies of the referred elements.

The following members are defined.
template <class T> class mask_array {
public:
  typedef T value_type;
  void operator=   (const valarray<T>&) const;
  void operator*=  (const valarray<T>&) const;
  void operator/=  (const valarray<T>&) const;
  void operator%=  (const valarray<T>&) const;
  void operator+=  (const valarray<T>&) const;
  void operator-=  (const valarray<T>&) const;
  void operator^=  (const valarray<T>&) const;
  void operator&=  (const valarray<T>&) const;
  void operator|=  (const valarray<T>&) const;
  void operator<<= (const valarray<T>&) const;
  void operator>>= (const valarray<T>&) const;
  void operator=(const T&) const;

  mask_array() = delete;
  mask_array(const mask_array&);
  const mask_array& operator= (const mask_array&) const;
  ~mask_array();
};
The following diagram depicts mask_array pictorially.



The following examples returns values in even indices.
valarray<int> v{1,2,3,4,5,6,7,8,9,10};
valarray<bool> m{1,0,1,0,1,0,1,0,1,0};
//odd:1 3 5 7 9
auto  odd = valarray(v[m]);

indirect_array
Represents an intermediate type returned by valarray's subscript operator (operator[]) when used with indices.
It references the elements in the valarray object that are selected by the an array of indices stored in a valarray<size_t>  and overloads the assignment and compound assignment operators, allowing direct access to the elements in the selection.
The type is convertible to a valarray, producing a new object with copies of the referred elements.

The following members are defined.
template <class T> class indirect_array {
public:
  typedef T value_type;
  void operator=   (const valarray<T>&) const;
  void operator*=  (const valarray<T>&) const;
  void operator/=  (const valarray<T>&) const;
  void operator%=  (const valarray<T>&) const;
  void operator+=  (const valarray<T>&) const;
  void operator-=  (const valarray<T>&) const;
  void operator^=  (const valarray<T>&) const;
  void operator&=  (const valarray<T>&) const;
  void operator|=  (const valarray<T>&) const;
  void operator<<= (const valarray<T>&) const;
  void operator>>= (const valarray<T>&) const;
  void operator=(const T&);

  indirect_array() = delete;
  indirect_array(const gslice_array&);
  const indirect_array& operator= (const indirect_array&) const;
  ~indirect_array();
};
The following diagram depicts indirect_array pictorially.
The following examples returns values in odd indices.
valarray<int> v{1,2,3,4,5,6,7,8,9,10};
valarray<size_t> i{1,3,5,6,9};
//even:2 4 6 7 10 
auto  even = valarray(v[i]);







Saturday, September 28, 2024

valarray

 Overview
In C/C++,  fixed size arrays can be allocated on the stack and variable size arrays are allocated on the heap. However this is inflexible and also managing  the array such as adding elements, removing elements or retrieving will require extra code. 
The standard library provides valarray class is similar to a vector but mathematical functions can be applied directly to all the elements. It also allows to get different cross section of the elements in the valarray including  multidimensional using helper classes.

Details
valarray are basically template based, class is designed to hold an array of values of arithmetic types, and easily perform mathematical operations on them. It also allows special mechanisms to refer to subsets of elements in the arrays.
Most mathematical operations can be applied directly to valarray objects, including arithmetic and comparison operators, affecting all its elements.

Syntax
The syntax is as below. Template parameter represents the datatype to store. 
template < class T > 
class valarray;

Members
 It defines following types
member typedefinition
value_typeThe first template parameter (T)

Helper classes
The following helper classes are used to refer to a cross section of elements within a valarray.
NameDescription
slice➹A definition to a single dimension collection of elements to a valarray.
slice_array➹A collection of elements in the valarray referred by the slice.
gslice➹A definition to a multi dimension collection of elements to a valarray.
gslice_array➹A collection of elements in the valarray referred by the slice.
mask_array➹valarray<bool> object that refers to individual elements in a valarray.
indirect_array➹valarray<size_t> object that contain indices to individual elements in a valarray.

Functionality
Constructors
NameDescription
valarray()Default Constructor
Example:
//v:{}
valarray<int> v;
valarray(size_type n)Constructs a container with n elements initialized with T().
Example:
//v:{0,0,0,0,0}
valarray<int> v(5);
valarray(size_type n, const value_type& val)Constructs a container with n elements initialized with with val.
Example:
//v:{10,10,10,10,10}
valarray<int> v(5,10);
valarray(const valarray& x)copy constructor
valarray(valarray&& x)move constructor
valarray(slice_array<value_type> sa)slice_array constructor
Example:
valarray<int> m {1,2,3,4,5,6,7,8,9};
//diag:{1,5,9}
auto diag = valarray(m[slice(0,3,4)]);
valarray(gslice_array<value_type> gsa)gslice_array constructor
Example:
valarray<int> m(4*4*3);
int n = 0;
for (auto i=0; i<3; ++i) 
    for (auto k=0; k<4; ++k) 
        for (auto j=0; j<4; ++j) 
            m[n++]=(k+1)*100+(j+1)*10+(i+1);

//m:{111 121 131 141 211 221 231 241 311 321 331 341 411 421 431 441}
//m:{112 122 132 142 212 222 232 242 312 322 332 342 412 422 432 442}
//m:{113 123 133 143 213 223 233 243 313 323 333 343 413 423 433 443 }

//d:{111 221 331 441 112 222 332 442 113 223 333 443}
auto d = valarray(m[gslice(0,{3,1,4},{16,16,5})]);
valarray(mask_array<bool> ma)mask_array constructor
Example:
valarray<int> v{1,2,3,4,5,6,7,8,9,10};
valarray<bool> m{1,0,1,0,1,0,1,0,1,0};
//odd:1 3 5 7 9
auto  odd = valarray(v[m]);
valarray(indiriect_array<size_t> sa)indirect_array constructor
Example:
valarray<int> v{1,2,3,4,5,6,7,8,9,10};
valarray<size_t> i{1,3,5,6,9};
//even:2 4 6 7 10 
auto  even = valarray(v[i]);
valarray(initializer_list<value_type> il)initializer_list constructor
Example:
//v:{1,2,3,4,5}
valarray<int> v{1,2,3,4,5};

Iterator
iterators are externally supported.
NameDescription
/*unspecified*/ begin()
/*unspecified*/ end()
Returns an unspecified iterator to begin and end.
Example:
valarray<int> v{1,2,3,4,5};
//prints 1 2 3 4 5
for (auto itr=begin(v); itr!=end(v); ++itr)
    cout << *itr << ' ';

Overloaded Operators
NameDescription
valarray operator+() 
valarray operator-() 
valarray operator~() 
valarray <bool> operator!()
Unary operators.
Return valarray after applying the operator.


valarray& operator*= (const valarray& v)
valarray& operator*= (const value_type & val)
Self multiplication operators.
Return valarray after applying the operator.
valarray& operator/= (const valarray& v)
valarray& operator/= (const value_type & val)
Self division operators.
Return valarray after applying the operator.
valarray& operator%= (const valarray& v)
valarray& operator%= (const value_type & val)
Self modulo operators.
Return valarray after applying the operator.
valarray& operator+= (const valarray& v)
valarray& operator+= (const value_type & val)
Self add operators.
Return valarray after applying the operator.
valarray& operator-= (const valarray& v)
valarray& operator-= (const value_type & val)
Self subtraction operators.
Return valarray after applying the operator.
valarray& operator^= (const valarray& v)
valarray& operator^= (const value_type & val)
Self xor operators.
Return valarray after applying the operator.
valarray& operator&= (const valarray& v)
valarray& operator&= (const value_type & val)
Self and operators.
Return valarray after applying the operator.
valarray& operator|= (const valarray& v)
valarray& operator|= (const value_type & val)
Self or operators.
Return valarray after applying the operator.
valarray& operator<<= (const valarray& v)
valarray& operator<<= (const value_type & val)
Self left shift operators.
Return valarray after applying the operator.
valarray& operator>>= (const valarray& v)
valarray& operator>>= (const value_type & val)
Self right shift operators.
Return valarray after applying the operator.
valarray<T> operator+ ( const valarray<T>& l, const valarray<T>& r)
valarray<T> operator+ ( const value_type & val, const valarray<T>& r)
valarray<T> operator+ ( const valarray<T>& l, const value_type & val)
Binary addition operators.
Return valarray after applying the operator.
valarray<T> operator- ( const valarray<T>& l, const valarray<T>& r)
valarray<T> operator- ( const value_type & val, const valarray<T>& r)
valarray<T> operator- ( const valarray<T>& l, const value_type & val)
Binary subtraction operators.
Return valarray after applying the operator.
valarray<T> operator* ( const valarray<T>& l, const valarray<T>& r)
valarray<T> operator* ( const value_type & val, const valarray<T>& r)
valarray<T> operator* ( const valarray<T>& l, const value_type & val)
Binary multiplication operators.
Return valarray after applying the operator.
valarray<T> operator/ ( const valarray<T>& l, const valarray<T>& r)
valarray<T> operator/ ( const value_type & val, const valarray<T>& r)
valarray<T> operator/ ( const valarray<T>& l, const value_type & val)
Binary divide operators.
Return valarray after applying the operator.
valarray<T> operator% ( const valarray<T>& l, const valarray<T>& r)
valarray<T> operator% ( const value_type & val, const valarray<T>& r)
valarray<T> operator% ( const valarray<T>& l, const value_type & val)
Binary modulo operators.
Return valarray after applying the operator.
valarray<T> operator& ( const valarray<T>& l, const valarray<T>& r)
valarray<T> operator& ( const value_type & val, const valarray<T>& r)
valarray<T> operator& ( const valarray<T>& l, const value_type & val)
Binary AND operators.
Return valarray after applying the operator.
valarray<T> operator| ( const valarray<T>& l, const valarray<T>& r)
valarray<T> operator| ( const value_type & val, const valarray<T>& r)
valarray<T> operator| ( const valarray<T>& l, const value_type & val)
Binary OR operators.
Return valarray after applying the operator.
valarray<T> operator^ ( const valarray<T>& l, const valarray<T>& r)
valarray<T> operator^ ( const value_type & val, const valarray<T>& r)
valarray<T> operator^ ( const valarray<T>& l, const value_type & val)
Binary XOR operators.
Return valarray after applying the operator.
valarray<T> operator<<( const valarray<T>& l, const valarray<T>& r)
valarray<T> operator<< ( const value_type & val, const valarray<T>& r)
valarray<T> operator<< ( const valarray<T>& l, const value_type & val)
Binary left shift operators.
Return valarray after applying the operator.
valarray<T> operator>>( const valarray<T>& l, const valarray<T>& r)
valarray<T> operator>> ( const value_type & val, const valarray<T>& r)
valarray<T> operator>> ( const valarray<T>& l, const value_type & val)
Binary right shift operators.
Return valarray after applying the operator.
valarray<bool> operator&&( const valarray<T>& l, const valarray<T>& r)
valarray<T> operator&& ( const value_type & val, const valarray<T>& r)
valarray<T> operator&& ( const valarray<T>& l, const value_type & val)
Logical AND operators.
Return valarray after applying the operator.
valarray<bool> operator||( const valarray<T>& l, const valarray<T>& r)
valarray<T> operator|| ( const value_type & val, const valarray<T>& r)
valarray<T> operator|| ( const valarray<T>& l, const value_type & val)
Logical OR operators.
Return valarray after applying the operator.
valarray<T>& operator=( const valarray<T>& other )
valarray<T>& operator=( valarray<T>&& other ) 
valarray<T>& operator=( const T& val )
valarray<T>& operator=( const slice_array<T>& other )
valarray<T>& operator=( const gslice_array<T>& other )
valarray<T>& operator=( const mask_array<T>& other )
valarray<T>& operator=( const indirect_array<T>& other )
valarray<T>& operator=( initializer_list<T> il )
Assignment operators.
Return valarray after applying the operator.

Element Access
NameDescription
T& operator[]( size_t pos )
valarray<T>  operator[]( slice slicearr ) 
slice_array<T> operator[]( slice slicearr )
valarray<T>  operator[]( const gslice& gslicearr ) 
gslice_array<T> operator[]( const gslice& gslice )
valarray<T>  operator[]( const valarray<bool>& boolarr ) 
mask_array<T> operator[]( const valarray<bool>& boolarr )
valarray<T>  operator[]( const valarray<size_t>& indarr ) 
indirect_array<T> operator[]( const valarray<size_t>& indarr )
Index operator



Modifiers
NameDescription
void resize (size_type n, const value_type& val )Size is also changed to n. All elements are initialized to val. 
Example
valarray<int> v{1,2,3};
//v:{9,9,9,9,9,9,9,9}
v.resize(8,9);
void swap( valarray& other )

Swaps contents with another valarray.
Example:
valarray<int> v{1,2,3,4};
valarray<int> v2{6,7,8,9};
v.swap(v2);

Non Modifiers
NameDescription
size_type size() Returns the number of elements.
Example:
valarray<int> v{1,2,3,4,5};
//prints 5
cout << v.size();
min() 
T max()
Returns the minimum and maximum element in the valarray.
Example:
valarray<int> v{1,2,3,4,5};
//prints 1  5
cout << v.min() << "  " << v.max();
sum() 

Returns sum of all the element in the valarray.
Example:
valarray<int> v{1,2,3,4,5};
//prints 15
cout << v.sum();
valarray shift (int n)
Returns the valarray of the same size after shifting n elements to the left if n>0 or right if n< 0. The remaining elements are set to default value.

Example:
valarray<int> v{1,2,3,4,5};
//v2:{3,4,5,0,0}
auto v2 = v.shift(2);
//v3:{0,0,1,2,3}
auto v3 = v.shift(-2);
valarray shift (int n)

Returns the valarray of the same size after circularly shifting n elements to the left if n>0 or right if n< 0. 

Example:
valarray<int> v{1,2,3,4,5};
//v2:{3,4,5,1,2}
auto v2 = v.cshift(2);
//v3:{4,5,1,2,3}
auto v3 = v.shift(-2);
valarray<T> apply( T func(T) )

Returns a new valarray of the same size with values which are acquired by applying function func to the previous values of the elements.

Example:
valarray<int> v{1,2,3,4,5};
//v2:{83,86,77,15,93}
valarray<int> v2 = v.apply([](int n){return rand()%100;});


Math Functions
The following math functions are overloaded to accept valarray and return after applying the function.

NameDescription

valarray<T> abs( const valarray<T>& va )
Absolute function.
Returns an valarray after applying the function abs to each element of valarray.
Example:
valarray<int> v{-1,2,-3,4,-5};
//v2:{1,2,3,4,5}
valarray<int> v2 = abs(v);
valarray<T> exp( const valarray<T>& va )
valarray<T> log( const valarray<T>& va )
valarray<T> log10( const valarray<T>& va )
Logarithmic  functions.
Returns an valarray after applying the function exp/log/log10 to each element of valarray.


valarray<T> pow( const valarray<T>& va )
valarray<T> sqrt( const valarray<T>& va )
Power functions.
Returns an valarray after applying the function pow/sqrt to each element of valarray.


valarray<T>sin( const valarray<T>& va )
valarray<T> cos( const valarray<T>& va )
valarray<T> tan( const valarray<T>& va )
Trigonometric functions.
Returns an valarray after applying the function sin/cos/tan to each element of valarray.


valarray<T> asin( const valarray<T>& va )
valarray<T> acos( const valarray<T>& va )
valarray<T> atan( const valarray<T>& va )
valarray<T> atan2( const valarray<T>& va )
Trigonometric arc functions
Returns an valarray after applying the function asin/acos/atan/atan2 to each element of valarray.


valarray<T> sinh( const valarray<T>& va )
valarray<T> cosh( const valarray<T>& va )
valarray<T> tanh( const valarray<T>& va )
Hyperbolic functions.
Returns an valarray after applying the function sinh/cosh/tanh to each element of valarray.