Array Operations
[lite array - A C++ Multidimensional Array Library]

Classes

class  lite::array_comparator
 This class defines a function object that can be used to compare two compatible arrays to define an ordering. More...

Functions

template<typename size_type_ >
int lite::volume (const size_type_ &sz)
 Returns the total volume of an array of the size sz.
template<typename value_type_ , int n0_..., int nN_>
const array<...> lite::from (value_type_(&a)[n0_]...[nN_])
 constructs a reference array to a C array.
template<typename iterator_type_ >
const array<...> lite::from (iterator_type_ it, int n0..., int nN)
 Constructs a reference array from a pointer (or any other appropriate random access iterator) with the specified dimension sizes.
template<typename iterator_type_ , typename type0_... , typename typeN_ >
const array<...> lite::from (iterator_type_ it, const pack< type0_..., typeN_ > &size)
 Constructs a reference array from a pointer (or any other appropriate random access iterator) with the specified size.
template<typename dst_array_type_ , typename src_signature_ , typename src_traits_type_ , typename src_rep_ >
const array<...> lite::array_cast (const array< src_signature_, src_traits_type_, src_rep_ > &ar)
 Casts the array ar to a compatible array type that has the same signature and traits type as dst_array_type_.
template<typename char_type_ , typename char_traits_type_ , typename signature_ , typename traits_type_ , typename rep_ >
std::basic_ostream< char_type_,
char_traits_type_ > & 
lite::operator<< (std::basic_ostream< char_type_, char_traits_type_ > &os, const array< signature_, traits_type_, rep_ > &ar)
 Prints the array ar to the output stream os.
template<typename char_type_ , typename char_traits_type_ , typename signature_ , typename traits_type_ , typename rep_ >
std::basic_istream< char_type_,
char_traits_type_ > & 
lite::operator>> (std::basic_istream< char_type_, char_traits_type_ > &is, const array< signature_, traits_type_, rep_ > &ar)
 Scans (reads) the array ar from the input stream is.
template<typename char_type_ , typename char_traits_type_ , typename signature_ , typename traits_type_ , typename rep_ >
std::basic_istream< char_type_,
char_traits_type_ > & 
lite::operator>> (std::basic_istream< char_type_, char_traits_type_ > &is, array< signature_, traits_type_, rep_ > &ar)
 Scans (reads) the array ar from the input stream is.

Detailed Description

