Scippy

SCIP

Solving Constraint Integer Programs

bitencode.c
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the program and library */
4/* SCIP --- Solving Constraint Integer Programs */
5/* */
6/* Copyright (c) 2002-2024 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/**@file bitencode.c
26 * @ingroup OTHER_CFILES
27 * @brief packing single and dual bit values
28 * @author Thorsten Koch
29 * @author Tobias Achterberg
30 */
31
32/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
33
34#include <assert.h>
35
36#include "scip/def.h"
37#include "scip/bitencode.h"
38
39
40/** encode a single bit vector into packed format */
42 const int* inp, /**< unpacked input vector */
43 SCIP_SINGLEPACKET* out, /**< buffer to store the packed vector */
44 int count /**< number of elements */
45 )
46{
47 static const SCIP_SINGLEPACKET mask[SCIP_SINGLEPACKETSIZE][2] = { /* if the packet size changes, the mask has to be updated */
48 {0x00000000, 0x00000001},
49 {0x00000000, 0x00000002},
50 {0x00000000, 0x00000004},
51 {0x00000000, 0x00000008},
52 {0x00000000, 0x00000010},
53 {0x00000000, 0x00000020},
54 {0x00000000, 0x00000040},
55 {0x00000000, 0x00000080},
56 {0x00000000, 0x00000100},
57 {0x00000000, 0x00000200},
58 {0x00000000, 0x00000400},
59 {0x00000000, 0x00000800},
60 {0x00000000, 0x00001000},
61 {0x00000000, 0x00002000},
62 {0x00000000, 0x00004000},
63 {0x00000000, 0x00008000},
64 {0x00000000, 0x00010000},
65 {0x00000000, 0x00020000},
66 {0x00000000, 0x00040000},
67 {0x00000000, 0x00080000},
68 {0x00000000, 0x00100000},
69 {0x00000000, 0x00200000},
70 {0x00000000, 0x00400000},
71 {0x00000000, 0x00800000},
72 {0x00000000, 0x01000000},
73 {0x00000000, 0x02000000},
74 {0x00000000, 0x04000000},
75 {0x00000000, 0x08000000},
76 {0x00000000, 0x10000000},
77 {0x00000000, 0x20000000},
78 {0x00000000, 0x40000000},
79 {0x00000000, 0x80000000}
80 };
81 int rest;
82 int nfull;
83 const int packetsize = (int) SCIP_SINGLEPACKETSIZE;
84
85 assert(inp != NULL || count == 0);
86 assert(out != NULL || count == 0);
87 assert(count >= 0);
88 assert(packetsize == 32);
89
90 rest = count % packetsize;
91 nfull = count - rest;
92
93 for( int i = 0; i < nfull; i += packetsize )
94 {
95 assert(inp != NULL);
96 assert(out != NULL);
97
98#ifndef NDEBUG
99 {
100 for( int j = 0; j < packetsize; ++j )
101 assert(0 <= inp[j] && inp[j] <= 1);
102 }
103#endif
104 *out++ =
105 mask[0][inp[0]] | mask[1][inp[1]] | mask[2][inp[2]] | mask[3][inp[3]]
106 | mask[4][inp[4]] | mask[5][inp[5]] | mask[6][inp[6]] | mask[7][inp[7]]
107 | mask[8][inp[8]] | mask[9][inp[9]] | mask[10][inp[10]] | mask[11][inp[11]]
108 | mask[12][inp[12]] | mask[13][inp[13]] | mask[14][inp[14]] | mask[15][inp[15]]
109 | mask[16][inp[16]] | mask[17][inp[17]] | mask[18][inp[18]] | mask[19][inp[19]]
110 | mask[20][inp[20]] | mask[21][inp[21]] | mask[22][inp[22]] | mask[23][inp[23]]
111 | mask[24][inp[24]] | mask[25][inp[25]] | mask[26][inp[26]] | mask[27][inp[27]]
112 | mask[28][inp[28]] | mask[29][inp[29]] | mask[30][inp[30]] | mask[31][inp[31]];
113 inp += packetsize;
114 }
115
116 if( rest > 0 )
117 {
119
120 assert(inp != NULL);
121 assert(out != NULL);
122 assert(rest <= (int) SCIP_SINGLEPACKETSIZE);
123
124 for( int i = 0; i < rest; i++ )
125 m |= mask[i][inp[i]];
126 *out = m;
127 }
128}
129
130/** decode a packed single bit vector into unpacked format */
132 const SCIP_SINGLEPACKET* inp, /**< packed input vector */
133 int* out, /**< buffer to store unpacked vector */
134 int count /**< number of elements */
135 )
136{
138 int rest;
139 int nfull;
140 int i;
141
142 assert(inp != NULL || count == 0);
143 assert(out != NULL || count == 0);
144 assert(count >= 0);
145 assert(SCIP_SINGLEPACKETSIZE == 32); /*lint !e506*/
146
147 rest = count % (int)SCIP_SINGLEPACKETSIZE;
148 nfull = count - rest;
149
150 for( i = 0; i < nfull; i += (int)SCIP_SINGLEPACKETSIZE )
151 {
152 assert(inp != NULL);
153 assert(out != NULL);
154
155 m = *inp++;
156
157 *out++ = (int)m & 1;
158 m >>= 1;
159 *out++ = (int)m & 1;
160 m >>= 1;
161 *out++ = (int)m & 1;
162 m >>= 1;
163 *out++ = (int)m & 1;
164 m >>= 1;
165 *out++ = (int)m & 1;
166 m >>= 1;
167 *out++ = (int)m & 1;
168 m >>= 1;
169 *out++ = (int)m & 1;
170 m >>= 1;
171 *out++ = (int)m & 1;
172 m >>= 1;
173 *out++ = (int)m & 1;
174 m >>= 1;
175 *out++ = (int)m & 1;
176 m >>= 1;
177 *out++ = (int)m & 1;
178 m >>= 1;
179 *out++ = (int)m & 1;
180 m >>= 1;
181 *out++ = (int)m & 1;
182 m >>= 1;
183 *out++ = (int)m & 1;
184 m >>= 1;
185 *out++ = (int)m & 1;
186 m >>= 1;
187 *out++ = (int)m & 1;
188 m >>= 1;
189 *out++ = (int)m & 1;
190 m >>= 1;
191 *out++ = (int)m & 1;
192 m >>= 1;
193 *out++ = (int)m & 1;
194 m >>= 1;
195 *out++ = (int)m & 1;
196 m >>= 1;
197 *out++ = (int)m & 1;
198 m >>= 1;
199 *out++ = (int)m & 1;
200 m >>= 1;
201 *out++ = (int)m & 1;
202 m >>= 1;
203 *out++ = (int)m & 1;
204 m >>= 1;
205 *out++ = (int)m & 1;
206 m >>= 1;
207 *out++ = (int)m & 1;
208 m >>= 1;
209 *out++ = (int)m & 1;
210 m >>= 1;
211 *out++ = (int)m & 1;
212 m >>= 1;
213 *out++ = (int)m & 1;
214 m >>= 1;
215 *out++ = (int)m & 1;
216 m >>= 1;
217 *out++ = (int)m & 1;
218 m >>= 1;
219 *out++ = (int)m & 1;
220 assert(m >> 1 == 0);
221 }
222
223 if( rest > 0 )
224 {
225 assert(inp != NULL);
226 assert(out != NULL);
227
228 m = *inp;
229 for( i = 0; i < rest; i++ )
230 {
231 *out++ = (int)m & 1;
232 m >>= 1;
233 }
234 }
235}
236
237/** encode a dual bit vector into packed format */
239 const int* inp, /**< unpacked input vector */
240 SCIP_DUALPACKET* out, /**< buffer to store the packed vector */
241 int count /**< number of elements */
242 )
243{
244 static const SCIP_DUALPACKET mask[SCIP_DUALPACKETSIZE][4] = { /* if the packet size changes, the mask has to be updated */
245 {0x00000000, 0x00000001, 0x00000002, 0x00000003},
246 {0x00000000, 0x00000004, 0x00000008, 0x0000000C},
247 {0x00000000, 0x00000010, 0x00000020, 0x00000030},
248 {0x00000000, 0x00000040, 0x00000080, 0x000000C0},
249 {0x00000000, 0x00000100, 0x00000200, 0x00000300},
250 {0x00000000, 0x00000400, 0x00000800, 0x00000C00},
251 {0x00000000, 0x00001000, 0x00002000, 0x00003000},
252 {0x00000000, 0x00004000, 0x00008000, 0x0000C000},
253 {0x00000000, 0x00010000, 0x00020000, 0x00030000},
254 {0x00000000, 0x00040000, 0x00080000, 0x000C0000},
255 {0x00000000, 0x00100000, 0x00200000, 0x00300000},
256 {0x00000000, 0x00400000, 0x00800000, 0x00C00000},
257 {0x00000000, 0x01000000, 0x02000000, 0x03000000},
258 {0x00000000, 0x04000000, 0x08000000, 0x0C000000},
259 {0x00000000, 0x10000000, 0x20000000, 0x30000000},
260 {0x00000000, 0x40000000, 0x80000000, 0xC0000000}
261 };
262 int rest;
263 int nfull;
264 const int dualpacketsize = (int) SCIP_DUALPACKETSIZE;
265
266 assert(inp != NULL || count == 0);
267 assert(out != NULL || count == 0);
268 assert(count >= 0);
269 assert(dualpacketsize == 16);
270
271 rest = count % dualpacketsize;
272 nfull = count - rest;
273
274 for( int i = 0; i < nfull; i += dualpacketsize, inp += dualpacketsize ) /*lint !e679*/
275 {
276 assert(inp != NULL);
277 assert(out != NULL);
278
279#ifndef NDEBUG
280 {
281 for( int j = 0; j < dualpacketsize; ++j )
282 assert(0 <= inp[j] && inp[j] <= 3);
283 }
284#endif
285 *out++ =
286 mask[0][inp[0]] | mask[1][inp[1]] | mask[2][inp[2]] | mask[3][inp[3]]
287 | mask[4][inp[4]] | mask[5][inp[5]] | mask[6][inp[6]]
288 | mask[7][inp[7]] | mask[8][inp[8]] | mask[9][inp[9]]
289 | mask[10][inp[10]] | mask[11][inp[11]] | mask[12][inp[12]]
290 | mask[13][inp[13]] | mask[14][inp[14]] | mask[15][inp[15]];
291 }
292
293 if( rest > 0 )
294 {
296
297 assert(inp != NULL);
298 assert(out != NULL);
299 assert(rest <= (int) SCIP_DUALPACKETSIZE);
300
301 for( int i = 0; i < rest; i++ )
302 m |= mask[i][inp[i]];
303 *out = m;
304 }
305}
306
307/** decode a packed dual bit vector into unpacked format */
309 const SCIP_DUALPACKET* inp, /**< packed input vector */
310 int* out, /**< buffer to store unpacked vector */
311 int count /**< number of elements */
312 )
313{
315 int rest;
316 int nfull;
317 int i;
318
319 assert(inp != NULL || count == 0);
320 assert(out != NULL || count == 0);
321 assert(count >= 0);
322 assert(SCIP_DUALPACKETSIZE == 16); /*lint !e506*/
323
324 rest = count % (int)SCIP_DUALPACKETSIZE;
325 nfull = count - rest;
326
327 for( i = 0; i < nfull; i += (int)SCIP_DUALPACKETSIZE )
328 {
329 assert(inp != NULL);
330 assert(out != NULL);
331
332 m = *inp++;
333
334 *out++ = (int)m & 3;
335 m >>= 2;
336 *out++ = (int)m & 3;
337 m >>= 2;
338 *out++ = (int)m & 3;
339 m >>= 2;
340 *out++ = (int)m & 3;
341 m >>= 2;
342 *out++ = (int)m & 3;
343 m >>= 2;
344 *out++ = (int)m & 3;
345 m >>= 2;
346 *out++ = (int)m & 3;
347 m >>= 2;
348 *out++ = (int)m & 3;
349 m >>= 2;
350 *out++ = (int)m & 3;
351 m >>= 2;
352 *out++ = (int)m & 3;
353 m >>= 2;
354 *out++ = (int)m & 3;
355 m >>= 2;
356 *out++ = (int)m & 3;
357 m >>= 2;
358 *out++ = (int)m & 3;
359 m >>= 2;
360 *out++ = (int)m & 3;
361 m >>= 2;
362 *out++ = (int)m & 3;
363 m >>= 2;
364 *out++ = (int)m & 3;
365 assert(m >> 2 == 0);
366 }
367
368 if( rest > 0 )
369 {
370 assert(inp != NULL);
371 assert(out != NULL);
372
373 m = *inp;
374 for( i = 0; i < rest; i++ )
375 {
376 *out++ = (int)m & 3;
377 m >>= 2;
378 }
379 }
380}
381
void SCIPdecodeDualBit(const SCIP_DUALPACKET *inp, int *out, int count)
Definition: bitencode.c:308
void SCIPencodeDualBit(const int *inp, SCIP_DUALPACKET *out, int count)
Definition: bitencode.c:238
void SCIPencodeSingleBit(const int *inp, SCIP_SINGLEPACKET *out, int count)
Definition: bitencode.c:41
void SCIPdecodeSingleBit(const SCIP_SINGLEPACKET *inp, int *out, int count)
Definition: bitencode.c:131
packing single and dual bit values
#define SCIP_SINGLEPACKETSIZE
Definition: bitencode.h:41
#define SCIP_DUALPACKETSIZE
Definition: bitencode.h:43
unsigned int SCIP_SINGLEPACKET
Definition: bitencode.h:40
unsigned int SCIP_DUALPACKET
Definition: bitencode.h:42
common defines and data types used in all packages of SCIP
#define NULL
Definition: def.h:267