Beispiel #1
0
        /// <summary>
        /// Returns the index of the first occurrence of the specified
        /// stated Returns <code>-1</code> if the receiver does not contain this state.
        /// Searches between <code>from</code>, inclusive and <code>to</code>, inclusive.
        /// <p>
        /// Optimized for speedd Preliminary performance (200Mhz Pentium Pro, JDK 1.2, NT): size=10^6, from=0, to=size-1, receiver contains matching state in the very end --> 0.002 seconds elapsed time.
        /// </summary>
        /// <param name="from">the leftmost search position, inclusive.</param>
        /// <param name="to">the rightmost search position, inclusive.</param>
        /// <param name="state">state to search for.</param>
        /// <returns>the index of the first occurrence of the element in the receiver; returns <code>-1</code> if the element is not found.</returns>
        /// <exception cref="IndexOutOfRangeException">if (<i>Size&gt;0 && (from&lt;0 || from&gt;to || to&gt;=Size)</i>).</exception>
        public int IndexOfFromTo(int from, int to, Boolean state)
        {
            var indexProcedure = new Cern.Colt.Function.IntProcedure((a) => { return(false); });
            int foundPos       = 0;

            ForEachIndexFromToInState(from, to, state, ref foundPos, indexProcedure);
            return(foundPos);
        }
Beispiel #2
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);
        }