private void appendFill(int nWords, int v) { if (vec.isEmpty()) { if (v == 0) { vec.add(HEADER0 | nWords); } else { vec.add(HEADER1 | nWords); } } else if (nWords > 1) { int back = getBack(); if (v == 0) { if (isZeroFill(back)) { setBack(back + nWords); } else { vec.add(HEADER0 | nWords); } } else if (isOneFill(back)) { setBack(back + nWords); } else { vec.add(HEADER1 | nWords); } } else { active.val = v != 0 ? ALLONES : 0; appendLiteral(); } }
/** * Checks if the bit is set in the compressed bitset. * * <p>This operation is considerably slower than the uncompressed version. Use it with care. * * @param i the index where bit is checked. * @return true if the index is set, false otherwise. */ public boolean get(int i) { if (i > numBits()) { // no-way return false; } else { // we have to do hard way for (int j = 0; j < vec.size() && i >= 0; j++) { int v = vec.getQuick(j); // for a fill, we know easily. if (isAFill(v)) { int size = (v & MAXCNT) * MAXBITS; if (i < size) return isOneFill(v); i -= size; } else { // plain value. if (i < MAXBITS) { // do we need to check? return (1 << (MAXBITS - i - 1) & v) != 0; } else { // yet to get there. i -= MAXBITS; } } } // we need to check the active word. if (i >= 0) { return (moreThanInUnsigned(active.val << (MAXBITS + 1 - active.nbits + i), ALLONES)); } } return false; }
// Remplit les cycles avec le generateur LFSR. // Le nombre de valeurs dans l'ensemble des cycles est de 2^(k1+k2). // Cette methode fonctionne pour tous les polynomes, meme ceux dont // la periode n'est pas maximale. private void fillCyclesLFSR() { int n = 1 << (k1 + k2); // Nombre de points dans l'ensemble. IntArrayList c; // Array used to store the current cycle. int i; boolean stateVisited[] = new boolean[n]; // Indicates which states have been visited so far. for (i = 0; i < n; i++) stateVisited[i] = false; int startState = 0; // First state of the cycle currently considered. numPoints = 0; while (startState < n) { stateVisited[startState] = true; c = new IntArrayList(); c.add(value); nextState(); while (state != startState) { stateVisited[state] = true; c.add(value); nextState(); } addCycle(c); // System.out.println("Size of Cycle: " + c.size()); for (i = startState + 1; i < n; i++) if (stateVisited[i] == false) break; startState = i; validateState(i); } }
/** * Fills all values contained in the receiver into the specified list. Fills the list, starting at * index 0. After this call returns the specified list has a new size that equals * <tt>this.size()</tt>. Iteration order is guaranteed to be <i>identical</i> to the order used by * method {@link #forEachKey(DoubleProcedure)}. * * <p>This method can be used to iterate over the values of the receiver. * * @param list the list to be filled, can have any size. */ public void values(IntArrayList list) { list.setSize(distinct); int[] elements = list.elements(); int[] val = values; byte[] stat = state; int j = 0; for (int i = stat.length; i-- > 0; ) { if (stat[i] == FULL) elements[j++] = val[i]; } }
/** * Fills all pairs satisfying a given condition into the specified lists. Fills into the lists, * starting at index 0. After this call returns the specified lists both have a new size, the * number of pairs satisfying the condition. Iteration order is guaranteed to be <i>identical</i> * to the order used by method {@link #forEachKey(DoubleProcedure)}. * * <p><b>Example:</b> <br> * * <pre> * DoubleIntProcedure condition = new DoubleIntProcedure() { // match even values only * public boolean apply(double key, int value) { return value%2==0; } * } * keys = (8,7,6), values = (1,2,2) --> keyList = (6,8), valueList = (2,1)</tt> * </pre> * * @param condition the condition to be matched. Takes the current key as first and the current * value as second argument. * @param keyList the list to be filled with keys, can have any size. * @param valueList the list to be filled with values, can have any size. */ public void pairsMatching( final DoubleIntProcedure condition, final DoubleArrayList keyList, final IntArrayList valueList) { keyList.clear(); valueList.clear(); for (int i = table.length; i-- > 0; ) { if (state[i] == FULL && condition.apply(table[i], values[i])) { keyList.add(table[i]); valueList.add(values[i]); } } }
private void appendLiteral() { if (vec.size() == 0) { vec.add(active.val); } else { int back = vec.getQuick(vec.size() - 1); if (active.val == 0) { // incoming word is zero if (back == 0) { setBack(HEADER0 + 2); } else if (isZeroFill(back)) { setBack(++back); } else { vec.add(active.val); } } else if (active.val == ALLONES) { // incoming word is allones if (back == ALLONES) { setBack((HEADER1 | 2)); } else if (isOneFill(back)) { setBack(++back); } else { vec.add(active.val); } } else { // incoming word contains a mixture of bits vec.add(active.val); } } nbits += MAXBITS; active.reset(); nset = 0; }
private int doCount() { nset = 0; nbits = 0; for (int i = 0; i < vec.size(); i++) { int v = vec.getQuick(i); if (!isAFill(v)) { nbits += MAXBITS; nset += Integer.bitCount(v); } else { int tmp = (v & MAXCNT) * MAXBITS; nbits += tmp; nset += tmp * (isOneFill(v) ? 1 : 0); } } return nbits; }
/** * Returns the number of 1 bits in the bitset. * * @return the number of 1 bits in the bitset. */ public int cardinality() { // check the cardinality, again if it has been reset. if (nset == 0 && !vec.isEmpty()) { doCount(); } // the sizes in the vector and the active word. return nset + Integer.bitCount(active.val); }
private WAHBitSet genericOp(OpType op, WAHBitSet other) { WAHBitSet ret = new WAHBitSet(); // ensure that they have the same bit length. if (this.numBits() < other.numBits()) { this.setBit(other.numBits() - 1, 0); } else if (this.numBits() > other.numBits()) { other.setBit(numBits() - 1, 0); } if (vec.size() > 0) { run xrun = new run(vec), yrun = new run(other.vec); xrun.decode(); yrun.decode(); do { if (xrun.nWords == 0) { xrun.inc(); xrun.decode(); } if (yrun.nWords == 0) { yrun.inc(); yrun.decode(); } if (xrun.isFill()) { if (yrun.isFill()) { int nWords = Math.min(xrun.nWords, yrun.nWords); ret.appendFill(nWords, getOpResult(op, xrun.fillWord, yrun.fillWord)); xrun.nWords -= nWords; yrun.nWords -= nWords; } else { ret.active.val = getOpResult(op, xrun.fillWord, yrun.get()); ret.appendLiteral(); --xrun.nWords; yrun.nWords = 0; } } else if (yrun.isFill()) { ret.active.val = getOpResult(op, yrun.fillWord, xrun.get()); ret.appendLiteral(); yrun.nWords--; xrun.nWords = 0; } else { ret.active.val = getOpResult(op, xrun.get(), yrun.get()); ret.appendLiteral(); yrun.nWords = 0; xrun.nWords = 0; } } while (!(xrun.end() && yrun.end())); } ret.active.val = getOpResult(op, this.active.val, other.active.val); ret.active.nbits = this.active.nbits; ret.doCount(); return ret; }
public void decode() { int v = vec.get(idx); if (WAHBitSet.isAFill(v)) { fillWord = (isOneFill(v) ? ALLONES : 0); nWords = v & MAXCNT; fill = true; } else { nWords = 1; fill = false; } }
private void appendCounter(int val, int cnt) { int head = 2 + val; int w = (head << SECONDBIT) + cnt; nbits += cnt * MAXBITS; if (vec.isEmpty()) { vec.add(w); } else { int back = getBack(); if ((back >>> SECONDBIT) == head) { back += cnt; setBack(back); } else if ((back == ALLONES) && head == 3) { setBack(w + 1); } else if ((back == 0) && head == 2) { setBack(w + 1); } else { vec.add(w); } } }
/** * This is an optimization over the and function. This does not create new bitset. This just * counts the number of 1 bits common between the two bitsets. * * @param other the bitset to and with. * @return the number of 1s common between two bitsets. */ public int andSize(WAHBitSet other) { int size = 0; // ensure that they have the same bit length. if (this.numBits() < other.numBits()) { this.setBit(other.numBits() - 1, 0); } else if (this.numBits() > other.numBits()) { other.setBit(numBits() - 1, 0); } if (vec.size() > 0) { run xrun = new run(vec), yrun = new run(other.vec); xrun.decode(); yrun.decode(); do { if (xrun.nWords == 0) { xrun.inc(); xrun.decode(); } if (yrun.nWords == 0) { yrun.inc(); yrun.decode(); } if (xrun.isFill()) { if (yrun.isFill()) { int nWords = Math.min(xrun.nWords, yrun.nWords); if ((xrun.fillWord & yrun.fillWord) == 1) { size += nWords * MAXBITS; } xrun.nWords -= nWords; yrun.nWords -= nWords; } else { size += countInRun(xrun, yrun); } } else if (yrun.isFill()) { size += countInRun(yrun, xrun); } else { int val = xrun.get() & yrun.get(); if (val > 0) size += Integer.bitCount(val); yrun.nWords = 0; xrun.nWords = 0; } } while (!(xrun.end() && yrun.end())); } size += Integer.bitCount(this.active.val & other.active.val); return size; }
// this function tries to advance the run by nWords // sometimes it is not possible, in that case it returns how much it advanced. public int inc(int nWords) { int orig = nWords; nWords--; while (nWords > 0) { ++idx; int v = vec.get(idx); if (isAFill(v)) { int words = v & MAXCNT; if (words > nWords) { --idx; break; } nWords -= words; } else { nWords--; } } return orig - nWords; }
private void appendCompressed(int v) { vec.add(v); nbits += MAXBITS; nset = 0; }
public boolean end() { return idx >= vec.size() - 1; }
public int get() { return vec.getQuick(idx); }
private void setBack(int val) { vec.setQuick(vec.size() - 1, val); }
/** * Returns the best cut of a graph w.r.t. the degree of dissimilarity between points of different * partitions and the degree of similarity between points of the same partition. * * @param W the weight matrix of the graph * @return an array of two elements, each of these contains the points of a partition */ protected static int[][] bestCut(DoubleMatrix2D W) { int n = W.columns(); // Builds the diagonal matrices D and D^(-1/2) (represented as their diagonals) DoubleMatrix1D d = DoubleFactory1D.dense.make(n); DoubleMatrix1D d_minus_1_2 = DoubleFactory1D.dense.make(n); for (int i = 0; i < n; i++) { double d_i = W.viewRow(i).zSum(); d.set(i, d_i); d_minus_1_2.set(i, 1 / Math.sqrt(d_i)); } DoubleMatrix2D D = DoubleFactory2D.sparse.diagonal(d); // System.out.println("DoubleMatrix2D :\n"+D.toString()); DoubleMatrix2D X = D.copy(); // System.out.println("DoubleMatrix2D copy :\n"+X.toString()); // X = D^(-1/2) * (D - W) * D^(-1/2) X.assign(W, Functions.minus); // System.out.println("DoubleMatrix2D X: (D-W) :\n"+X.toString()); for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) X.set(i, j, X.get(i, j) * d_minus_1_2.get(i) * d_minus_1_2.get(j)); // Computes the eigenvalues and the eigenvectors of X EigenvalueDecomposition e = new EigenvalueDecomposition(X); DoubleMatrix1D lambda = e.getRealEigenvalues(); // Selects the eigenvector z_2 associated with the second smallest eigenvalue // Creates a map that contains the pairs <index, eigenvalue> AbstractIntDoubleMap map = new OpenIntDoubleHashMap(n); for (int i = 0; i < n; i++) map.put(i, Math.abs(lambda.get(i))); IntArrayList list = new IntArrayList(); // Sorts the map on the value map.keysSortedByValue(list); // Gets the index of the second smallest element int i_2 = list.get(1); // y_2 = D^(-1/2) * z_2 DoubleMatrix1D y_2 = e.getV().viewColumn(i_2).copy(); y_2.assign(d_minus_1_2, Functions.mult); // Creates a map that contains the pairs <i, y_2[i]> map.clear(); for (int i = 0; i < n; i++) map.put(i, y_2.get(i)); // Sorts the map on the value map.keysSortedByValue(list); // Search the element in the map previuosly ordered that minimizes the cut // of the partition double best_cut = Double.POSITIVE_INFINITY; int[][] partition = new int[2][]; // The array v contains all the elements of the graph ordered by their // projection on vector y_2 int[] v = list.elements(); // For each admissible splitting point i for (int i = 1; i < n; i++) { // The array a contains all the elements that have a projection on vector // y_2 less or equal to the one of i-th element // The array b contains the remaining elements int[] a = new int[i]; int[] b = new int[n - i]; System.arraycopy(v, 0, a, 0, i); System.arraycopy(v, i, b, 0, n - i); double cut = Ncut(W, a, b, v); if (cut < best_cut) { best_cut = cut; partition[0] = a; partition[1] = b; } } // System.out.println("Partition:"); // UtilsJS.printMatrix(partition); return partition; }
private int getBack() { return vec.getQuick(vec.size() - 1); }
/** * Returns the amount of memory used by the compressed bit set * * @return the amount of memory used by the compressed bit set */ public long memSize() { return vec.size() + 2; }
/** * Returns a new WAH compressed bitset after anding the current bitset with the <i>other</i> * bitset. * * @param other the bitset to and with * @return The resulting bitset */ public WAHBitSet and(WAHBitSet other) { WAHBitSet ret = new WAHBitSet(); // ensure that they have the same bit length. if (this.numBits() < other.numBits()) { this.setBit(other.numBits() - 1, 0); } else if (this.numBits() > other.numBits()) { other.setBit(numBits() - 1, 0); } // if there is something in the vector. if (vec.size() > 0) { // create new run objects and decode them. run xrun = new run(vec), yrun = new run(other.vec); xrun.decode(); yrun.decode(); do { // if you finished a run, then get the next one. if (xrun.nWords == 0) { xrun.inc(); xrun.decode(); } if (yrun.nWords == 0) { yrun.inc(); yrun.decode(); } if (xrun.isFill()) { if (yrun.isFill()) { // both are fills... this is the best. int nWords = Math.min(xrun.nWords, yrun.nWords); ret.appendFill(nWords, xrun.fillWord & yrun.fillWord); xrun.nWords -= nWords; yrun.nWords -= nWords; } else { // just cut through the other run chewUpRun(xrun, ret, yrun); } } else if (yrun.isFill()) { // again do the same, with different order. chewUpRun(yrun, ret, xrun); } else { // both are literals, so get the new literal and // append it to the return value. ret.active.val = xrun.get() & yrun.get(); ret.appendLiteral(); yrun.nWords = 0; xrun.nWords = 0; } // till they are not at the end. } while (!(xrun.end() && yrun.end())); } // set the active word. ret.active.val = this.active.val & other.active.val; ret.active.nbits = this.active.nbits; // ensure that the counts are set properly. ret.doCount(); return ret; }
private void setBit(int ind, int val) { assert val == 0 || val == 1; if (ind >= numBits()) { int diff = ind - numBits() + 1; if (active.nbits > 0) { if (ind + 1 >= nbits + MAXBITS) { diff -= MAXBITS - active.nbits; active.val <<= (MAXBITS - active.nbits); if (diff == 0) active.val += (val != 0 ? 1 : 0); appendLiteral(); } else { active.nbits += diff; active.val <<= diff; active.val += (val != 0 ? 1 : 0); diff = 0; } } if (diff != 0) { int w = diff / MAXBITS; diff -= w * MAXBITS; if (diff != 0) { if (w > 1) { appendCounter(0, w); } else if (w != 0) { appendLiteral(); } active.nbits = diff; active.val += (val != 0 ? 1 : 0); } else if (val != 0) { if (w > 2) { appendCounter(0, w - 1); } else if (w == 2) { appendLiteral(); } active.val = 1; appendLiteral(); } else { if (w > 1) { appendCounter(0, w); } else if (w != 0) { appendLiteral(); } } } if (numBits() != ind + 1) logger.warning("Warning"); if (nset != 0) nset += (val != 0 ? 1 : 0); return; } else if (ind >= nbits) { // modify an active bit int u = active.val; if (val != 0) { active.val |= (1 << (active.nbits - (ind - nbits) - 1)); } else { active.val &= ~(1 << (active.nbits - (ind - nbits) - 1)); } if (nset != 0 && (u != active.val)) nset += (val != 0 ? 1 : -1); return; } else if (vec.size() * MAXBITS == nbits) { // uncompressed int i = ind / MAXBITS; int u = vec.get(i); int w = (1 << (SECONDBIT - (ind % MAXBITS))); if (val != 0) vec.setQuick(i, u |= w); else vec.setQuick(i, u &= ~w); if (nset != 0 && (vec.getQuick(i) != u)) nset += (val != 0 ? 1 : -1); return; } // the code after this has not been verified at all... // should proceed with caution. // compressed bit vector -- // the bit to be modified is in vec if (RUN_UNTESTED_CODE) { int idx = 0; int compressed = 0, cnt = 0, ind1 = 0, ind0 = ind; int current = 0; // current bit value while ((ind0 > 0) && (idx < vec.size())) { int v = vec.getQuick(idx); if (isAFill(v)) { // a fill cnt = ((v) & MAXCNT) * MAXBITS; if (cnt > ind0) { // found the location current = (isOneFill(v) ? 1 : 0); compressed = 1; ind1 = ind0; ind0 = 0; } else { ind0 -= cnt; ind1 = ind0; ++idx; } } else { // a literal word cnt = MAXBITS; if (MAXBITS > ind0) { // found the location current = (1 & ((v) >>> (SECONDBIT - ind0))); compressed = 0; ind1 = ind0; ind0 = 0; } else { ind0 -= MAXBITS; ind1 = ind0; ++idx; } } } // while (ind... if (ind1 == 0) { // set current and compressed int v = vec.getQuick(idx); if (isAFill(v)) { cnt = (v & MAXCNT) * MAXBITS; current = (isOneFill(v) ? 1 : 0); compressed = 1; } else { cnt = MAXBITS; current = (v >>> SECONDBIT); compressed = 0; } } if (ind0 > 0) // has not found the right location yet. { if (ind0 < active.nbits) { // in the active word ind1 = (1 << (active.nbits - ind0 - 1)); if (val != 0) { active.val |= ind1; } else { active.val &= ~ind1; } } else { // extends the current bit vector ind1 = ind0 - active.nbits - 1; appendWord(HEADER0 | (ind1 / MAXBITS)); for (ind1 %= MAXBITS; ind1 > 0; --ind1) addOneBit(0); addOneBit(val != 0 ? 1 : 0); } if (nset != 0) nset += val != 0 ? 1 : -1; return; } // locate the bit to be changed, lots of work hidden here if (current == val) return; // nothing to do int v = vec.getQuick(idx); // need to actually modify the bit if (compressed == 0) { // toggle a single bit of a literal word v ^= (1 << (SECONDBIT - ind1)); vec.setQuick(idx, v); } else if (ind1 < MAXBITS) { // bit to be modified is in the first word, two pieces --v; vec.set(idx, v); if ((v & MAXCNT) == 1) { v = (current != 0) ? ALLONES : 0; vec.setQuick(idx, v); } int w = 1 << (SECONDBIT - ind1); if (val == 0) w ^= ALLONES; vec.beforeInsert(idx, w); idx++; } else if (cnt - ind1 <= MAXBITS) { // bit to be modified is in the last word, two pieces --(v); vec.setQuick(idx, v); if ((v & MAXCNT) == 1) { v = (current != 0) ? ALLONES : 0; vec.setQuick(idx, v); } int w = 1 << (cnt - ind1 - 1); if (val == 0) w ^= ALLONES; ++idx; vec.beforeInsert(idx, w); } else { // the counter breaks into three pieces int u[] = new int[2], w; u[0] = ind1 / MAXBITS; w = (v & MAXCNT) - u[0] - 1; u[1] = 1 << (SECONDBIT - ind1 + u[0] * MAXBITS); if (val == 0) { u[0] = (u[0] > 1) ? (HEADER1 | u[0]) : (ALLONES); u[1] ^= ALLONES; w = (w > 1) ? (HEADER1 | w) : (ALLONES); } else { u[0] = (u[0] > 1) ? (HEADER0 | u[0]) : 0; w = (w > 1) ? (HEADER0 | w) : 0; } vec.setQuick(idx, w); vec.beforeInsertAllOf(idx, Arrays.asList(u)); } if (nset != 0) nset += val != 0 ? 1 : -1; } else { throw new AssertionError("Untested code detected, would rather die than run this"); } }
/** * Parses the provided FSMPDA and converts the old transitions to new ones. The {@link #newStates} * list and the {@link #oldToNewStates} mapping should already be populated before this method is * called. * * @param fsm * @throws ResourceInstantiationException */ protected void createNewTransitions(FSMPDA fsm) throws ResourceInstantiationException { LinkedList<StatePDA> oldStatesQueue = new LinkedList<StatePDA>(); oldStatesQueue.add(fsm.getInitialState()); IntArrayList visitedOldStates = new IntArrayList(); while (oldStatesQueue.size() > 0) { StatePDA anOldState = oldStatesQueue.removeFirst(); if (visitedOldStates.contains(anOldState.getIndex())) { // state already processed -> nothing to do } else { if (!oldToNewStates.containsKey(anOldState.getIndex())) { throw new ResourceInstantiationException( "State mapping org.p4535992.mvc.error: " + "old state not associated with a new state!"); } SPTBase.State newState = newStates.get(oldToNewStates.get(anOldState.getIndex())); // now process all transitions List<SPTBase.Transition> newTransitions = new LinkedList<SPTBase.Transition>(); for (gate.fsm.Transition t : anOldState.getTransitions()) { TransitionPDA anOldTransition = (TransitionPDA) t; if (!visitedOldStates.contains(anOldTransition.getTarget().getIndex())) { oldStatesQueue.add((StatePDA) anOldTransition.getTarget()); } if (!oldToNewStates.containsKey(anOldTransition.getTarget().getIndex())) { throw new ResourceInstantiationException( "State mapping org.p4535992.mvc.error: " + "old target state not associated with a new state!"); } int newStateTarget = oldToNewStates.get(anOldTransition.getTarget().getIndex()); SPTBase.Transition newTransition = new SPTBase.Transition(); newTransitions.add(newTransition); newTransition.nextState = newStateTarget; newTransition.type = anOldTransition.getType(); if (newTransition.type != TransitionPDA.TYPE_CONSTRAINT) { continue; } Constraint[] oldConstraints = anOldTransition.getConstraints().getConstraints(); List<int[]> newConstraints = new ArrayList<int[]>(); for (int i = 0; i < oldConstraints.length; i++) { String annType = oldConstraints[i].getAnnotType(); int annTypeInt = annotationTypes.indexOf(annType); if (annTypeInt < 0) { annotationTypes.add(annType); annTypeInt = annotationTypes.size() - 1; } int[] newConstraint = new int[oldConstraints[i].getAttributeSeq().size() + 2]; newConstraints.add(newConstraint); newConstraint[0] = annTypeInt; newConstraint[1] = oldConstraints[i].isNegated() ? -1 : 0; int predId = 2; for (ConstraintPredicate oldPredicate : oldConstraints[i].getAttributeSeq()) { newConstraint[predId++] = convertPredicate(annType, oldPredicate); } } // now save the new constraints newTransition.constraints = new int[newConstraints.size()][]; newTransition.constraints = newConstraints.toArray(newTransition.constraints); } // convert the transitions list to an array newState.transitions = new SPTBase.Transition[newTransitions.size()]; newState.transitions = newTransitions.toArray(newState.transitions); // finally, mark the old state as visited. visitedOldStates.add(anOldState.getIndex()); } } }