Reputation: 357
My program produces the following output at some time
and at some time later
and I would like to determine the largest 4 values of BOTH crests. I've managed to find the largest 4 values of the largest crest (see the code below), which is relatively simple because I basically need to find the absolute largest values. But I don't know how to find the largest 4 values of the smaller crest, and I was wondering if anybody could help me with this?
Here is the C++ code I used to find the largest 4 values of the largest crest:
for(i=0;i<4;i=i+1)
{
queue_matrix[i] = 0.0;
}
for(i=0;i<SPACE;i=i+1)
{
if(U_field_matrix[i][t1] > queue_matrix[0])
{
queue_matrix[0] = U_field_matrix[i][t1];
}
}
for(i=0;i<SPACE;i=i+1)
{
if((U_field_matrix[i][t1] > queue_matrix[1]) && (U_field_matrix[i][t1] < queue_matrix[0]))
{
queue_matrix[1] = U_field_matrix[i][t1];
}
}
for(i=0;i<SPACE;i=i+1)
{
if((U_field_matrix[i][t1] > queue_matrix[2]) && (U_field_matrix[i][t1] < queue_matrix[1]))
{
queue_matrix[2] = U_field_matrix[i][t1];
}
}
for(i=0;i<SPACE;i=i+1)
{
if((U_field_matrix[i][t1] > queue_matrix[3]) && (U_field_matrix[i][t1] < queue_matrix[2]))
{
queue_matrix[3] = U_field_matrix[i][t1];
}
}
Upvotes: 1
Views: 148
Reputation: 5557
I was hesitant to post this, because you seem to have a really simple usecase, which your solution probably covers sufficiently well, but there are really nicer ways to look for top-k values. In general you would probably do yourself a favor, if you split this up into a function that looks for maxima (according to what eOk said, if this works for you), a function that looks for top-k and a program which runs over your data and calls the top-k function on the surrounding values whenever it finds a maximum.
I don't have a solution like that lying around right now, and without knowing about the types of your variables, it is impossible to write one for you, but top-k for example usually looks like this for me:
#include <algorithm>
#include <vector>
template <class in_iterator, class out_iterator,
class value_type = typename std::iterator_traits<in_iterator>::value_type,
class compare = std::greater<value_type>>
void findTopK(in_iterator start, in_iterator end, out_iterator out,
size_t k)
{
std::vector<value_type> heap;
heap.reserve(k + 1);
for (;start != end; ++start)
{
heap.push_back(*start); //min-oriented heap, order implied by compare
std::push_heap(std::begin(heap), std::end(heap), compare());
if (heap.size() > k)
{
std::pop_heap(std::begin(heap), std::end(heap), compare());
heap.pop_back();
}
}
while (!heap.empty())
{
std::pop_heap(std::begin(heap), std::end(heap), compare());
*out++ = heap.back();
heap.pop_back();
}
}
This method uses a heap to keep track of the k largest elements. Calling it on a regular array works as well as on any container and looks like this:
int main()
{
int array[] = {1,3,4,5,6,2,62,3,32};
std::vector<int> results;
findTopK(std::begin(array), std::end(array), back_inserter(results), 5);
}
As a result you don't have to write the k counterx loops every time, and your code becomes more readable. The difficult part for you may be providing a custom compare-function for your elements, but there are enough posts on this on so:
Upvotes: 1
Reputation: 357
Inspired by @e0k's comment (thank you!), the following code will determine the largest 4 values of both crests.
for(i=0;i<SPACE;i=i+1)
{
if((U_field_matrix[i][t1] > 0.1) && (U_field_matrix[i+1][t1]-U_field_matrix[i][t1] < 0.0))
{
counter1 = i;
break;
}
}
for(i=0;i<4;i=i+1)
{
queue_matrix1[i] = 0.0;
}
for(i=(counter1-3);i<(counter1+4);i=i+1)
{
if(U_field_matrix[i][t1] > queue_matrix1[0])
{
queue_matrix1[0] = U_field_matrix[i][t1];
}
}
for(i=(counter1-3);i<(counter1+4);i=i+1)
{
if((U_field_matrix[i][t1] > queue_matrix1[1]) && (U_field_matrix[i][t1] < queue_matrix1[0]))
{
queue_matrix1[1] = U_field_matrix[i][t1];
}
}
for(i=(counter1-3);i<(counter1+4);i=i+1)
{
if((U_field_matrix[i][t1] > queue_matrix1[2]) && (U_field_matrix[i][t1] < queue_matrix1[1]))
{
queue_matrix1[2] = U_field_matrix[i][t1];
}
}
for(i=(counter1-3);i<(counter1+4);i=i+1)
{
if((U_field_matrix[i][t1] > queue_matrix1[3]) && (U_field_matrix[i][t1] < queue_matrix1[2]))
{
queue_matrix1[3] = U_field_matrix[i][t1];
}
}
for(i=SPACE;i>-1;i=i-1)
{
if((U_field_matrix[i][t1] > 0.1) && (U_field_matrix[i-1][t1]-U_field_matrix[i][t1] < 0.0))
{
counter2 = i;
break;
}
}
for(i=0;i<4;i=i+1)
{
queue_matrix2[i] = 0.0;
}
for(i=(counter2-3);i<(counter2+4);i=i+1)
{
if(U_field_matrix[i][t1] > queue_matrix2[0])
{
queue_matrix2[0] = U_field_matrix[i][t1];
}
}
for(i=(counter2-3);i<(counter2+4);i=i+1)
{
if((U_field_matrix[i][t1] > queue_matrix2[1]) && (U_field_matrix[i][t1] < queue_matrix2[0]))
{
queue_matrix2[1] = U_field_matrix[i][t1];
}
}
for(i=(counter2-3);i<(counter2+4);i=i+1)
{
if((U_field_matrix[i][t1] > queue_matrix2[2]) && (U_field_matrix[i][t1] < queue_matrix2[1]))
{
queue_matrix2[2] = U_field_matrix[i][t1];
}
}
for(i=(counter2-3);i<(counter2+4);i=i+1)
{
if((U_field_matrix[i][t1] > queue_matrix2[3]) && (U_field_matrix[i][t1] < queue_matrix2[2]))
{
queue_matrix2[3] = U_field_matrix[i][t1];
}
}
Upvotes: 0
Reputation: 53
At every graph you should find crests looking for values for x axis = i
greater than value for x axis = i + 1
. You will get the two crests, larger value is for larger crest. Then, compare each value with the set of values found previously
Upvotes: 0