/// <summary> /// Applies a procedure to each coordinate that holds a bit in the given state. /// Iterates rowwise downwards from [columns()-1,rows()-1] to [0,0]. /// Useful, for example, if you want to copy bits into an image or somewhere else. /// Optimized for speedd Particularly quick if one of the following conditions holds /// <ul> /// <li><i>state==true</i> and the receiver is sparse (<i>cardinality()</i> is small compared to <i>Size</i>). /// <li><i>state==false</i> and the receiver is dense (<i>cardinality()</i> is large compared to <i>Size</i>). /// </ul> /// </summary> /// <param name="state">element to search for.</param> /// <param name="procedure">a procedure object taking as first argument the current column and as second argument the current rowd Stops iteration if the procedure returns <i>false</i>, otherwise continuesd </param> /// <returns><i>false</i> if the procedure stopped before all elements where iterated over, <i>true</i> otherwised </returns> public Boolean ForEachCoordinateInState(Boolean state, Cern.Colt.Function.IntIntProcedure procedure) { /* * this is equivalent to the low level version below, apart from that it iterates in the reverse oder and is slower. * if (Size==0) return true; * BitVector vector = toBitVector(); * return vector.forEachIndexFromToInState(0,Size-1,state, * new cern.colt.function.IntFunction() { * public Boolean apply(int index) { * return function.apply(index%columns, index/columns); * } * } * ); */ //low level implementation for speed. if (Size == 0) { return(true); } BitVector vector = new BitVector(_bits, Size); long[] theBits = _bits; int column = _columns - 1; int row = _rows - 1; // for each coordinate of bits of partial unit long val = theBits[_bits.Length - 1]; for (int j = vector.NumberOfBitsInPartialUnit(); --j >= 0;) { long mask = val & (1L << j); if ((state && (mask != 0L)) || ((!state) && (mask == 0L))) { if (!procedure(column, row)) { return(false); } } if (--column < 0) { column = _columns - 1; --row; } } // for each coordinate of bits of full units int bitsPerUnit = QuickBitVector.BITS_PER_UNIT; long comparator; if (state) { comparator = 0L; } else { comparator = ~0L; // all 64 bits set } for (int i = vector.NumberOfFullUnits(); --i >= 0;) { val = theBits[i]; if (val != comparator) { // at least one element within current unit matches. // iterate over all bits within current unit. if (state) { for (int j = bitsPerUnit; --j >= 0;) { if (((val & (1L << j))) != 0L) { if (!procedure(column, row)) { return(false); } } if (--column < 0) { column = _columns - 1; --row; } } } else { // unrolled comparison for speed. for (int j = bitsPerUnit; --j >= 0;) { if (((val & (1L << j))) == 0L) { if (!procedure(column, row)) { return(false); } } if (--column < 0) { column = _columns - 1; --row; } } } } else { // no element within current unit matches --> skip unit column -= bitsPerUnit; if (column < 0) { // avoid implementation with *, /, % column += bitsPerUnit; for (int j = bitsPerUnit; --j >= 0;) { if (--column < 0) { column = _columns - 1; --row; } } } } } return(true); }