def findBinomialNsWithLowerBoundSampleMinimum(confidence, desiredValuesSorted,
                                              p, numSamples, nMax):
  """
  For each desired value, find an approximate n for which the sample minimum
  has a probabilistic lower bound equal to this value.

  For each value, find an adjacent pair of n values whose lower bound sample
  minima are below and above the desired value, respectively, and return a
  linearly-interpolated n between these two values.

  @param confidence (float)
  For the probabilistic lower bound, this specifies the probability. If this is
  0.8, that means that there's an 80% chance that the sample minimum is >= the
  desired value, and 20% chance that it's < the desired value.

  @param p (float)
  The p if the binomial distribution.

  @param numSamples (int)
  The number of samples in the sample minimum distribution.

  @return
  A list of results. Each result contains
    (interpolated_n, lower_value, upper_value).
  where each lower_value and upper_value are the probabilistic lower bound
  sample minimum for floor(interpolated_n) and ceil(interpolated_n)
  respectively.
   ...]
  """

  def P(n, numOccurrences):
    """
    Given n, return probability than the sample minimum is >= numOccurrences
    """
    return 1 - SampleMinimumDistribution(numSamples, BinomialDistribution(n, p)).cdf(
      numOccurrences - 1)

  results = []

  n = 0

  for desiredValue in desiredValuesSorted:
    while n + 1 <= nMax and P(n + 1, desiredValue) < confidence:
      n += 1

    if n + 1 > nMax:
      break

    left = P(n, desiredValue)
    right = P(n + 1, desiredValue)

    interpolated = n + ((confidence - left) /
                        (right - left))
    result = (interpolated, left, right)
    results.append(result)

  return results
def findBinomialNsWithLowerBoundSampleMinimum ( confidence , desiredValuesSorted , p , numSamples , nMax ) : def P ( n , numOccurrences ) : return 1 - SampleMinimumDistribution ( numSamples , BinomialDistribution ( n , p ) ) . cdf ( numOccurrences - 1 ) results = [ ] n = 0 for desiredValue in desiredValuesSorted : while n + 1 <= nMax and P ( n + 1 , desiredValue ) < confidence : n += 1 if n + 1 > nMax : break left = P ( n , desiredValue ) right = P ( n + 1 , desiredValue ) interpolated = n + ( ( confidence - left ) / ( right - left ) ) result = ( interpolated , left , right ) results . append ( result ) return results
For each desired value, find an approximate n for which the sample minimum
  has a probabilistic lower bound equal to this value.

  For each value, find an adjacent pair of n values whose lower bound sample
  minima are below and above the desired value, respectively, and return a
  linearly-interpolated n between these two values.

  @param confidence (float)
  For the probabilistic lower bound, this specifies the probability. If this is
  0.8, that means that there's an 80% chance that the sample minimum is >= the
  desired value, and 20% chance that it's < the desired value.

  @param p (float)
  The p if the binomial distribution.

  @param numSamples (int)
  The number of samples in the sample minimum distribution.

  @return
  A list of results. Each result contains
    (interpolated_n, lower_value, upper_value).
  where each lower_value and upper_value are the probabilistic lower bound
  sample minimum for floor(interpolated_n) and ceil(interpolated_n)
  respectively.
   ...]