Is there a container that I can add and remove from both ends - c++11

Is there a container in C++ I could use to add elements in both ends, not just back or just front, but would like to add in either end. And similarly remove elements from any end, not from just one. Maybe in STLs or Boost?

You can portably add an element x to the front of a sequence container (vector/deque/list) via v.insert(v.begin(), x). However, for vector this is an O(n) operation (this is why vector does not have a convenient push_front operation) and it relocates all the existing elements. If you don't want existing elements to be relocated, deque or list may be a better fit.

Related

Mutable data types that use stack allocation

Based on my earlier question, I understand the benefit of using stack allocation. Suppose I have an array of arrays. For example, A is a list of matrices and each element A[i] is a 1x3 matrix. The length of A and the dimension of A[i] are known at run time (given by the user). Each A[i] is a matrix of Float64 and this is also known at run time. However, through out the program, I will be modifying the values of A[i] element by element. What data structure can also allow me to use stack allocation? I tried StaticArrays but it doesn't allow me to modify a static array.
StaticArrays defines MArray (MVector, MMatrix) types that are fixed-size and mutable. If you use these there's a higher chance of the compiler determining that they can be stack-allocated, but it's not guaranteed. Moreover, since the pattern you're using is that you're passing the mutable state vector into a function which presumably modifies it, it's not going to be valid or helpful to stack allocate that anyway. If you're going to allocate state once and modify it throughout the program, it doesn't really matter if it is heap or stack allocated—stack allocation is only a big win for objects that are allocated, used locally and then don't escape the local scope, so they can be “freed” simply by popping the stack.
From the code snippet you showed in the linked question, the state vector is allocated in the outer function, test_for_loop, which shouldn't be a big deal since it's done once at the beginning of execution. Using a variably sized state vector to index into an array with a splat (...) might be an issue, however, and that's done in test_function. Using something with fixed size like MVector might be better for that. It might, however, be better still, to use a state tuple and return a new rather than mutated state tuple at the end. The compiler is very good at turning that kind of thing into very efficient code because of immutability.
Note that by convention test_function should be called test_function! since it modifies its M argument and even more so if it modifies the state vector.
I would also note that this isn't a great question/answer pair since it's not standalone at all and really just a continuation of your other question. StackOverflow isn't very good for this kind of iterative question/discussion interaction, I'm afraid.

Are OpenMesh iterators changed when adding elements?

Do existing OpenMesh iterators change, when I add elements?
Example code:
auto vh1 = mesh.vertex_handle(0);
auto vh2 = mesh.vertex_handle(1);
auto vh3 = mesh.vertex_handle(2);
for(auto fh: mesh.faces()) {
mesh.add_face(vh1, vh2, vh3);
}
I did not find something about this in the documentation.
Example seem to work, but I want to know if it's undefined behavior or if OpenMesh promises to make sure that the iterator does not change during the loop.
OpenMesh does not change the iterators when you add elements, but I don't think OpenMesh gives you a promise on that.
OpenMesh iterators are basically just ints. (They hold a SmartHandle and some information about which elements should be skipped. A SmartHandle holds a Handle and a reference to the mesh. A Handle is just a strongly typed integer.)
Incrementing the iterator will just increment the integer (until an element is reached which should not be skipped). Since you always access elements via the mesh and a handle the relocation of the actual memory that stores the elements is not a problem.
Note that depending on how you code your loop the new element may or may not be iterated over.
for (auto it = mesh_.vertices_begin(); it != mesh_.vertices_end(); ++it)
{
mesh_.add_vertex(point);
}
The loop above will include the newly added vertex as mesh_.vertices_end() is reevaluated for each comparison and will thus include the newly added elements. This leads to an infinite loop in that case.
auto end = mesh_.vertices.end();
for (auto it = mesh_.vertices_begin(); it != end; ++it)
{
mesh_.add_vertex(point);
}
In this case, the newly added elements will not be contained in the loop. That is because end is evaluated only once in the beginning and basically just holds the number of vertices the mesh had at that point.
for (auto vh : mesh_.vertices())
{
mesh_.add_vertex(point);
}
This will behave as the second version as here, too, vertices_end() is only evaluated once in the beginning.
Deletion
Since it was brought up in the other answer I want to quickly talk about deletion.
Deleting an element will only mark it as deleted. Thus, deleting elements while iterating over the elements is fine.
When you delete elements which have not been visited yet, they may or may not be iterated over later. If you use skipping iterators the deleted elements will be skipped, otherwise they won't be skipped.
For OpenMesh 7.0 or newer for (auto fh : mesh_.faces()) {...} will not include deleted elements.
Instead for (auto fh : mesh_.all_faces()) {...} will include deleted elements.
Garbage Collection
You should probably not call garbage collection inside your loop. If you have deleted elements, garbage collection will cause two problems. First, it reduces the size of the container storing the elements. Thus, versions of the loop that evaluate the end iterator once will likely run too far and crash.
If you use the other version of the loop or manage to create more new elements than you remove, you still have the problem that garbage collection will move elements from the back into the spots of the elements that were marked as deleted. Thus, you will miss those elements if they are moved to spots that you already passed.
One can search typedef std::vector< in openmesh,then you can find it. But
add_face won't reallocation this iterators, because the new vertex handle or face handle will push_back to the end of this vector. Meanwhile , in order to have a high-efficient search speed, Openmesh builds at least three layers of iterators, and the vector we discuss is only the bottom of them. The middle or top iterators, I use them by assemble functions,so I'm not sure it will be reallocated/invalidated or not, and you can find them in PolyConnectivity.hh and TriConnectivity.hh.

