What is the complexity of boost::multi_array reshape() function? I expect it to be O(1) but I can't find this info in the documentation. The documentation for this library is actually pretty scarce.
The reason I'm asking is that I would like to iterate through a multi_array object using a single loop (I don't care about array indices). It seems like the library doesn't provide a way of iterating through an array using a single iterator. So, as a workaround, I'd like to reshape the array along a single dimension first (with other dimensions set to 1). Then I can iterate through the array using a single loop. However, I'm not sure how efficient the reshape() operation is.
Hence my second question: Is there an easy way to iterate through all the elements of a multi-array object using a single loop?
Below is the implementation of reshape function in multi_array_ref.hpp file.
template <typename SizeList>
void reshape(const SizeList& extents) {
boost::function_requires<
CollectionConcept<SizeList> >();
BOOST_ASSERT(num_elements_ ==
std::accumulate(extents.begin(),extents.end(),
size_type(1),std::multiplies<size_type>()));
std::copy(extents.begin(),extents.end(),extent_list_.begin());
this->compute_strides(stride_list_,extent_list_,storage_);
origin_offset_ =
this->calculate_origin_offset(stride_list_,extent_list_,
storage_,index_base_list_);
}
It looks like the function just re-indexes the elements in extents object associated with array size. The function is linear in the number of elements in extends. But I think it's complexity is constant in the total number of elements in the array.
Related
I need to create a multidimensional matrix of randomly distributed numbers using a Gaussian distribution, and am trying to keep the program as optimized as possible. Currently I am using Boost matrices, but I can't seem to find anything that accomplishes this without manually looping. Ideally, I would like something similar to Python's numpy.random.randn() function, but this must be done in C++. Is there another way to accomplish this that is faster than manually looping?
You're going to have to loop anyway, but you can eliminate the array lookup inside your loop. True N-dimensional array indexing is going to be expensive, so you best option is any library (or written yourself) which also provides you with an underlying linear data store.
You can then loop over the entire n-dimensional array as if it was linear, avoiding many multiplications of the indexes by the dimensions.
Another optimization is to do away with the index altogether, and take a pointer to the first element, then iterate the pointer itself, this does away with a whole variable in the CPU which can give the compiler more space for other things. e.g. if you had 1000 elements in a vector:
vector<int> data;
data.resize(1000);
int *intPtr = &data[0];
int *endPtr = &data[0] + 1000;
while(intPtr != endPtr)
{
(*intPtr) == rand_function();
++intPtr;
}
Here, two tricks have happened. Pre-calculate the end condition outside the loop itself (this avoids a lookup of a function such as vector::size() 1000 times), and working with pointers to the data in memory rather than indexes. An index gets internally converted to a pointer every time it's used to access the array. By storing the "current pointer" and adding 1 to that each time, then the cost of calculating the pointers from indexes 1000 times is eliminated.
This can be faster but it depends on the implementation. Compilers can do some of the same hand-optimizations, but not all of them. The rand_function should also be inline to avoid the function call overhead.
A warning however: if you use std::vector with the pointer trick then it's not thread safe, if another thread changed the vector's length during the loop then the vector can get reallocated to a different place in memory. Don't do pointer tricks unless you'd be perfectly comfortable writing your own vector, array, table classes as needed.
So I want to create an array of nine elements, but I want the indices to be specified by me, that is, instead of accesing elements of my array,
std::array<bool,9> myarray
using myarray[0], myarray[1], myarray[2]... I want to access them, for example, as
myarray[21], myarray[34], myarray[100], myarray[9], myarray[56]...
But still conserving the properties of standard library array and storing only 9 elements.
More specifically, I need an easy access to the elements of a boolean matrix.
That is, suppose I have the matrix:
Array<array<bool,100>,100> mymatrix;
And that it is going to be used for checking certain positions (Say position x,y) easily simply using mymatrix[x][y]. I also know that some of the elements are never going to be checked, so they are not really needed. In order to save the most memory possible, the idea is to get rid of those not needed elements, but still conserving the structure to check my elements.
Such an array is best represented with one of the associative containers provided by the Standard C++ Library - i.e. either a std::map<int,bool> or an std::unordered_map<int,bool>. These containers provide an idiomatic way of doing this in C++.
One added benefit of using an associative container is the ability to iterate the values along with their external "indexes".
If you insist on using an array to store the values, you would have to make your own class that builds a "mapping" between external and internal indexes. This would either take a significant amount of memory for an O(1) access time, use CPU cycles for binary search plus an index-to-index map, use linear search, or hard-code the external indexes.
On the first glance, what you want is an std::map<int, bool>, which allows you to have your own indices. But, map is not fixed in size.
In order to get both fixed size and custom indices, you may combine a map and an array with a custom add and access functions:
map<int, bool> indices; // fill it with custom indices mapped onto the array
array<bool, n> data;
bool get(int index) {
return data[map(index)]
}
I would like to know what the most suitable data structure is for the following problem in C++
I am wanting to store 100 floats ordered by recency. So when I add (push) a new item the other elements are moved up one position. Every time an event is triggered I receive a value and then add it to my data structure.
When the number of elements reaches 100, I would like to remove (pop) the item at the end (the oldest).
I want to able to iterate over all the elements and perform some mathematical operations on them.
I have looked at all the standard C++ containers but none of them fulfill all my needs. What's the easiest way to achieve this with standard C++ code?
You want a circular buffer. You can use Boost's implementation or make your own by allocating an array, and keeping track of the beginning and end of the used range. This boils down to doing indexing modulo 100.
Without creating your own or using a library, std::vector is the most efficient standard data structure for this. Once it has reached its maximum size, there will be no more dynamic memory allocations. The cost of moving up 100 floats is trivial compared to the cost of dynamic memory allocations. (This is why std::list is a slow data structure for this). There is no push_front function for vector. Instead you have to use v.insert(v.begin(), f)
Of course this assumes what you are doing is performance-critical, which it probably isn't. In that case I would use std::deque for more convenient usage.
Just saw that you need to iterator over them. Use a list.
Your basic function would look something like this
void addToList(int value){
list100.push_back(value);
if(list100.size() > 100){
list100.pop_front();
}
}
Iterating over them is easy as well:
for(int val : list100){
sum += val;
}
// Average, or whatever you need to do
Obviously, if you're using something besides int, you'll need to change that. Although this adds a little bit more functionality than you need, it's very efficient since it's a doubly linked list.
http://www.cplusplus.com/reference/list/list/
You can use either std::array, std::dequeue, std::list or std::priority_queue
A MAP (std::map) should be able to solve your requirement. Use Key as the object and value as the current push number nPusheCount which gets incremented whenever you add an element to map.
when adding a new element to map, if you have less than 100 elements, just add the number to the MAP as key and nPushCount as the value.
If you have 100 elements already, check if the number exists in map already and do following:
If the number already exists in map, then add the number as key and nPushCount as value;
If doesnt, delete the number with lowest nPushCount as value and then add the desired number with updated nPushCount.
Let's say I have a 2D array and I want to pass it's i th column to a sort function that takes in a 1D array and sorts it.
Can it be done without copying the column to another array in C/C++ language. I am concerned about reducing time and space used. (Ofcourse the complexity remains same)
I suppose that by sort you mean std::sort from STL, which takes random access iterators. So all you need to do is provide column iterators.
You can either implement one by yourself (example), use some iterator library (ie. Boost.Iterator) or use some matrix implementation which provides row/column iterators.
If you can write your own sort function, it's rather easy; you just make the interface like this:
void Sort (T a [], size_t n, size_t stride);
The key is in the stride parameter, which is the distance between the elements of this "virtual" array. For example, if you have a float x [10][20]; and you want to send its column #2, you'd do this: (some casts omitted for clarity)
Sort (x[0] + 2, 10, 20); // Usually, stride is the width of the 2D array
Inside the Sort function, you access the ith element of an array that has a stride like this:
a[i * stride] = 42;
That's it.
You can use the same principle to write your own MatrixColumnView class that wraps up this concept and can be passed into templated functions that take arrays.
If you want to work with STL or STL-like libraries, you can simply write your own MatrixColumnIterator iterator class that essentially uses an stride internally and gives iteration over a column of a 2D array.
As far as i know, the multidimensional array storage in C/C++ is actually a 1D-arrary,
which you can refer a very good explanation in this post : How to get column of a multidimensional array in C/C++?
Therefore I do not think there's any default / easy method to extract a particular column of a 2D array and pass it to another function.
I'm trying to make a 3 dimensional array of booleans that tells me if I previously visited a location in 3d space for a simple navigation algorithm. The array could be quite large (something along the lines of 1,000,000 x 1,000,000 x 1,000,000 or maybe larger), so I'm wondering if it would be faster to declare an array of that size and set each boolean value to false, or to make a map with a key of coordinate (x, y, z) and a value of type bool.
From what I figure, the array would take O(1) to find or modify a coordinate, and the map would take O(log n) to find or insert a value. Obviously, for accessing values, the array is faster. However, does this offset the time it takes to declare such an array?
Thanks
Even at 1 bit per bool, your array will take over 2**39 bytes. I'd suggest a set if there aren't too many elements that will be true.
You can use a class to hide the implementation details, and use a 1D set.
Have you tried calculating how much memory would be needed for an array like this? A lot!
Use std::map if ordering of the points is important, or std::unordeded_map if not. Also the unordered map gives you a constant time insertion and lookup.
I guess that some kind of search tree is probably what you're looking for (k-d tree for example).
You're going to make an array that is one exabyte, assuming that you use 8 bits per point? Wow, you have a lot of RAM!
I think you should re-think your approach.