Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions contents/approximate_counting/approximate_counting.md
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,8 @@ As we do not have any objects to count, we will instead simulate the counting wi
{% method %}
{% sample lang="jl" %}
[import, lang:"julia"](code/julia/approximate_counting.jl)
{% sample lang="c" %}
[import, lang:"c"](code/c/approximate_counting.c)
{% endmethod %}

### Bibliography
Expand Down
82 changes: 82 additions & 0 deletions contents/approximate_counting/code/c/approximate_counting.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

// This function returns a pseudo-random number between 0 and 1
double drand()
{
return (double)rand() / RAND_MAX;
}

// This function takes
// - v: value in register
// - a: a scaling value for the logarithm based on Morris's paper
// It returns the approximate count
double n(double v, double a)
{
return a * (pow(1 + 1 / a, v) - 1);
}

// This function takes
// - v: value in register
// - a: a scaling value for the logarithm based on Morris's paper
// It returns a new value for v
double increment(double v, double a)
{
// delta is the probability of incrementing our counter
double delta = 1 / (n(v + 1, a) - n(v, a));

if (drand() <= delta) {
return v + 1;
}
return v;
}

// This function simulates counting and takes
// - n_items: number of items to count and loop over
// - a: a scaling value for the logarithm based on Morris's paper
// It returns n(v, a), the approximate count
double approximate_count(size_t n_items, double a)
{
int v = 0;
for (size_t i = 0; i < n_items; ++i) {
v = increment(v, a);
}

return n(v, a);
}

// This function takes
// - n_trials: the number of counting trials
// - n_items: the number off items to count
// - a: a scaling value for the logarithm based on Morris's paper
// - threshold: the maximum percent error allowed
// It terminates the program on failure
void test_approximation_count(size_t n_trials, size_t n_items, double a,
double threshold)
{
double sum = 0.0;
for (size_t i = 0; i < n_trials; ++i) {
sum += approximate_count(n_items, a);
}
double avg = sum / n_trials;

assert(fabs((avg - n_items) / n_items) < threshold);
}

int main()
{
srand(time(NULL));

printf("Counting Tests, 100 trials\n");
printf("testing 1000, a = 30, 1%% error\n");
test_approximation_count(100, 1000, 30, 0.1);
printf("testing 12345, a = 10, 1%% error\n");
test_approximation_count(100, 12345, 10, 0.1);
printf("testing 222222, a = 0.5, 10%% error\n");
test_approximation_count(100, 222222, 0.5, 0.1);

return 0;
}