public boolean check(final LongArrayBitVector solutions) { assert solutions.length() == numVars * 2; final long[] solutionBits = solutions.bits(); for(final Modulo3Equation equation: equations) if (equation.c != Modulo3Equation.scalarProduct(equation.bits, solutionBits) % 3) return false; return true; }
@Override public BitVector toBitVector(final CharSequence cs) { final String s = cs.toString(); final int length = s.length(); final LongArrayBitVector bitVector = LongArrayBitVector.getInstance(length(s)); for (int i = 0, cp; i < length; i += Character.charCount(cp)) bitVector.append(cp = s.codePointAt(i), Integer.SIZE); return bitVector; }
/** Creates a new equation. * * @param c the constant term. * @param numVars the number of variables. */ public Modulo3Equation(final long c, final int numVars) { this.c = c; this.bitVector = LongArrayBitVector.ofLength(numVars * 2); this.bits = bitVector.bits(); this.list = bitVector.asLongBigList(2); this.firstVar = Integer.MAX_VALUE; this.isEmpty = true; }
protected Modulo3Equation(final Modulo3Equation equation){ this.c = equation.c; this.bitVector = equation.bitVector.copy(); this.bits = this.bitVector.bits(); this.list = this.bitVector.asLongBigList(2); this.firstVar = equation.firstVar; this.firstCoeff = equation.firstCoeff; this.isEmpty = equation.isEmpty; }
/** Creates a new bit vector with given bits. * * @param bit a list of bits that will be set in the newly created bit vector. */ public static LongArrayBitVector of( final int... bit ) { final LongArrayBitVector bitVector = new LongArrayBitVector( bit.length ); for( int b : bit ) bitVector.add( b ); return bitVector; }
LongArrayBitVector prev = LongArrayBitVector.copy(transform.toBitVector(iterator.next())), curr = LongArrayBitVector.getInstance(), temp; if (DEBUG) System.err.println(prev); pl.lightUpdate(); totalLength = maxLength = prev.length(); curr.replace(transform.toBitVector(iterator.next())); if (DEBUG) System.err.println(curr); pl.lightUpdate(); if (maxLength < curr.length()) maxLength = curr.length(); totalLength += curr.length(); prefix = (int)curr.longestCommonPrefixLength(prev); if (prefix == prev.length() && prefix == curr.length()) throw new IllegalArgumentException("The input bit vectors are not distinct"); if (prefix == prev.length() || prefix == curr.length()) throw new IllegalArgumentException("The input bit vectors are not prefix-free"); if (prev.getBoolean(prefix)) throw new IllegalArgumentException("The input bit vectors are not lexicographically sorted"); long skipSize = 0; do { reprSize += n.repr.length() + 2; skipSize += n.skips.size64() + 1; } while ((n = n.right) != null); newNode.repr.ensureCapacity(reprSize); newNode.skips.ensureCapacity(skipSize); newNode.repr.add(true); newNode.repr.append(n.repr); newNode.repr.add(false); newNode.skips.add(n.skip);
rankers.add(LongArrayBitVector.copy(bv.subVector(0, bv.lastOne() + 1))); rankers.add(LongArrayBitVector.copy(bv).append(1, 1)); final LongArrayBitVector plus1 = LongArrayBitVector.copy(bv); final long lastZero = plus1.lastZero(); if (lastZero != -1) { plus1.length(lastZero + 1); plus1.set(lastZero); rankers.add(plus1); final LongArrayBitVector leavesBitVector = LongArrayBitVector.ofLength(rankerArray.length); int q = 0; for(final BitVector v : rankerArray) { while(bv != null) { cmp = bv.compareTo(v); if (cmp == 0) leavesBitVector.set(q); if (cmp >= 0) break; bv = delimiterIterator.hasNext() ? delimiterIterator.next() : null;
final long numSmall = minCostSmall / (minIndex + 1); final long numLarge = minCostLarge / width; (small = LongArrayBitVector.getInstance().asLongBigList(minIndex)).size(numSmall); (marker = LongArrayBitVector.getInstance()).length(length); (large = LongArrayBitVector.getInstance().asLongBigList(width)).size(numLarge); (small = LongArrayBitVector.getInstance().asLongBigList(minIndex)).size(length); marker = null; large = null; else { large.set(q++, value); marker.set(i); numBits = small.size64() * minIndex + (marker != null ? rank.numBits() + marker.length() + large.size64() * width : 0); if (ASSERTS) { final LongIterator t = elements.iterator();
/** Returns the bit vector indexed; since the bits are not stored in this data structure, * a copy is built on purpose and returned. * * <p><strong>Warning</strong>: this method is very slow, as the only way to recover the original bit * array is to rank each position in the bit vector. * * @return a copy of the underlying bit vector. */ @Override public BitVector bitVector() { final LongArrayBitVector result = LongArrayBitVector.getInstance().length(n); long prev = 0, rank; for(long i = 1; i <= n; i++) { if ((rank = rank(i)) != prev) result.set(i - 1); prev = rank; } return result; } }
/** Creates a new shift-add-xor signed string map using a given hash map. * * @param iterator an iterator enumerating a set of strings. * @param map a minimal perfect hash for the strings enumerated by <code>iterator</code>; it must support {@link Function#size() size()} * and have default return value -1. * @param signatureWidth the width, in bits, of the signature of each string. */ public ShiftAddXorSignedStringMap( final Iterator<? extends CharSequence> iterator, final Object2LongFunction<? extends CharSequence> map, final int signatureWidth ) { CharSequence s; this.function = map; this.width = signatureWidth; this.defRetValue = -1; shift = Long.SIZE - width; mask = width == Long.SIZE ? 0 : ( 1L << width ) - 1; final int n = map.size(); signatures = LongArrayBitVector.getInstance().asLongBigList( signatureWidth ).length( n ); for( int i = 0; i < n; i++ ) { s = iterator.next(); signatures.set( map.getLong( s ), signature( s ) ); } if ( iterator.hasNext() ) throw new IllegalStateException( "Iterator provides more than " + n + " elements" ); }
offsetAndSeed = new long[numChunks + 1]; final OfflineIterable<BitVector, LongArrayBitVector> offlineData = new OfflineIterable<>(BitVectors.OFFLINE_SERIALIZER, LongArrayBitVector.getInstance()); final LongArrayBitVector data = LongArrayBitVector.getInstance(); final long[] solution = solver.solution; data.length(solution.length); for (int j = 0; j < solution.length; j++) data.set(j, (int)solution[j]); final LongArrayBitVector dataBitVector = LongArrayBitVector.getInstance(); this.data = dataBitVector; final OfflineIterator<BitVector, LongArrayBitVector> iterator = offlineData.iterator(); while (iterator.hasNext()) dataBitVector.append(iterator.next()); iterator.close(); offlineData.close();
void labelIntermediateTrie(final Node node, final LongArrayBitVector path, final OfflineIterable<BitVector, LongArrayBitVector> delimiters, final OfflineIterable<BitVector, LongArrayBitVector> representations, final OfflineIterable<BitVector, LongArrayBitVector> keys, final LongBigList internalNodeSignatures, final long seed, final boolean left) throws IOException { assert (node.left != null) == (node.right != null); final long parentPathLength = Math.max(0, path.length() - 1); if (node.left != null) { path.append(node.path); labelIntermediateTrie(node.left, path.append(0, 1), delimiters, representations, keys, internalNodeSignatures, seed, true); path.removeBoolean((int)(path.length() - 1)); final long h = Hashes.spooky4(path, seed); final long p = (-1L << Fast.mostSignificantBit(parentPathLength ^ path.length()) & path.length()); assert p <= path.length() : p + " > " + path.length(); assert path.length() == 0 || p > parentPathLength : p + " <= " + parentPathLength; keys.add(LongArrayBitVector.copy(path.subVector(0, p))); representations.add(path.copy()); assert Fast.length(path.length()) <= logW; if (DDDEBUG) System.err.println("Entering " + path + " with key (" + p + "," + path.subVector(0, p).hashCode() + ") " + path.subVector(0, p) + ", signature " + (h & signatureMask) + " and length " + (path.length() & logWMask) + "(value: " + ((h & signatureMask) << logW | (path.length() & logWMask)) + ")"); internalNodeSignatures.add((h & signatureMask) << logW | (path.length() & logWMask)); labelIntermediateTrie(node.right, path.append(1, 1), delimiters, representations, keys, internalNodeSignatures, seed, false); path.length(path.length() - node.path.length() - 1); } else { if (left) delimiters.add(LongArrayBitVector.copy(path.subVector(0, path.lastOne() + 1))); else delimiters.add(LongArrayBitVector.copy(path)); } }
@Override public String toString() { final StringBuilder b = new StringBuilder(); boolean someNonZero = false; for(int i = 0; i < bitVector.length(); i++) { if (bitVector.getBoolean(i)) { if (someNonZero) b.append(" + "); someNonZero = true; b.append("x_").append(i); } } if (! someNonZero) b.append('0'); return b.append(" = ").append(c).toString(); }
public boolean removeBoolean( final long index ) { if ( CHECKS ) ensureRestrictedIndex( index ); final boolean oldValue = getBoolean( index ); final long[] bits = this.bits; final int word = word( index ); final int bit = bit( index ); bits[ word ] = ( bits[ word ] & - ( 1L << bit ) << 1 ) >>> 1 | bits[ word ] & ( 1L << bit ) - 1; final int numWords = numWords( length-- ); for( int i = word + 1; i < numWords; i++ ) { if ( ( bits[ i ] & 1 ) != 0 ) bits[ i - 1 ] |= LAST_BIT_MASK; bits[ i ] >>>= 1; } return oldValue; }
public void add( final long index, final boolean value ) { if ( CHECKS ) ensureIndex( index ); if ( length == bits.length << LOG2_BITS_PER_WORD ) bits = LongArrays.grow( bits, numWords( length + 1 ) ); length++; if ( index == length - 1 ) set( index, value ); else { final int word = word( index ); final int bit = bit( index ); boolean carry = ( bits[ word ] & LAST_BIT_MASK ) != 0, nextCarry; long t = bits[ word ]; if ( bit == LAST_BIT ) t &= ~LAST_BIT_MASK; else t = ( t & - ( 1L << bit ) ) << 1 | t & ( 1L << bit ) - 1; if ( value ) t |= 1L << bit; bits[ word ] = t; final int numWords = numWords( length ); for( int i = word + 1; i < numWords; i++ ) { nextCarry = ( bits[ i ] & LAST_BIT_MASK ) != 0; bits[ i ] <<= 1; if ( carry ) bits[ i ] |= 1; carry = nextCarry; } } return; }
public void dump(final String file) throws IOException { final ByteBuffer buffer = ByteBuffer.allocateDirect(offsetAndSeed.length * 8 + 40).order(ByteOrder.nativeOrder()); final FileOutputStream fos = new FileOutputStream(file); final FileChannel channel = fos.getChannel(); buffer.clear(); buffer.putLong(size64()); buffer.putLong(width); buffer.putLong(chunkShift); buffer.putLong(globalSeed); buffer.putLong(offsetAndSeed.length); for(final long l : offsetAndSeed) buffer.putLong(l); buffer.flip(); channel.write(buffer); buffer.clear(); final LongArrayBitVector v = LongArrayBitVector.getInstance().ensureCapacity(data.size64() * width); for(final long d: data) v.append(d, width); final long[] array = v.bits(); buffer.putLong(array.length); for(final long l: array) { if (!buffer.hasRemaining()) { buffer.flip(); channel.write(buffer); buffer.clear(); } buffer.putLong(l); } buffer.flip(); channel.write(buffer); fos.close(); }
/** Solves the system using Gaussian elimination and write the solution * in a bit vector. * * @param solution a bit vector where the solution will be written using * two bits per value. * @return true if the system is solvable. */ public boolean gaussianElimination(final LongArrayBitVector solution) { assert solution.length() == numVars * 2; for (final Modulo3Equation equation: equations) equation.updateFirstVar(); if (! echelonForm()) return false; final long[] solutionBits = solution.bits(); final LongBigList solutionList = solution.asLongBigList(2); for (int i = equations.size(); i-- != 0;) { final Modulo3Equation equation = equations.get(i); if (equation.isIdentity()) continue; assert solutionList.getLong(equation.firstVar) == 0 : equation.firstVar; long sum = (equation.c - Modulo3Equation.scalarProduct(equation.bits, solutionBits)) % 3; if (sum < 0) sum += 3; solutionList.set(equation.firstVar, sum == 0 ? 0 : equation.firstCoeff == sum ? 1 : 2); } return true; } /** Solves the system using lazy Gaussian elimination.
l = length == 0 ? 0 : Math.max(0, Fast.mostSignificantBit(upperBound / length)); final long lowerBitsMask = (1L << l) - 1; final LongBigList lowerBitsList = LongArrayBitVector.getInstance().asLongBigList(l); lowerBitsList.size(length); final BitVector upperBitsVector = LongArrayBitVector.getInstance().length(length + (upperBound >>> l) + 1); long v = 0; for(int i = 0; i < length; i++) {
/** Creates a new Bloom filter with given number of hash functions and expected number of elements. * * @param n the expected number of elements. * @param d the number of hash functions; if the filter add not more than <code>n</code> elements, * false positives will happen with probability 2<sup>-<var>d</var></sup>. */ public IntBloomFilter( final int n, final int d ) { this.d = d; bits = LongArrayBitVector.getInstance().length( (long)Math.ceil( ( n * d / NATURAL_LOG_OF_2 ) ) ); m = bits.length() * Long.SIZE; if ( DEBUG ) System.err.println( "Number of bits: " + m ); // The purpose of Random().nextInt() is to generate a different seed at each invocation. final MersenneTwister mersenneTwister = new MersenneTwister( new Random().nextInt() ); a = new int[ d ]; b = new int[ d ]; for( int i = 0; i < d; i++ ) { a[ i ] = mersenneTwister.nextInt(); b[ i ] = mersenneTwister.nextInt(); } }