sn-pairwise: Implement the pairwise sorting network.
[sort-networks.git] / src / sn_network.h
1 /**
2  * \file sn_network.h
3  * \brief The sn_network_t class and associated methods.
4  *
5  * This is more details about what this file does.
6  *
7  * \verbatim
8  * libsortnetwork - src/sn_network.h
9  * Copyright (C) 2008-2010  Florian octo Forster
10  *
11  * This program is free software; you can redistribute it and/or modify it
12  * under the terms of the GNU General Public License as published by the
13  * Free Software Foundation; only version 2 of the License is applicable.
14  *
15  * This program is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License along
21  * with this program; if not, write to the Free Software Foundation, Inc.,
22  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
23  *
24  * Authors:
25  *   Florian octo Forster <ff at octo.it>
26  * \endverbatim
27  **/
28
29
30 #ifndef SN_NETWORK_H
31 #define SN_NETWORK_H 1
32
33 #include <stdio.h>
34
35 #include "sn_comparator.h"
36 #include "sn_stage.h"
37
38 /**
39  * The global struct representing a comparator or sort network.
40  */
41 struct sn_network_s
42 {
43   int inputs_num;       /**< Number of inputs of the comparator network. */
44   sn_stage_t **stages;  /**< Array of pointers to the stages of a comparator network. */
45   int stages_num;       /**< Number of stages in this comparator network. */
46 };
47 typedef struct sn_network_s sn_network_t;
48
49 #define SN_NETWORK_STAGE_NUM(n) (n)->stages_num
50 #define SN_NETWORK_STAGE_GET(n,i) ((n)->stages[i])
51 #define SN_NETWORK_INPUT_NUM(n) (n)->inputs_num
52
53 /**
54  * Creates an empty comparator network and returns a pointer to it. The
55  * comparator network must be freed using sn_network_destroy().
56  *
57  * \param inputs_num Number of inputs the comparator network has.
58  * \return Pointer to the comparator network or \c NULL on error.
59  */
60 sn_network_t *sn_network_create (int inputs_num);
61
62 /**
63  * Clones an existing comparator network.
64  *
65  * \param n Comparator network to clone.
66  * \return Copied sort network or \c NULL on error. The returned network must
67  *   be freed using sn_network_destroy().
68  */
69 sn_network_t *sn_network_clone (const sn_network_t *n);
70
71 /**
72  * Destroys a comparator network allocated with sn_network_create() or one of
73  * the other methods returning a \c sn_network_t. This frees all allocated
74  * space.
75  *
76  * \param n The comparator network to destroy. May be \c NULL.
77  */
78 void sn_network_destroy (sn_network_t *n);
79
80 /**
81  * Creates a new sort network using Batcher's Odd-Even-Mergesort algorithm.
82  *
83  * \param inputs_num Number of inputs / outputs of the sorting network.
84  * \return A pointer to the newly allocated sorting network or \c NULL if an
85  *   invalid number of inputs was given or allocation failed.
86  */
87 sn_network_t *sn_network_create_odd_even_mergesort (int inputs_num);
88
89 /**
90  * Creates a new sorting network using the Pairwise sorting algorithm published
91  * by Ian Parberry.
92  * \param inputs_num Number of inputs / outputs of the sorting network.
93  * \return A pointer to the newly allocated sorting network or \c NULL if an
94  *   invalid number of inputs was given or allocation failed.
95  */
96 sn_network_t *sn_network_create_pairwise (int inputs_num);
97
98 /**
99  * Append a new stage to a comparator network.
100  *
101  * \param n The comparator network to which to add the stage.
102  * \param s A pointer to a stage. The memory pointed to by this parameter is
103  *   not copied and freed by sn_network_destroy(). It is the caller's
104  *   responsibility to call sn_stage_clone() if appropriate.
105  * \return Zero on success, non-zero on failure.
106  */
107 int sn_network_stage_add (sn_network_t *n, sn_stage_t *s);
108
109 /**
110  * Remove a stage from a comparator network.
111  *
112  * \param n A pointer to the comparator network to modify.
113  * \param s_num The depth of the comparator network to remove, with zero being
114  *   meaning the stage closest to the inputs.
115  * \return Zero on success, non-zero on failure.
116  */
117 int sn_network_stage_remove (sn_network_t *n, int s_num);
118
119 /**
120  * Adds a comparator to a comparator network. The code tries to add the
121  * comparator to the last stage, i.e. the stage closest to the outputs. If this
122  * is not possible, because one line is used by another comparator, a new stage
123  * is created and appended to the sorting network.
124  *
125  * \param n Pointer to the comparator netork.
126  * \param c Pointer to a comparator to add. The given comparator is copied. It
127  *   is the caller's responsibility to free c.
128  * \return Zero on success, non-zero on failure.
129  */
130 int sn_network_comparator_add (sn_network_t *n, const sn_comparator_t *c);
131
132 /**
133  * Returns the number of comparators contained in the comparator network. This
134  * will traverse all comparators in all stages, resulting in a running time of
135  * \f$ \mathcal{O}(n) \f$.
136  *
137  * \param n Comparator network to work with.
138  * \return The number of comparators contained in the network or less than zero
139  *  on error (\c n is \c NULL).
140  */
141 int sn_network_get_comparator_num (const sn_network_t *n);
142
143 /**
144  * Applies a comparator network to an array of integers. This is implemented by
145  * calling sn_stage_sort() with every stage of the network.
146  *
147  * \param n Pointer to the comparator netork.
148  * \param[in,out] values Pointer to integer values to sort. The number of
149  *   integer values pointed to must be at least the number of inputs of the
150  *   comparator network. Otherwise, segmentation faults or memory corruption
151  *   will occur.
152  * \return Zero on success, non-zero on failure.
153  * \see sn_stage_sort
154  */
155 int sn_network_sort (sn_network_t *n, int *values);
156
157 /**
158  * Checks whether a given comparator network is a sorting network by testing
159  * all \f$ 2^n \f$ 0-1-patterns. Since this function has exponential running
160  * time, using it with comparator networks with many inputs is not advisable.
161  *
162  * \param n The comparator network to test.
163  * \return Zero if the comparator network is a sort network, one if the
164  *   comparator network is \em not a sort network, or something else on error.
165  */
166 int sn_network_brute_force_check (sn_network_t *n);
167
168 /**
169  * Prints the comparator network to \c STDOUT using a human readable
170  * representation.
171  *
172  * \param n The comparator network to display.
173  * \return Zero on success, non-zero on failure.
174  */
175 int sn_network_show (sn_network_t *n);
176
177 /**
178  * Inverts a comparator network by switching the direction of all comparators.
179  *
180  * \param n The network to invert.
181  * \return Zero on success, non-zero on failure.
182  */
183 int sn_network_invert (sn_network_t *n);
184
185 /**
186  * Shifts a comparator network (permutes the inputs). Each input is shifted
187  * \f$ s \f$ positions, higher inputs are "wrapped around".
188  *
189  * \param n The comparator network to shift.
190  * \param s The number of positions to shift.
191  * \return Zero on success, non-zero on failure.
192  */
193 int sn_network_shift (sn_network_t *n, int s);
194
195 /**
196  * Compresses a comparator network by moving all comparators to the earliest
197  * possible stage and removing all remaining empty stages.
198  *
199  * \param n The network to compress.
200  * \return Zero on success, non-zero on failure.
201  */
202 int sn_network_compress (sn_network_t *n);
203
204 /**
205  * Converts a non-standard comparator network to a standard comparator network,
206  * i.e. a network in which all comparators point in the same direction.
207  *
208  * \param n The network to normalize.
209  * \return Zero on success, non-zero on failure.
210  */
211 int sn_network_normalize (sn_network_t *n);
212
213 /**
214  * Removes an inputs from a comparator network by assuming positive or negative
215  * infinity to be supplied to a given input. The value will take a
216  * deterministic way through the comparator network. After removing the path
217  * and all comparators it touched from the comparator network, a new comparator
218  * network with \f$ n-1 \f$ inputs remains. The remaining outputs behave
219  * identical to the original network with respect to one another.
220  *
221  * \param n The comparator network to modify.
222  * \param input The input to remove.
223  * \param dir The direction in which to cut, i.e. whether to assume positive or
224  *   negative infinity.
225  * \return Zero on success, non-zero on failure.
226  */
227 int sn_network_cut_at (sn_network_t *n, int input, enum sn_network_cut_dir_e dir);
228
229 /**
230  * An alias for sn_network_combine_odd_even_merge().
231  */
232 sn_network_t *sn_network_combine (sn_network_t *n0, sn_network_t *n1);
233
234 /**
235  * Combines two comparator networks using a bitonic merger. The number of
236  * inputs of both comparator networks must be identical and a power of two.
237  *
238  * \param n0 First network.
239  * \param n1 Second network.
240  * \return Newly allocated network with twice the number of inputs or \c NULL
241  *   on error.
242  */
243 sn_network_t *sn_network_combine_bitonic_merge (sn_network_t *n0, sn_network_t *n1);
244
245 /**
246  * Combines two comparator networks using the odd-even-merger.
247  *
248  * \param n0 First network.
249  * \param n1 Second network.
250  * \return Newly allocated network or \c NULL on error.
251  */
252 sn_network_t *sn_network_combine_odd_even_merge (sn_network_t *n0, sn_network_t *n1);
253
254 /**
255  * Reads a comparator network from a open file handle.
256  *
257  * \param fh The FILE pointer to read from.
258  * \return A newly allocated comparator network or \c NULL on error.
259  * \see sn_network_read_file
260  */
261 sn_network_t *sn_network_read (FILE *fh);
262
263 /**
264  * Reads a comparator network from a file.
265  *
266  * \param file File name to read the network from.
267  * \return A newly allocated comparator network or \c NULL on error.
268  * \see sn_network_read
269  */
270 sn_network_t *sn_network_read_file (const char *file);
271
272 /**
273  * Writes a comparator network to a file handle.
274  *
275  * \param n The comparator network to write.
276  * \param fh The file handle to write to. Must be opened in write mode.
277  * \return Zero on success, non-zero on failure.
278  * \see sn_network_write_file
279  */
280 int sn_network_write (sn_network_t *n, FILE *fh);
281
282 /**
283  * Writes a comparator network to a file.
284  *
285  * \param n The comparator network to write.
286  * \param fh The file name to write the network to.
287  * \return Zero on success, non-zero on failure.
288  * \see sn_network_write
289  */
290 int sn_network_write_file (sn_network_t *n, const char *file);
291
292 /**
293  * Creates a serialized form of the given comparator network. The serialized
294  * form is byte-order independent and can easily be sent over a computer
295  * network.
296  *
297  * \param n The comparator network to serialize.
298  * \param[out] ret_buffer Pointer to a pointer into which the location of the
299  *   allocated memory will be written. It is the caller's responsibility to
300  *   free this memory.
301  * \param[out] ret_buffer_size Pointer to a size_t into which the size of the
302  *   allocated memory will be written.
303  * \return Zero on success, non-zero on failure.
304  * \see sn_network_unserialize
305  */
306 int sn_network_serialize (sn_network_t *n, char **ret_buffer,
307     size_t *ret_buffer_size);
308
309 /**
310  * Creates a comparator network from its serialized form.
311  *
312  * \param buffer Pointer to a buffer containing the comparator network in
313  *   serialized form.
314  * \param buffer_size Size of the buffer (in bytes).
315  * \return Pointer to the newly allocated comparator network or \c NULL on
316  *   error.
317  * \see sn_network_serialize
318  */
319 sn_network_t *sn_network_unserialize (char *buffer, size_t buffer_size);
320 #endif /* SN_NETWORK_H */
321
322 /* vim: set shiftwidth=2 softtabstop=2 : */