SSJ API Documentation
Stochastic Simulation in Java
Loading...
Searching...
No Matches
BitVector.java
1/*
2 * Class: BitVector
3 * Description: implements vectors of bits and their operations
4 * Environment: Java
5 * Software: SSJ
6 * Copyright (C) 2001 Pierre L'Ecuyer and Universite de Montreal
7 * Organization: DIRO, Universite de Montreal
8 * @author
9 * @since
10 *
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 *
24 */
25package umontreal.ssj.util;
26
27import java.io.Serializable;
28
45public class BitVector implements Serializable, Cloneable {
46
47 static final long serialVersionUID = -3448233092524725148L;
48
49 private int[] v; // the bits data
50 private int length; // number of data bits (in bits, not in bytes)
51
52 private final static int all_1 = -1; // integer with all bits set to 1
53 private final static int one_1 = 1; // integer with only his last bit set to 1
54 /*
55 * Note sur le format interne du vecteur de bits : On fait toujours en sorte que
56 * les bits redondants (ceux qui apparaissent quand length % 32 != 0) soient mis
57 * a 0. Ceci permet de faire des operations entre des vecteurs de longeurs
58 * differentes en posant que les bits manquants sur le plus petit des deux
59 * vecteurs ont la valeur 0.
60 */
61
67 public BitVector(int length) {
68 this.length = length;
69 v = new int[(length + 31) / 32];
70 for (int i = 0; i < v.length; i++)
71 v[i] = 0;
72 }
73
86 public BitVector(int[] vect, int length) {
87 if (((length + 31) / 32) != vect.length)
88 throw new IllegalArgumentException("The int[] length must be equal to the (length + 31) / 32");
89
90 this.length = length;
91 v = new int[vect.length];
92 for (int i = 0; i < vect.length; i++)
93 v[i] = vect[i];
94
95 // the extra bits must be set at zero
96 v[v.length - 1] &= (all_1 >>> (31 - (length - 1) % 32));
97 }
98
105 public BitVector(int[] vect) {
106 this(vect, vect.length * 32);
107 }
108
114 public BitVector(BitVector that) {
115 this.length = that.length;
116 this.v = new int[that.v.length];
117 for (int i = 0; i < that.v.length; i++)
118 this.v[i] = that.v[i];
119 }
120
126 public Object clone() {
127 try {
128 BitVector c = (BitVector) super.clone();
129 c.v = (int[]) v.clone();
130 return c;
131 } catch (CloneNotSupportedException e) {
132 IllegalStateException ne = new IllegalStateException();
133 ne.initCause(e);
134 throw ne;
135 }
136 }
137
145 public boolean equals(BitVector that) {
146 if (this.length != that.length)
147 return false;
148 for (int i = 0; i < this.v.length; i++)
149 if (this.v[i] != that.v[i])
150 return false;
151 return true;
152 }
153
159 public int size() {
160 return length;
161 }
162
171 public void enlarge(int size, boolean filling) {
172 if (size < 0)
173 throw new NegativeArraySizeException("The BitVector must have a non-negative size");
174 if (filling && (length % 32) != 0)
175 v[v.length - 1] ^= all_1 << (length % 32);
176 if ((size + 31) / 32 != v.length) {
177 int[] new_v = new int[(size + 31) / 32];
178 int i;
179 for (i = 0; i < new_v.length && i < v.length; i++)
180 new_v[i] = v[i];
181 for (; i < new_v.length; i++)
182 new_v[i] = filling ? all_1 : 0;
183 v = new_v;
184 }
185 length = size;
186
187 // the extra bits must be set at zero
188 v[v.length - 1] &= (all_1 >>> (31 - (length - 1) % 32));
189 }
190
197 public void enlarge(int size) {
198 enlarge(size, false);
199 }
200
211 public boolean getBool(int pos) {
212 if (pos < 0 || pos >= length)
213 throw new ArrayIndexOutOfBoundsException(pos);
214 return (v[pos >>> 5] & (one_1 << (pos & 31))) != 0;
215 }
216
226 public void setBool(int pos, boolean value) {
227 if (pos > length || pos < 0)
228 throw new ArrayIndexOutOfBoundsException(pos);
229 if (value)
230 v[pos / 32] |= (one_1 << (pos % 32));
231 else
232 v[pos / 32] &= (one_1 << (pos % 32)) ^ all_1;
233 }
234
245 public int getInt(int pos) {
246 if (pos >= v.length || pos < 0)
247 throw new ArrayIndexOutOfBoundsException(pos);
248 return v[pos];
249 }
250
258 public String toString() {
259 StringBuffer sb = new StringBuffer();
260
261 for (int i = length - 1; i > 0; i--)
262 sb.append(getBool(i) ? "1" : "0").append(i % 8 == 0 ? " " : "");
263 sb.append(getBool(0) ? "1" : "0");
264
265 return sb.toString();
266 }
267
276 public BitVector not() {
277 BitVector bv = new BitVector(length);
278 for (int i = 0; i < v.length; i++)
279 bv.v[i] = v[i] ^ all_1;
280
281 // the extra bits must be set at zero
282 bv.v[v.length - 1] &= (all_1 >>> (31 - (length - 1) % 32));
283
284 return bv;
285 }
286
293 for (int i = 0; i < v.length; i++)
294 v[i] = v[i] ^ all_1;
295
296 // the extra bits must be set at zero
297 v[v.length - 1] &= (all_1 >>> (31 - (length - 1) % 32));
298
299 return this;
300 }
301
312 public BitVector xor(BitVector that) {
313 // we always consider that this is longer than that
314 if (that.length > this.length)
315 return that.xor(this);
316
317 BitVector bv = new BitVector(this.length);
318
319 int max = this.v.length;
320 int min = that.v.length;
321
322 for (int i = 0; i < min; i++)
323 bv.v[i] = this.v[i] ^ that.v[i];
324 for (int i = min; i < max; i++)
325 bv.v[i] = this.v[i];
326
327 return bv;
328 }
329
338 // we assume that this is large enough to contain that
339 if (this.length < that.length)
340 this.enlarge(that.length);
341
342 int min = that.v.length;
343
344 for (int i = 0; i < min; i++)
345 this.v[i] ^= that.v[i];
346
347 return this;
348 }
349
359 public BitVector and(BitVector that) {
360 // we always consider this as longer than that
361 if (that.length > this.length)
362 return that.and(this);
363
364 BitVector bv = new BitVector(this.length);
365
366 int max = this.v.length;
367 int min = that.v.length;
368
369 for (int i = 0; i < min; i++)
370 bv.v[i] = this.v[i] & that.v[i];
371 if (that.length % 32 != 0)
372 bv.v[min - 1] |= this.v[min - 1] & (all_1 << (that.length % 32));
373 for (int i = min; i < max; i++)
374 bv.v[i] = 0;
375
376 return bv;
377 }
378
387 // we assume that this is large enough to contain that
388 if (this.length < that.length)
389 this.enlarge(that.length, true);
390
391 int min = that.v.length;
392
393 for (int i = 0; i < min - 1; i++)
394 this.v[i] &= that.v[i];
395 this.v[min - 1] &= (that.v[min - 1] | (all_1 << (that.length % 32)));
396
397 return this;
398 }
399
409 public BitVector or(BitVector that) {
410 // we always consider this is longer than that
411 if (that.length > this.length)
412 return that.or(this);
413
414 BitVector bv = new BitVector(this.length);
415
416 int max = this.v.length;
417 int min = that.v.length;
418
419 for (int i = 0; i < min; i++)
420 bv.v[i] = this.v[i] | that.v[i];
421 for (int i = min; i < max; i++)
422 bv.v[i] = 0;
423
424 return bv;
425 }
426
435 // we assume that this is large enough to contain that
436 if (this.length < that.length)
437 this.enlarge(that.length);
438
439 int min = that.v.length;
440
441 for (int i = 0; i < min; i++)
442 this.v[i] |= that.v[i];
443
444 return this;
445 }
446
457 public BitVector shift(int j) {
458 BitVector bv = new BitVector(length);
459
460 if (j == 0)
461 return bv;
462 else if (j > 0) {
463 int a = j / 32;
464 int b = j % 32;
465 int c = 32 - b;
466
467 int i;
468 for (i = 0; i + a < v.length; i++)
469 bv.v[i] = v[i + a] >>> b;
470 // la retenue
471 for (i = 0; i + a + 1 < v.length; i++)
472 bv.v[i] ^= v[i + a + 1] << c;
473 } else // if(j < 0)
474 {
475 j = -j;
476 int a = j / 32;
477 int b = j % 32;
478 int c = 32 - b;
479
480 int i;
481 for (i = a; i < v.length; i++)
482 bv.v[i] ^= v[i - a] << b;
483 // la retenue
484 for (i = a + 1; i < v.length; i++)
485 bv.v[i] ^= v[i - a - 1] >>> c;
486 }
487
488 return bv;
489 }
490
499 public BitVector selfShift(int j) {
500 if (j == 0)
501 return this;
502 else if (j > length || j < -length) {
503 for (int i = 0; i < v.length; i++)
504 v[i] = 0;
505 } else if (j > 0) {
506 int a = j / 32;
507 int b = j % 32;
508 int c = 32 - b;
509
510 int i;
511 for (i = 0; i + a + 1 < v.length; i++) {
512 v[i] = v[i + a] >>> b;
513 // la retenue
514 v[i] ^= v[i + a + 1] << c;
515 }
516 v[i] = v[i + a] >>> b;
517 for (i += 1; i < v.length; i++)
518 v[i] = 0;
519 } else // if(j < 0)
520 {
521 j = -j;
522 int a = j / 32;
523 int b = j % 32;
524 int c = 32 - b;
525
526 int i;
527 for (i = v.length - 1; i > a; i--) {
528 v[i] = v[i - a] << b;
529 // la retenue
530 v[i] ^= v[i - a - 1] >>> c;
531 }
532 v[i] = v[i - a] << b;
533 for (i -= 1; i >= 0; i--)
534 v[i] = 0;
535 }
536
537 return this;
538 }
539
549 public boolean scalarProduct(BitVector that) {
550 // we must take that is not longer than this
551 if (that.v.length > this.v.length)
552 return that.scalarProduct(this);
553
554 boolean result = false;
555 int prod;
556
557 for (int i = 0; i < that.v.length; i++) {
558 prod = this.v[i] & that.v[i];
559 while (prod != 0) {
560 // a chaque iteration, on enleve le 1 le plus a droite
561 prod &= prod - 1;
562 result = !result;
563 }
564 }
565
566 return result;
567 }
568
569}
int getInt(int pos)
Returns an int containing all the bits in the interval.
Object clone()
Creates a copy of the BitVector.
BitVector selfNot()
Applies the not operator on the current BitVector and returns it.
boolean equals(BitVector that)
Verifies if two BitVector’s have the same length and the same data.
BitVector(int length)
Creates a new BitVector of length length with all its bits set to 0.
BitVector selfXor(BitVector that)
Applies the xor operator on this with that.
void enlarge(int size)
Resizes the BitVector so that its length is equal to size.
BitVector(int[] vect)
Creates a new BitVector using the data in vect.
int size()
Returns the length of the BitVector.
BitVector xor(BitVector that)
Returns a BitVector which is the result of the xor operator applied on this and that.
BitVector shift(int j)
Returns a BitVector equal to the original with all the bits shifted j positions to the right if j is ...
boolean scalarProduct(BitVector that)
Returns the scalar product of two BitVector’s modulo 2.
BitVector selfShift(int j)
Shift all the bits of the current BitVector j positions to the right if j is positive,...
BitVector and(BitVector that)
Returns a BitVector which is the result of the and operator with both the this and that BitVector’s.
void enlarge(int size, boolean filling)
Resizes the BitVector so that its length is equal to size.
String toString()
Returns a string containing all the bits of the BitVector, starting with the highest order bit and fi...
boolean getBool(int pos)
Gives the value of the bit in position pos.
void setBool(int pos, boolean value)
Sets the value of the bit in position pos.
BitVector selfOr(BitVector that)
Applies the or operator on this with that.
BitVector or(BitVector that)
Returns a BitVector which is the result of the or operator with both the this and that BitVector’s.
BitVector not()
Returns a BitVector which is the result of the not operator on the current BitVector.
BitVector selfAnd(BitVector that)
Applies the and operator on this with that.
BitVector(BitVector that)
Creates a copy of the BitVector that.
BitVector(int[] vect, int length)
Creates a new BitVector of length length using the data in vect.