The library provides a rich set of array operations. The next example provides a brief list of operations that are supported. In the example, the type Array could be any general array (single/multi dimensional with fixed or variable size), the type Matrix could be any 2-dimensional array with fixed or variable size dimensions and the type Vector could be any 1-dimensional array of fixed or variable size.

    // general array operations:

    typedef array<float[5][20][20]> Array;

    Array A, A1, A2, B;
    float c;
    bool b;
    int res;

    B = A;                  //  copy A to B, possibly resizing B
    swap(A, B);             //  swap A and B

    A = c;                  //  A(i,j,k) = c
    B = +A;                 //? B(i,j,k) = +A(i,j,k)
    B = -A;                 //? B(i,j,k) = -A(i,j,k)
    B = A + c;              //? B(i,j,k) = A(i,j,k) + c
    B = c + A;              //? B(i,j,k) = c + A(i,j,k)
    B = A + c;              //? B(i,j,k) = A(i,j,k) + c
    B = A - c;              //? B(i,j,k) = A(i,j,k) - c
    B = c - A;              //? B(i,j,k) = c - A(i,j,k)
    B = c * A;              //? B(i,j,k) = c * A(i,j,k)
    B = A * c;              //? B(i,j,k) = A(i,j,k) * c
    B = A / c;              //? B(i,j,k) = A(i,j,k) / c
    B = A / c;              //? B(i,j,k) = A(i,j,k) / c
    B = A1 + A2;            //? B(i,j,k) = A1(i,j,k) + A2(i,j,k)                    
    B = A1 - A2;            //? B(i,j,k) = A1(i,j,k) - A2(i,j,k)
    B = A1 - A2;            //? B(i,j,k) = A1(i,j,k) - A2(i,j,k)
    B = A1 | A2;            //? B(i,j,k) = A1(i,j,k) * A2(i,j,k)

    A += c;                 //  A(i,j,k) += c
    A -= c;                 //  A(i,j,k) -= c
    A *= c;                 //  A(i,j,k) *= c
    A /= c;                 //  A(i,j,k) /= c
    B += A;                 //  B(i,j,k) += A(i,j,k)
    B -= A;                 //  B(i,j,k) -= A(i,j,k)

    b = B < A;              //  true if B(i,j,k) < A(i,j,k) for all i,j,k
    b = B <= A;             //  true if B(i,j,k) <= A(i,j,k) for all i,j,k
    b = B == A;             //  true if B(i,j,k) == A(i,j,k) for all i,j,k
    b = B != A;             //  is equivalent to !(B==A)
    b = B >= A;             //  true if B(i,j,k) >= A(i,j,k) for all i,j,k
    b = B > A;              //  true if B(i,j,k) > A(i,j,k) for all i,j,k
    res = compare(B, A);    //  lexicographically compare A and B. 
                            //  returns -1 if B is before A, +1 if B is after A and 0 otherwise

    c = norm(A);            //  returns the sum of the squares of all of the elements
    c = abs(A);             //  returns sqrt(norm(A))
    B = normalized(A);      //  returns a scaled copy of A such that abs(normalized(A)) = 1

    B = min(A1, A2);        //? B(i,j,k) = min(A1(i,j,k), A2(i,j,k))
    B = max(A1, A2);        //? B(i,j,k) = max(A1(i,j,k), A2(i,j,k))

    std::cin >> A;          //  reads from a std::basic_istream
    std::cout << A;         //  writes to a std::basic_ostream

    B = apply<std::negate>(A);          //? B(i,j,k) = -A(i,j,k)
    B = apply(A, std::negate());        //? B(i,j,k) = -A(i,j,k)
    B = apply<std::plus>(A1, A2);       //? B(i,j,k) = A1(i,j,k) + A2(i,j,k)
    B = apply(A1, A2, std::plus());     //? B(i,j,k) = A1(i,j,k) + A2(i,j,k)

    // matrix and vector operations:

    typedef array<float[20][20]> Matrix;
    typedef array<float[20]> Vector;

    Matrix N, M, M1, M2;
    Vector U, V, V1, V2;

    c = V1 * V2;            //  returns the inner product of V1 and V2
    U = M * V;              //  matrix-vector product (V is treated as a column vector)
    U = V * M;              //  vector-matrix product (V is treated as a row vector)
    N = M1 * M2;            //  matrix-matrix product (V is treated as a row vector)
    N = M1 * M2;            //  matrix-matrix product (V is treated as a row vector)
    c = det(M);             //  returns the determinant of M
    N = inverse(M);         //  returns the inverse of M
    M = scale(V);           //  returns a square matrix with V on the main diagonal

    // 2D specific geometric operations:

    typedef array<float[2][2]> Matrix2;
    typedef array<float[2]> Vector2;

    Matrix2 M2;
    Vector2 u2, v2, w2;

    c = u2 % v2;            //  returns the cross product of u2 and v2
    M2 = rotation(v2, c);   //  returns a rotation matrix that rotates c radians, v2 is ignored
    M2 = rotation_n(v2, c); //  same as rotation(v2, c)

    // 3D specific geometric operations:

    typedef array<float[3][3]> Matrix3;
    typedef array<float[3]> Vector3;

    Matrix3 M3;
    Vector3 u3, v3, w3;

    w3 = u3 % v3;           //  returns the cross product of u3 and v3
    M3 = rotation(v3, c);   //  returns a rotation matrix that rotates c radians around v3
    M3 = rotation_n(v3, c); //  slightly faster than rotation(v3, c) but v3 must be a unit vector.

Note that the above operations can be used on any type that support the underlying operators. For example, to use the compare() function, the operator< should be defined on the elements of the array.

Remarks:
  • Note that all of the operations that involve two arrays, require the two array to have matching signatures and traits. For example, you cannot add an array of type array<float[10]> with and array of type array<float[1]> even if the size of the second array is actually 10. To use two arrays with the same size but different signatures or different traits type, you first need to cast one of them using the lite::array_cast(). For matrix and vector operations, only the relevant part of the signature is required to match. For example you can multiply an array<float[1][10]> by an array<float[10]> but not by an array<float[1]> event if the size of the second array is actually 10. You would first need to cast the second array to array<float[10]> using lite::array_cast().
  • All the operations the are marked with a question mark in their comment use lazy evaluation (see Lazy Evaluation). Note that due to lazy evaluation, sometimes it is necessary to make a temporary copy of an array to ensure proper result. To do that you can use the lite::copy(). For example:
                array<float[5][5]> a;
    
                a = a[transpose()];         // does not work correctly due to lazy evaluation
                a = copy(a[transpose()]);   // works fine. makes a temporary copy of a[transpose()]
    
  • Note that when copying arrays using operator=(), the left array will be resized (if possible) before the actual copy.

Array Casting

For more information on array casting, see lite::array_cast().

Array I/O

For more information on reading/writing arrays to io streams, see lite::operator>>() and lite::operator<<().

Constructing Reference Arrays from C Arrays, Iterators or Pointers

You can create a reference array from a C array, an appropriate random access iterator or a pointer using lite::from().

Ordering Array Objects

If you ever need to define an ordering on array objects (e.g. to use lite::array as the key to a std::map) you can use lite::array_comparator.


Function Documentation

template<typename dst_array_type_ , typename src_signature_ , typename src_traits_type_ , typename src_rep_ >
const array<...> lite::array_cast ( const array< src_signature_, src_traits_type_, src_rep_ > &  ar  )  [inline]