Can someone explain how std::greater is used to implement priority_queue

std::priority_queue<int, vector<int>, std::greater<int> > pq;
I cannot understand the work of std::greater in the priority queue.
I am replacing minheap by the priority queue.
this code is taken from
geeksForGeeks implementation of Prims algorithm using STL
The std::priority_queue type is what’s called a container adapter. It works by starting with a type you can use to represent a sequence, then uses that type to build the priority queue (specifically, as a binary heap). By default, it uses a vector.
In order to do this, the priority queue type has to know how to compare elements against one another in a way that determines which elements are “smaller” than other elements. By default, it uses the less-than operator.
If you make a standard std::priority_queue<int>, you get back a priority queue that
uses a std::vector for storage, and
uses the less-than operator to compare elements.
In many cases, this is what you want. If you insert elements into a priority queue created this way, you’ll read them back out from greatest to least.
In some cases, though, this isn’t the behavior you want. In Prim’s algorithm and Dijkstra’s algorithm, for example, you want the values to come back in ascending order rather than descending order. To do this, you need to, in effect, reverse the order of comparisons by using the greater-than operator instead of the less-than operator.
To do this, you need to tell the priority queue to use a different comparison method. Unfortunately, the priority queue type is designed so that if you want to do that, you also need to specify which underlying container you want to use. I think this is a mistake in the design - it would be really nice to just be able to specify the comparator rather than the comparator and the container - but c’est la vie. The syntax for this is
std::priority_queue<int, // store integers...
std::vector<int>, // ... in a vector ...
std::greater<int>> // ... comparing using >

Constant-time list concatenation in OCaml

Is it possible to implement constant-time list concatenation in OCaml?
I imagine an approach where we deal directly with memory and concatenate lists by pointing the end of the first list to the beginning of the second list. Essentially, we're creating some type of linked-list like object.
With the normal list type, no, you can't. The algorithm you gave is exactly the one implemented ... but you still have to actually find the end of the first list...
There are various methods to implement constant time concatenation (see Okazaki for fancy details). I will just give you names of ocaml libraries that implement it: BatSeq, BatLazyList (both in batteries), sequence, gen, Core.Sequence.
Pretty sure there is a diff-list implementation somewhere too.
Lists are already (singly) linked lists. But list nodes are immutable. So you change any node's pointer to point to anything different. In order to concatenate two lists you must therefore copy all the nodes in the first list.

vector --> concurrent_vector migration + OpenGL restriction

I need to speed-up some calculation and result of calculation then used to draw OpenGL model.
Major speed-up archived when I changed std::vector to Concurrency::concurrent_vector and used parallel_for instead of just for loops.
This vector (or concurrent_vector) calculated in for (or parallel_for) loop and contains vertices for OpenGL to visualize.
It is fine using std::vector because OpenGL rendering procedure relies on the fact that std::vector keeps it's items in sequence which is not a case with concurrent_vector. Code runs something like this:
glVertexPointer(3, GL_FLOAT, 0, &vectorWithVerticesData[0]);
To generate concurrent_vector and copy it to std::vector is too expensive since there are lot of items.
So, the question is: I'd like to use OpenGL arrays, but also like to use concurrent_vector which is incompatible with OpenGL output.
Any suggestions?
You're trying to use a data structure that doesn't store its elements contiguously in an API that requires contiguous storage. Well, one of those has to give, and it's not going to be OpenGL. GL isn't going to walk concurrent_vector's data structure (not if you like performance).
So your option is to not use non-sequential objects.
I can only guess at what you're doing (since you didn't provide example code for the generator), so that limits what I can advise. If your parallel_for iterates for a fixed number of times (by "fixed", I mean a value that is known immediately before parallel_for executes. It doesn't change based on how many times you've iterated), then you can just use a regular vector.
Simply size the vector with vector::size. This will value-initialize the elements, which means that every element exists. You can now perform your parallel_for loop, but instead of using push_back or whatever, you simply copy the element directly into its location in the output. I think parallel_for can iterate over the actual vector iterators, but I'm not positive. Either way, it doesn't matter; you won't get any race conditions unless you try to set the same element from different threads.

Resources