/// <summary> /// Changes the bit with index <i>bitIndex</i> to the "set" (<i>true</i>) state. /// </summary> /// <param name="bitIndex">the index of the bit to be set.</param> /// <exception cref="IndexOutOfRangeException">if <i>bitIndex<0 || bitIndex>=Size</i></exception> public void Set(int bitIndex) { if (bitIndex < 0 || bitIndex >= nbits) { throw new IndexOutOfRangeException(bitIndex.ToString()); } QuickBitVector.Set(bits, bitIndex); }
/// <summary> /// Sets the bit at the specified coordinate to the state specified by <i>value</i>. /// </summary> /// <param name="column">the index of the column-coordinate.</param> /// <param name="row">the index of the row-coordinate.</param> /// <param name="value">the value of the bit to be copied into the specified coordinate.</param> /// <exception cref="IndexOutOfRangeException">if <i>column<0 || column>=columns() || row<0 || row>=rows()</i></exception> public void Put(int column, int row, Boolean value) { if (column < 0 || column >= _columns || row < 0 || row >= _rows) { throw new IndexOutOfRangeException("column:" + column + ", row:" + row); } QuickBitVector.Put(_bits, row * _columns + column, value); }
public Boolean this[int column, int row] { get { return(QuickBitVector.Get(_bits, row * _columns + column)); } set { QuickBitVector.Put(_bits, row * _columns + column, value); } }
/// <summary> /// Sets the bit with index <i>bitIndex</i> to the state specified by <i>value</i>; <b>WARNING:</b> Does not check preconditions. /// /// <p>Provided with invalid parameters this method may set invalid values without throwing any exception. /// <b>You should only use this method when you are absolutely sure that the index is within bounds.</b> /// Precondition (unchecked): <i>bitIndex >= 0 && bitIndex < Size</i>. /// </summary> /// <param name="bitIndex">the index of the bit to be changed.</param> /// <param name="value">the value to be stored in the bit.</param> public void PutQuick(int bitIndex, Boolean value) { if (value) { QuickBitVector.Set(bits, bitIndex); } else { QuickBitVector.Clear(bits, bitIndex); } }
/// <summary> /// Replaces the bits of the receiver in the given range with the bits of another bit vector. /// Replaces the range <i>[from,to]</i> with the contents of the range <i>[sourceFrom,sourceFrom+to-from]</i>, all inclusive. /// If <i>source==this</i> and the source and destination range intersect in an ambiguous way, then replaces as if using an intermediate auxiliary copy of the receiver. /// <p> /// Optimized for speedd Preliminary performance (200Mhz Pentium Pro, JDK 1.2, NT): replace 10^6 ill aligned bits --> 0.02 seconds elapsed time. /// </summary> /// <param name="from">the start index within the receiver, inclusive.</param> /// <param name="to">the end index within the receiver, inclusive.</param> /// <param name="source">the source bitvector to copy from.</param> /// <param name="sourceFrom">the start index within <i>source</i>, inclusive.</param> /// <exception cref="IndexOutOfRangeException">if <i>Size>0 && (from<0 || from>to || to>=Size || sourceFrom<0 || sourceFrom+to-from+1>source.Count))</i>.</exception> public void ReplaceFromToWith(int from, int to, BitVector source, int sourceFrom) { if (nbits == 0 || to == from - 1) { return; } CheckRangeFromTo(from, to, nbits); int Length = to - from + 1; if (sourceFrom < 0 || sourceFrom + Length > source.Size) { throw new IndexOutOfRangeException(); } if (source.bits == this.bits && from <= sourceFrom && sourceFrom <= to) { // dangerous intersection source = source.Copy(); } long[] theBits = this.bits; // cached for speed. long[] sourceBits = source.bits; // cached for speed. /* * This version is equivalent to the version below but 20 times slower.. * for (int i=from; --Length >= 0; i++, sourceFrom++) { * QuickBitVector.Put(theBits,i,QuickBitVector.Get(sourceBits,sourceFrom)); * } */ // Low level implementation for speed. // This could be done even faster by implementing on even lower levelsd But then the code would probably become a "don't touch" piece. int width = to - from + 1; int blocks = QuickBitVector.Unit(width); // width/64 int bitsPerUnit = QuickBitVector.BITS_PER_UNIT; int bitsPerUnitMinusOne = bitsPerUnit - 1; // copy entire 64 bit blocks, if any. for (int i = blocks; --i >= 0;) { long val1 = QuickBitVector.GetLongFromTo(sourceBits, sourceFrom, sourceFrom + bitsPerUnitMinusOne); QuickBitVector.PutLongFromTo(theBits, val1, from, from + bitsPerUnitMinusOne); sourceFrom += bitsPerUnit; from += bitsPerUnit; } // copy trailing bits, if any. int offset = QuickBitVector.Offset(width); //width%64 long val2 = QuickBitVector.GetLongFromTo(sourceBits, sourceFrom, sourceFrom + offset - 1); QuickBitVector.PutLongFromTo(theBits, val2, from, from + offset - 1); }
/// <summary> /// Sets bits of the receiver from index <code>from</code> to index <code>to</code> to the bits of <code>value</code>. /// Bit <code>from</code> is set to bit 0 of <code>value</code>, .d, bit <code>to</code> is set to bit <code>to-from</code> of <code>value</code>. /// All other bits stay unaffected. /// If <i>to-from+1==0</i> then does nothing. /// </summary> /// <param name="value">the value to be copied into the receiver.</param> /// <param name="from">index of start bit (inclusive).</param> /// <param name="to">index of end bit (inclusive).</param> /// <exception cref="IndexOutOfRangeException">if <i>from<0 || from>=Size || to<0 || to>=Size || to-from+1<0 || to-from+1>64</i>.</exception> public void PutLongFromTo(long value, int from, int to) { int width = to - from + 1; if (width == 0) { return; } if (from < 0 || from >= nbits || to < 0 || to >= nbits || width < 0 || width > QuickBitVector.BITS_PER_UNIT) { throw new IndexOutOfRangeException("from:" + from + ", to:" + to); } QuickBitVector.PutLongFromTo(bits, value, from, to); }
/// <summary> /// Returns a long value representing bits of the receiver from index <i>from</i> to index <i>to</i>. /// Bits are returned as a long value with the return value having bit 0 set to bit <code>from</code>, .d, bit <code>to-from</code> set to bit <code>to</code>. /// All other bits of the return value are set to 0. /// If <i>to-from+1==0</i> then returns zero (<i>0L</i>). /// </summary> /// <param name="from">index of start bit (inclusive).</param> /// <param name="to">index of end bit (inclusive).</param> /// <returns>the specified bits as long value.</returns> /// <exception cref="IndexOutOfRangeException">if <i>from<0 || from>=Size || to<0 || to>=Size || to-from+1<0 || to-from+1>64</i></exception> public long GetLongFromTo(int from, int to) { int width = to - from + 1; if (width == 0) { return(0L); } if (from < 0 || from >= nbits || to < 0 || to >= nbits || width < 0 || width > QuickBitVector.BITS_PER_UNIT) { throw new IndexOutOfRangeException("from:" + from + ", to:" + to); } return(QuickBitVector.GetLongFromTo(bits, from, to)); }
public Boolean this[int bitIndex] { get { if (bitIndex < 0 || bitIndex >= nbits) { throw new IndexOutOfRangeException(bitIndex.ToString()); } return(QuickBitVector.Get(bits, bitIndex)); } set { if (bitIndex < 0 || bitIndex >= nbits) { throw new IndexOutOfRangeException(bitIndex.ToString()); } if (value) { QuickBitVector.Set(bits, bitIndex); } else { QuickBitVector.Clear(bits, bitIndex); } } }
/// <summary> /// Constructs a bit matrix with a given number of columns and rowsd All bits are initially <i>false</i>. /// </summary> /// <param name="columns">the number of columns the matrix shall have.</param> /// <param name="rows">the number of rows the matrix shall have.</param> /// <exception cref="ArgumentException">if <i>columns < 0 || rows < 0</i>.</exception> public BitMatrix(int columns, int rows) { GetElements(QuickBitVector.MakeBitVector(columns * rows, 1), columns, rows); }
/// <summary> /// Sets the bits in the given range to the state specified by <i>value</i>. /// <p> /// Optimized for speedd Preliminary performance (200Mhz Pentium Pro, JDK 1.2, NT): replace 10^6 ill aligned bits --> 0.002 seconds elapsed time. /// </summary> /// <param name="from">the start index, inclusive.</param> /// <param name="to">the end index, inclusive.</param> /// <param name="value">the value to be stored in the bits of the range.</param> /// <exception cref="IndexOutOfRangeException">if <i>Size>0 && (from<0 || from>to || to>=Size)</i>.</exception> public void ReplaceFromToWith(int from, int to, Boolean value) { if (nbits == 0 || to == from - 1) { return; } CheckRangeFromTo(from, to, nbits); long[] theBits = this.bits; // cached for speed int fromUnit = QuickBitVector.Unit(from); int fromOffset = QuickBitVector.Offset(from); int toUnit = QuickBitVector.Unit(to); int toOffset = QuickBitVector.Offset(to); int bitsPerUnit = QuickBitVector.BITS_PER_UNIT; long filler; if (value) { filler = ~0L; } else { filler = 0L; } int bitIndex = from; if (fromUnit == toUnit) { // only one unit to do QuickBitVector.PutLongFromTo(theBits, filler, bitIndex, bitIndex + to - from); //slower: for (; bitIndex<=to; ) QuickBitVector.Put(theBits,bitIndex++,value); return; } // treat leading partial unit, if any. if (fromOffset > 0) { // fix by Olivier Janssens QuickBitVector.PutLongFromTo(theBits, filler, bitIndex, bitIndex + bitsPerUnit - fromOffset); bitIndex += bitsPerUnit - fromOffset + 1; /* slower: * for (int i=bitsPerUnit-fromOffset; --i >= 0; ) { * QuickBitVector.Put(theBits,bitIndex++,value); * }*/ fromUnit++; } if (toOffset < bitsPerUnit - 1) { toUnit--; // there is a trailing partial unit } // treat full units, if any. for (int i = fromUnit; i <= toUnit;) { theBits[i++] = filler; } if (fromUnit <= toUnit) { bitIndex += (toUnit - fromUnit + 1) * bitsPerUnit; } // treat trailing partial unit, if any. if (toOffset < bitsPerUnit - 1) { QuickBitVector.PutLongFromTo(theBits, filler, bitIndex, to); /* slower: * for (int i=toOffset+1; --i >= 0; ) { * QuickBitVector.Put(theBits,bitIndex++,value); * }*/ } }
/// <summary> /// Returns the number of units that are FULL (not PARTIAL). /// </summary> /// <returns></returns> public int NumberOfFullUnits() { return(QuickBitVector.Unit(nbits)); }
/// <summary> /// Returns the number of bits used in the trailing PARTIAL unit. /// Returns zero if there is no such trailing partial unit. /// </summary> /// <returns></returns> public int NumberOfBitsInPartialUnit() { return(QuickBitVector.Offset(nbits)); }
/// <summary> /// Returns from the bitvector the value of the bit with the specified index; <b>WARNING:</b> Does not check preconditions. /// The value is <i>true</i> if the bit with the index <i>bitIndex</i> /// is currently set; otherwise, returns <i>false</i>. /// /// <p>Provided with invalid parameters this method may return invalid values without throwing any exception. /// <b>You should only use this method when you are absolutely sure that the index is within bounds.</b> /// Precondition (unchecked): <i>bitIndex >= 0 && bitIndex < Size</i>. /// </summary> /// <param name="bitIndex">the bit index.</param> /// <returns>the value of the bit with the specified index.</returns> public Boolean GetQuick(int bitIndex) { return(QuickBitVector.Get(bits, bitIndex)); }
/// <summary> /// Applies a procedure to each bit index within the specified range that holds a bit in the given state. /// Starts at index <i>from</i>, moves rightwards to <i>to</i>. /// Useful, for example, if you want to copy bits into an image or somewhere else. /// <p> /// 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="from">the leftmost search position, inclusive.</param> /// <param name="to">the rightmost search position, inclusive.</param> /// <param name="state">element to search for.</param> /// <param name="foundPos">the index that found</param> /// <param name="procedure">a procedure object taking as argument the current bit indexd 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> /// <exception cref="IndexOutOfRangeException">if (<i>Size>0 && (from<0 || from>to || to>=Size)</i>).</exception> public Boolean ForEachIndexFromToInState(int from, int to, Boolean state, ref int foundPos, Cern.Colt.Function.IntProcedure procedure) { /* * // this version is equivalent to the low level version below, but about 100 times slower for large ranges. * if (nbits==0) return true; * checkRangeFromTo(from, to, nbits); * long[] theBits = this.bits; // cached for speed * int Length=to-from+1; * for (int i=from; --Length >= 0; i++) { * if (QuickBitVector.Get(theBits,i)==state) { * if (!function(i)) return false; * } * } * return true; */ /* * This low level implementation exploits the fact that for any full unit one can determine in O(1) * whether it contains at least one true bit, * and whether it contains at least one false bit. * Thus, 64 bits can often be skipped with one simple comparison if the vector is either sparse or dense. * * However, careful coding must be done for leading and/or trailing units which are not entirely contained in the query range. */ if (nbits == 0) { return(true); } CheckRangeFromTo(from, to, nbits); //Console.WriteLine("\n"); //Console.WriteLine(this); //Console.WriteLine("from="+from+", to="+to+", bit="+state); // Cache some vars for speed. long[] theBits = this.bits; int bitsPerUnit = QuickBitVector.BITS_PER_UNIT; // Prepare int fromUnit = QuickBitVector.Unit(from); int toUnit = QuickBitVector.Unit(to); int i = from; // current bitvector index // Iterate over the leading partial unit, if any. int bitIndex = QuickBitVector.Offset(from); int partialWidth; if (bitIndex > 0) { // There exists a leading partial unit. partialWidth = System.Math.Min(to - from + 1, bitsPerUnit - bitIndex); //Console.WriteLine("partialWidth1="+partialWidth); for (; --partialWidth >= 0; i++) { if (QuickBitVector.Get(theBits, i) == state) { foundPos = i; if (!procedure(i)) { return(false); } } } fromUnit++; // leading partial unit is done. } if (i > to) { return(true); // done } // If there is a trailing partial unit, then there is one full unit less to test. bitIndex = QuickBitVector.Offset(to); if (bitIndex < bitsPerUnit - 1) { toUnit--; // trailing partial unit needs to be tested extra. partialWidth = bitIndex + 1; } else { partialWidth = 0; } //Console.WriteLine("partialWidth2="+partialWidth); // Iterate over all full units, if any. // (It does not matter that iterating over partial units is a little bit slow, // the only thing that matters is that iterating over full units is quickd) long comparator; if (state) { comparator = 0L; } else { comparator = ~0L; // all 64 bits set } //Console.WriteLine("fromUnit="+fromUnit+", toUnit="+toUnit); for (int unit = fromUnit; unit <= toUnit; unit++) { long val = theBits[unit]; if (val != comparator) { // at least one element within current unit matches. // iterate over all bits within current unit. if (state) { for (int j = 0, k = bitsPerUnit; --k >= 0; i++) { if ((val & (1L << j++)) != 0L) { // is bit set? foundPos = i; if (!procedure(i)) { return(false); } } } } else { for (int j = 0, k = bitsPerUnit; --k >= 0; i++) { if ((val & (1L << j++)) == 0L) { // is bit cleared? foundPos = i; if (!procedure(i)) { return(false); } } } } } else { i += bitsPerUnit; } } //Console.WriteLine("trail with i="+i); // Iterate over trailing partial unit, if any. for (; --partialWidth >= 0; i++) { if (QuickBitVector.Get(theBits, i) == state) { foundPos = i; if (!procedure(i)) { return(false); } } } return(true); }
/// <summary> /// Constructs a bit vector that holds <i>size</i> bitsd All bits are initially <i>false</i>. /// </summary> /// <param name="size">the number of bits the bit vector shall have.</param> /// <exception cref="ArgumentException">if <i>size < 0</i>.</exception> public BitVector(int size) : this(QuickBitVector.MakeBitVector(size, 1), size) { }