X-Git-Url: https://git.octo.it/?p=sort-networks.git;a=blobdiff_plain;f=src%2Fsn_network.c;h=1b3dd3630515aaa92adbdd18eeed51cd2a2fb427;hp=b490de404cd5f6915aa5efce725e20f3d0c9cb60;hb=2b64b183834075911f9e53a6f0132d116bf45a76;hpb=5c43c25325b3a869d64c013b7ba02d1d28eb9ec6 diff --git a/src/sn_network.c b/src/sn_network.c index b490de4..1b3dd36 100644 --- a/src/sn_network.c +++ b/src/sn_network.c @@ -135,6 +135,78 @@ sn_network_t *sn_network_create_odd_even_mergesort (int inputs_num) /* {{{ */ } } /* }}} sn_network_t *sn_network_create_odd_even_mergesort */ +static int sn_network_create_pairwise_internal (sn_network_t *n, /* {{{ */ + int *inputs, int inputs_num) +{ + int i; + int inputs_copy[inputs_num]; + int m; + + for (i = 1; i < inputs_num; i += 2) + { + sn_comparator_t *c = sn_comparator_create (inputs[i-1], inputs[i]); + sn_network_comparator_add (n, c); + sn_comparator_destroy (c); + } + + if (inputs_num <= 2) + return (0); + + /* Sort "pairs" recursively. Like with odd-even mergesort, odd and even lines + * are handled recursively and later reunited. */ + for (i = 0; i < inputs_num; i += 2) + inputs_copy[(int) (i / 2)] = inputs[i]; + /* Recursive call #1 with first set of lines */ + sn_network_create_pairwise_internal (n, inputs_copy, + (int) ((inputs_num + 1) / 2)); + + for (i = 1; i < inputs_num; i += 2) + inputs_copy[(int) (i / 2)] = inputs[i]; + /* Recursive call #2 with second set of lines */ + sn_network_create_pairwise_internal (n, inputs_copy, + (int) (inputs_num/ 2)); + + /* m is the "amplitude" of the sorted pairs. This is a bit tricky to read due + * to different indices being used in the paper, unfortunately. */ + m = inputs_num / 2; + while (m > 1) + { + for (i = 1; (i + (m - 1)) < inputs_num; i += 2) + { + int left = i; + int right = i + (m - 1); + sn_comparator_t *c; + + assert (left < right); + c = sn_comparator_create (inputs[left], inputs[right]); + sn_network_comparator_add (n, c); + sn_comparator_destroy (c); + } + + m = m / 2; + } /* while (m > 1) */ + + return (0); +} /* }}} int sn_network_create_pairwise_internal */ + +sn_network_t *sn_network_create_pairwise (int inputs_num) /* {{{ */ +{ + sn_network_t *n = sn_network_create (inputs_num); + int inputs[inputs_num]; + int i; + + if (n == NULL) + return (NULL); + + for (i = 0; i < inputs_num; i++) + inputs[i] = i; + + sn_network_create_pairwise_internal (n, inputs, inputs_num); + sn_network_compress (n); + + return (n); +} /* }}} sn_network_t *sn_network_create_pairwise */ + int sn_network_stage_add (sn_network_t *n, sn_stage_t *s) /* {{{ */ { sn_stage_t **temp;