Ejemplo n.º 1
0
        /// <summary>
        /// Collapses the specified full buffers (must not include partial buffer).
        /// </summary>
        /// <param name="buffers">the buffers to be collapsed (all of them must be full or partially full)</param>
        /// <returns>a full buffer containing the collapsed values. The buffer has accumulated weight.</returns>
        public DoubleBuffer Collapse(DoubleBuffer[] buffers)
        {
            //determine W
            int W = 0;                              //sum of all weights

            for (int i = 0; i < buffers.Length; i++)
            {
                W += buffers[i].Weight;
            }

            //determine outputTriggerPositions
            int k = this.NumberOfElements;

            long[] triggerPositions = new long[k];
            for (int j = 0; j < k; j++)
            {
                triggerPositions[j] = this.NextTriggerPosition(j, W);
            }

            //do the main work: determine values at given positions in sorted sequence
            double[] outputValues = this.GetValuesAtPositions(buffers, triggerPositions);

            //mark all full buffers as empty, except the first, which will contain the output
            for (int b = 1; b < buffers.Length; b++)
            {
                buffers[b].Clear();
            }

            DoubleBuffer outputBuffer = buffers[0];

            outputBuffer.Values.Clear();
            outputBuffer.Values.SetElements(outputValues);
            outputBuffer.Weight = W;

            return(outputBuffer);
        }
        protected void RemoveInfinitiesFrom(int infinities, DoubleBuffer buffer)
        {
            int plusInf  = 0;
            int minusInf = 0;
            // count them (this is not very clever but it's safe)
            Boolean even = true;

            for (int i = 0; i < infinities; i++)
            {
                if (even)
                {
                    plusInf++;
                }
                else
                {
                    minusInf++;
                }
                even = !even;
            }

            buffer.Values.RemoveFromTo(buffer.Size - plusInf, buffer.Size - 1);
            buffer.Values.RemoveFromTo(0, minusInf - 1);
            //this.totalElementsFilled -= infinities;
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Determines all values of the specified buffers positioned at the specified triggerPositions within the sorted sequence and fills them into outputValues.
        /// </summary>
        /// <param name="buffers">the buffers to be searched (all must be full or partial) </param>
        /// <param name="triggerPositions">the positions of elements within the sorted sequence to be retrieved</param>
        /// <returns>outputValues a list filled with the values at triggerPositions</returns>
        internal double[] GetValuesAtPositions(DoubleBuffer[] buffers, long[] triggerPositions)
        {
            //if (buffers.Length==0)
            //{
            //	throw new ArgumentException("Oops! buffer.Length==0.");
            //}

            //System.out.println("triggers="+cern.it.util.Arrays.ToString(positions));

            //new List<Double>(outputValues).FillFromToWith(0, outputValues.Length-1, 0.0f);
            //delte the above line, it is only for testing

            //cern.it.util.Log.println("\nEntering getValuesAtPositions...");
            //cern.it.util.Log.println("hitPositions="+cern.it.util.Arrays.ToString(positions));

            // sort buffers.
            for (int i = buffers.Length; --i >= 0;)
            {
                buffers[i].Sort();
            }

            // collect some infos into fast cache; for tuning purposes only.
            int[]      bufferSizes      = new int[buffers.Length];
            double[][] bufferValues     = new double[buffers.Length][];
            int        totalBuffersSize = 0;

            for (int i = buffers.Length; --i >= 0;)
            {
                bufferSizes[i]    = buffers[i].Size;
                bufferValues[i]   = buffers[i].Values.ToArray();
                totalBuffersSize += bufferSizes[i];
                //cern.it.util.Log.println("buffer["+i+"]="+buffers[i].Values);
            }

            // prepare merge of equi-distant elements within buffers into output values

            // first collect some infos into fast cache; for tuning purposes only.
            int buffersSize            = buffers.Length;
            int triggerPositionsLength = triggerPositions.Length;

            // now prepare the important things.
            int j = 0;                               //current position in collapsed values

            int[] cursors = new int[buffers.Length]; //current position in each buffer; init with zeroes
            long  counter = 0;                       //current position in sorted sequence
            long  nextHit = triggerPositions[j];     //next position in sorted sequence to trigger output population

            double[] outputValues = new double[triggerPositionsLength];

            if (totalBuffersSize == 0)
            {
                // nothing to output, because no elements have been filled (we are empty).
                // return meaningless values
                for (int i = 0; i < triggerPositions.Length; i++)
                {
                    outputValues[i] = Double.NaN;
                }
                return(outputValues);
            }

            // fill all output values with equi-distant elements.
            while (j < triggerPositionsLength)
            {
                //System.out.println("\nj="+j);
                //System.out.println("counter="+counter);
                //System.out.println("nextHit="+nextHit);

                // determine buffer with smallest value at cursor position.
                double minValue       = Double.PositiveInfinity;
                int    minBufferIndex = -1;

                for (int b = buffersSize; --b >= 0;)
                {
                    //DoubleBuffer buffer = buffers[b];
                    //if (cursors[b] < buffer.Length) {
                    if (cursors[b] < bufferSizes[b])
                    {
                        ///double value = buffer.Values[cursors[b]];
                        double value = bufferValues[b][cursors[b]];
                        if (value <= minValue)
                        {
                            minValue       = value;
                            minBufferIndex = b;
                        }
                    }
                }

                DoubleBuffer minBuffer = buffers[minBufferIndex];

                // trigger copies into output sequence, if necessary.
                counter += minBuffer.Weight;
                while (counter > nextHit && j < triggerPositionsLength)
                {
                    outputValues[j++] = minValue;
                    //System.out.println("adding to output="+minValue);
                    if (j < triggerPositionsLength)
                    {
                        nextHit = triggerPositions[j];
                    }
                }


                // that element has now been treated, move further.
                cursors[minBufferIndex]++;
                //System.out.println("cursors="+cern.it.util.Arrays.ToString(cursors));
            } //end while (j<k)

            //cern.it.util.Log.println("returning output="+cern.it.util.Arrays.ToString(outputValues));
            return(outputValues);
        }