/// <summary> /// Computes the specified quantile elements over the values previously added. /// </summary> /// <param name="phis">the quantiles for which elements are to be computed. Each phi must be in the interval (0.0,1.0]. <tt>phis</tt> must be sorted ascending.</param> /// <returns>the approximate quantile elements.</returns> public override DoubleArrayList QuantileElements(DoubleArrayList phis) { if (precomputeEpsilon <= 0.0) { return(base.QuantileElements(phis)); } int quantilesToPrecompute = (int)Utils.EpsilonCeiling(1.0 / precomputeEpsilon); /* * if (phis.Count > quantilesToPrecompute) { * // illegal use case! * // we compute results, but loose explicit approximation guarantees. * return base.QuantileElements(phis); * } */ //select that quantile from the precomputed set that corresponds to a position closest to phi. phis = phis.Copy(); double e = precomputeEpsilon; for (int index = phis.Size; --index >= 0;) { double phi = phis[index]; int i = (int)System.Math.Round(((2.0 * phi / e) - 1.0) / 2.0); // finds closest i = System.Math.Min(quantilesToPrecompute - 1, System.Math.Max(0, i)); double augmentedPhi = (e / 2.0) * (1 + 2 * i); phis[index] = augmentedPhi; } return(base.QuantileElements(phis)); }
/// <summary> /// Computes the specified quantile elements over the values previously added. /// </summary> /// <param name="phis">the quantiles for which elements are to be computed. Each phi must be in the interval [0.0,1.0]. <tt>phis</tt> must be sorted ascending.</param> /// <returns>the approximate quantile elements.</returns> public virtual DoubleArrayList QuantileElements(DoubleArrayList phis) { /* * //check parameter */ List <Double> sortedPhiList = phis.Copy().ToList(); sortedPhiList.Sort(); if (!phis.Equals(sortedPhiList)) { throw new ArgumentException(Cern.LocalizedResources.Instance().Exception_PhisMustBeAscending); } //System.out.println("starting to augment missing values, if necessary..."); phis = PreProcessPhis(phis); long[] triggerPositions = new long[phis.Size]; long totalSize = this.bufferSet.TotalSize; for (int i = phis.Size; --i >= 0;) { triggerPositions[i] = Utils.EpsilonCeiling(phis[i] * totalSize) - 1; } //System.out.println("triggerPositions="+cern.colt.Arrays.ToString(triggerPositions)); //System.out.println("starting to determine quantiles..."); //System.out.println(bufferSet); DoubleBuffer[] fullBuffers = bufferSet.GetFullOrPartialBuffers(); double[] quantileElements = new double[phis.Size]; //do the main work: determine values at given positions in sorted sequence return(new DoubleArrayList(bufferSet.GetValuesAtPositions(fullBuffers, triggerPositions))); }
protected new DoubleArrayList PreProcessPhis(DoubleArrayList phis) { if (beta > 1.0) { phis = phis.Copy(); for (int i = phis.Size; --i >= 0;) { phis[i] = (2 * phis[i] + beta - 1) / (2 * beta); } } return(phis); }