Casts the array ar to a compatible array type that has the same signature and traits type as dst_array_type_.

The result of the cast is always a reference array that points to the original array. No copying is ever made. This function may throw a lite::size_mismatch_error exception if the actual size of the array ar does not match the signature type of dst_array_type_.

Example:
        array<float[10]> a;                     // 1D array of constant size 10
        array<float[1]> b(10);                  // 1D array of non-constant size 10

        a = b;                                  // error: array signatures do not match.
        a = array_cast<array<float[10]> >(b);   // works fine.
        array_cast<array<float[1]> >(a) = b;    // produces the same result as the previous line.
Exceptions:
lite::size_mismatch_error 
template<typename iterator_type_ , typename type0_... , typename typeN_ >
const array<...> lite::from ( iterator_type_  it,
const pack< type0_..., typeN_ > &  size 
) [inline]

Constructs a reference array from a pointer (or any other appropriate random access iterator) with the specified size.

Example:
    array<float[3][3]> a, c;
    std::vector<float> v(9);

    std::cin >> from(v.begin(), a.size());  // read v
    std::cin >> a;                          // read a
    c = a*from(v.begin(), a.size());        // matrix multiplication
template<typename iterator_type_ >
const array<...> lite::from ( iterator_type_  it,
int  n0...,
int  nN 
) [inline]

Constructs a reference array from a pointer (or any other appropriate random access iterator) with the specified dimension sizes.

Example:
    array<float[3][3]> a, c;
    std::vector<float> v(9);

    std::cin >> from(v.begin(), 3, 3);  // read v
    std::cin >> a;                      // read a
    c = a*from(v.begin(), 3, 3);        // matrix multiplication
template<typename value_type_ , int n0_..., int nN_>
const array<...> lite::from ( value_type_(&)  a...[n0_][nN_]  )  [inline]

constructs a reference array to a C array.

Example:
    array<float[3][3]> a, c;
    float b[3][3];

    std::cin >> from(b) >> a;   // read a and b
    c = a*from(b);              // matrix multiplication
template<typename char_type_ , typename char_traits_type_ , typename signature_ , typename traits_type_ , typename rep_ >
std::basic_ostream<char_type_, char_traits_type_>& lite::operator<< ( std::basic_ostream< char_type_, char_traits_type_ > &  os,
const array< signature_, traits_type_, rep_ > &  ar 
) [inline]

Prints the array ar to the output stream os.

If the field width value for os is set, it will be used to set the field width for each of the elements to be printed. Also if the boolalpha flags is set then the values of each dimension will be surrounded in a matching pair of square brackets.

Example:
        array<int[3][3]> m = 0;

        m[diagonal()] = 1;
        std::cout << std::boolalpha  << std::setw(2) << m << std::endl;

The output would be:

        [ 
          [ 1  0  0]
          [ 0  1  0]
          [ 0  0  1]
        ]
    
template<typename char_type_ , typename char_traits_type_ , typename signature_ , typename traits_type_ , typename rep_ >
std::basic_istream<char_type_, char_traits_type_>& lite::operator>> ( std::basic_istream< char_type_, char_traits_type_ > &  is,
array< signature_, traits_type_, rep_ > &  ar 
) [inline]

Scans (reads) the array ar from the input stream is.

The values of each dimension could be surrounded in a matching pair of square brackets.

Remarks:
All the consecutive line breaks and white space characters are treated as a single space.
Example:
        array<int[3][3]> m;
        std::cin >> m;
        std::cout << m << std::endl;

If the input is:

        [ 
          [ 1  0  0]
          [ 0  1  0]
          [ 0  0  1]
        ]
    

The output would be:

        1 0 0
        0 1 0
        0 0 1
    
template<typename char_type_ , typename char_traits_type_ , typename signature_ , typename traits_type_ , typename rep_ >
std::basic_istream<char_type_, char_traits_type_>& lite::operator>> ( std::basic_istream< char_type_, char_traits_type_ > &  is,
const array< signature_, traits_type_, rep_ > &  ar 
) [inline]

Scans (reads) the array ar from the input stream is.

The values of each dimension could be surrounded in a matching pair of square brackets.

Remarks:
  • All the consecutive line breaks and white space characters are treated as a single space.
  • ar is declared const to allow reading into reference arrays.
Example:
        array<int[3][3]> m=0;
        std::cin >> m[diagonal()];
        std::cout << m << std::endl;

If the input is:

        [ 1 2 3 ]
    

The output would be:

        1 0 0
        0 2 0
        0 0 3
    
template<typename size_type_ >
int lite::volume ( const size_type_ &  sz  )  [inline]

Returns the total volume of an array of the size sz.

Example:
        array<float[1][1][5]> a(10, 10, 5);

        std::cout << volume(a.size()) << std::endl;

The output would be:

        500
    
 All Classes Namespaces Files Functions Variables Typedefs Defines

Generated on Fri Nov 6 02:03:20 2009 for Lite by  doxygen 1.6.0