using count() question

Pages: 12
Using the count_intersection I'm getting an error for each instance.

error: 'count_intersection' was not declared in this scope.

Here is the code as written
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
    Clock clk;   //  CALLS the clock to start
    
    size_t layer_rep_start {1};
    int a {0};
    int line_number {1};
    while ( line_number <= timings_reporting ) {
        
        int two_counter {0};
        for (size_t b = layer_rep_start; b < d5.size(); ++b, ++two_counter)
                if (count_intersection(d5[a].begin(), d5[a].end(), d5[b].begin(), d5[b].end()) >= 2)
                    break;
        
        int three_counter {0};
        for (size_t b = layer_rep_start; b < d5.size(); ++b, ++three_counter)
                if (count_intersection(d5[a].begin(), d5[a].end(), d5[b].begin(), d5[b].end()) >= 3)
                    break;
        
        int four_counter {0};
        for (size_t b = layer_rep_start; b < d5.size(); ++b, ++four_counter)
                if (count_intersection(d5[a].begin(), d5[a].end(), d5[b].begin(), d5[b].end()) >= 4)
                    break;
                
        std::cout << line_number << "\t" << two_counter << "\t" << three_counter << "\t" << four_counter << "\n";
        
        ++layer_rep_start;
        ++a;
        ++line_number;
    }
    
    std::cout << "\n";
    clk.end_us(); // print time in microseconds (or clk.end_ms() for milliseconds)
    std::cout << "\n";
    
    return 0;    
I'm thinking that "count_intersection" should be "set_intersection". I'll give that a try.

EDIT:: set_intersection gave 3 errors also. The previous method that dutch provided (the one with creating an array) worked and output was correct. I did run some timings on the array method, and I'm happy with the results. I guess we can call this thread SOLVED!

Here are the timing results:
Ran 100 lines of results, cout was "line No." "two_counter" "three_counter" and lastly "four_counter"
Ran the code for 100 lines "5 times" and here are the times in microseconds:
253123
252384
241118
243622
241256

They were all run in Debug mode in my IDE. Guess I should have run in release mode, but, oh well. I'm happy that everything works.
Last edited on
The code of count_intersection exists only in my comment. You have to copy it from there.
Yeah, keskiverto wrote the count_intersection code as a modification (optimization for your purpose) of the set_intersection code, so you need to copy that code as a function in your program.

It looks like your code above might be rewritten something like this (untested):

1
2
3
4
5
6
7
8
9
    for (int a = 0; a < timings_reporting; ++a) {
        int cnt[3]{}, i = 2;
        for (size_t b = a + 1; b < d5.size(); ++b, ++cnt[i])
            if (count_intersection(d5[a].begin(), d5[a].end(), d5[b].begin(), d5[b].end()) >= i + 2)
                --i;
        cnt[1] += cnt[2]; // >= 3 includes >= 4
        cnt[0] += cnt[1]; // >= 2 includes >= 3
        std::cout << a + 1 << '\t' << cnt[0] << '\t' << cnt[1] << '\t' << cnt[2] << '\n';
    }

keskiverto Wrote:
The code of count_intersection exists only in my comment. You have to copy it from there.

After a little thinking what he meant. I realized it probably was a function that he was describing. Please bear in mind, I'm a real newbie at this yet.

dutch Wrote:
Yeah, keskiverto wrote the count_intersection code as a modification (optimization for your purpose) of the set_intersection code, so you need to copy that code as a function in your program.

After reading that, it confirms my thoughts. WOW!! Thanks keskiverto!!!!!! I can't believe that he wrote that just for my purpose. I will give it a try.

Now:
1
2
3
4
5
6
7
8
9
    for (int a = 0; a < timings_reporting; ++a) {
        int cnt[3]{}, i = 2;
        for (size_t b = a + 1; b < d5.size(); ++b, ++cnt[i])
            if (count_intersection(d5[a].begin(), d5[a].end(), d5[b].begin(), d5[b].end()) >= i + 2)
                --i;
        cnt[1] += cnt[2]; // >= 3 includes >= 4
        cnt[0] += cnt[1]; // >= 2 includes >= 3
        std::cout << a + 1 << '\t' << cnt[0] << '\t' << cnt[1] << '\t' << cnt[2] << '\n';
    }


This seems a little confusing to me. I have to think about this one. There are 4 parts of this I'm not following yet.

int cnt[3]{}, i = 2; // part 1

++cnt[i]) // part 2

>= i + 2) // part 3

cnt[1] += cnt[2]; // >= 3 includes >= 4 // parts 4
cnt[0] += cnt[1]; // >= 2 includes >= 3


I will give it a good effort though. It may take awhile.
This seems a little confusing to me.

Firstly, there's an error. I forgot to add a break to stop the inner for loop, so the code should be:

1
2
3
4
5
6
7
8
9
    for (int a = 0; a < timings_reporting; ++a) {
        int cnt[3]{}, i = 2;
        for (size_t b = a + 1; b < d5.size(); ++b, ++cnt[i])
            if (count_intersection(d5[a].begin(), d5[a].end(), d5[b].begin(), d5[b].end()) >= i + 2)
                if (--i < 0) break;
        cnt[1] += cnt[2]; // >= 3 includes >= 4
        cnt[0] += cnt[1]; // >= 2 includes >= 3
        std::cout << a + 1 << '\t' << cnt[0] << '\t' << cnt[1] << '\t' << cnt[2] << '\n';
    }

One point is that a, line_number, and layer_rep_start are basically the same, so I just used a.

int cnt[3] {} is an array of 3 ints to hold the counts.
It is initialized to all zeroes by the empty braces.
cnt[0] will hold the 2 count, cnt[1] the 3 count, cnt[2] the 4 count.
It is indexed with i, starting at 2 and going down to 0.
When i hits -1 the inner for loop will break.
i + 2 gives the count that index i represents.

The idea is that counting the 2's, 3's, and 4's separately is duplicating much of the work.
The >=4's are also >=3's and >=2's.
The >=3's are also >=2's.
If you see what I mean.
Last edited on
int cnt[3] {} is an array of 3 ints to hold the counts.
It is initialized to all zeroes by the empty braces.
cnt[0] will hold the 2 count, cnt[1] the 3 count, cnt[2] the 4 count.
It is indexed with i, starting at 2 and going down to 0.
When i hits -1 the inner for loop will break.
i + 2 gives the count that index i represents.
GREAT explanation!! Thanks dutch! That is very clear to me now.




The idea is that counting the 2's, 3's, and 4's separately is duplicating much of the work.
The >=4's are also >=3's and >=2's.
The >=3's are also >=2's.
If you see what I mean.
VERY very clear now!! I had a rough time with that one. You guys are geniuses! Don't know how you guys come up with this stuff. I would have never thought of it that way. I'll give this count_intersection function and new for loop a test drive tomorrow. I'll post back tomorrow with results on accuracy and timings.

THANKS dutch!!!
Here are the timing results for this method #1 of count_intersection:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
        int two_counter {0};
        for (size_t b = layer_rep_start; b < d5.size(); ++b, ++two_counter)
                if (count_intersection(d5[a].begin(), d5[a].end(), d5[b].begin(), d5[b].end()) >= 2 )
                    break;
        
        int three_counter {0};
        for (size_t b = layer_rep_start; b < d5.size(); ++b, ++three_counter)
                if (count_intersection(d5[a].begin(), d5[a].end(), d5[b].begin(), d5[b].end()) >= 3)
                    break;
        
        int four_counter {0};
        for (size_t b = layer_rep_start; b < d5.size(); ++b, ++four_counter)
                if (count_intersection(d5[a].begin(), d5[a].end(), d5[b].begin(), d5[b].end()) >= 4 )
                    break;
I ran the code (to print 100 lines of output) 5 times. Here are the chrono times in microseconds:
314895
318968
314709
319853
324660

After looking at a post above (6 up from here) these timings are about 5/100ths of a second slower. That's not a big deal for my purposes. I like the layout better with it this way. It's easier for me to follow (reading wise).

Here was another method #2 that I timed using chrono:
1
2
3
4
5
6
7
        int cnt[3]{}, i = 2;
        for (size_t b = a + 1; b < d5.size(); ++b, ++cnt[i])
            if (count_intersection(d5[a].begin(), d5[a].end(), d5[b].begin(), d5[b].end()) >= i + 2)
                if (--i < 0) break;
        cnt[1] += cnt[2]; // >= 3 includes >= 4
        cnt[0] += cnt[1]; // >= 2 includes >= 3
        std::cout << a + 1 << '\t' << cnt[0] << '\t' << cnt[1] << '\t' << cnt[2] << '\n';
There was a problem with the accuracy of the output. It was very strange indeed. The only counter that was correct was cnt[2]. Now, cnt[2] (>=4), should have the highest count of the three. But, cnt[1] was higher than cnt[2], and cnt[0] was higher than cnt[1]. The weird part is, cnt[2] values were correct!!! The timings using chrono were very similar, only about 2/100ths of a second slower than method #1 timings mentioned above(in this post).

I'm very satisfied using the count_intersection method #1. I'm going to consider this thread SOLVED!!!!

MANY MANY THANKS to dutch and keskiverto for educating me on a bunch of things, and for taking the time, and showing patience. I definetly have A LOT to learn yet!! Thanks guys!!
Last edited on
Registered users can post here. Sign in or register to post.
Pages: 12