How can I use a std::valarray
to store/manipulate a 2D array?
I'd like to see an example of a 2D array with elements accessed by row/column indices. Something like this pseudo code:
matrix(i,j) = 42;
An example of how to initialize such an array would also be nice.
I'm already aware of Boost.MultiArray, Boost.uBlas, and Blitz++.
Feel free to answer why I shouldn't use valarray for my use case. However, I want the memory for the multidimensional array to be a contiguous (columns x rows) block. No Java-style nested arrays.
To declare a 2D array, specify the type of elements that will be stored in the array, then ( [][] ) to show that it is a 2D array of that type, then at least one space, and then a name for the array. Note that the declarations below just name the variable and say what type of array it will reference.
As a result, the element locations within a row are contiguous, but elements are not contiguous across rows of the 2D array.
In C++ Two Dimensional array in C++ is an array that consists of more than one rows and more than one column. In 2-D array each element is refer by two indexes. Elements stored in these Arrays in the form of matrices. The first index shows a row of the matrix and the second index shows the column of the matrix.
Off the top of my head:
template <class element_type>
class matrix
{
public:
matrix(size_t width, size_t height): m_stride(width), m_height(height), m_storage(width*height) { }
element_type &operator()(size_t row, size_t column)
{
// column major
return m_storage[std::slice(column, m_height, m_stride)][row];
// row major
return m_storage[std::slice(row, m_stride, m_height)][column];
}
private:
std::valarray<element_type> m_storage;
size_t m_stride;
size_t m_height;
};
std::valarray
provides many interesting ways to access elements, via slices, masks, multidimentional slices, or an indirection table. See std::slice_array
, std::gslice_array
, std::mask_array
, and std::indirect_array
for more details.
#include <iostream>
#include <valarray>
using namespace std;
typedef valarray<valarray<int> > va2d;
int main()
{
int data[][3] = { {1, 2, 3}, {4, 5, 6} };
va2d mat(valarray<int>(3), 2);
for (int i = 0; i < 2; ++i)
{
for (int j = 0; j < 3; ++j)
mat[ i ][ j ] = data[ i ][ j ];
}
for (int i = 0; i < 2; ++i)
for (int j = 0; j < 3; ++j)
cout << mat[ i ][ j ] << endl;
}
More on valarray
:
vector
like container with special member functions for slicing and dicing.vector
access may be fastervalarray<T>
: E.g:3 In addition, many member and related functions of valarray can be successfully instantiated and will exhibit well-defined behavior if and only if T satisfies additional requirements specified for each such member or related function.
4 [ Example: It is valid to instantiate valarray, but operator>() will not be successfully instantiated for valarray operands, since complex does not have any ordering operators. —end example ]
Edit#2: The standard gurantees that vector
, like arrays, always use contiguous memory. Also, we have:
26.5.2 Class template valarray
1 The class template valarray 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 computed indices, together with the powerful subsetting capabilities provided by the generalized subscript operators.
and further:
26.5.2.3 valarray element access
4 Likewise, the expression &a[i] != &b[j] evaluates as true for any two 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With