Esempio n. 1
0
        /// <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&gt;0 && (from&lt;0 || from&gt;to || to&gt;=Size || sourceFrom&lt;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);
        }
Esempio n. 2
0
        /// <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&gt;0 && (from&lt;0 || from&gt;to || to&gt;=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);
                 * }*/
            }
        }
Esempio n. 3
0
 /// <summary>
 /// Returns the number of units that are FULL (not PARTIAL).
 /// </summary>
 /// <returns></returns>
 public int NumberOfFullUnits()
 {
     return(QuickBitVector.Unit(nbits));
 }
Esempio n. 4
0
        /// <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&gt;0 && (from&lt;0 || from&gt;to || to&gt;=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);
        }