Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements.  See the NOTICE file distributed with
   * this work for additional information regarding copyright ownership.
   * The ASF licenses this file to You under the Apache License, Version 2.0
   * (the "License"); you may not use this file except in compliance with
   * the License.  You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 package org.apache.mahout.math.random;
 
 
Samples from an empirical cumulative distribution.
 
 public final class Empirical extends AbstractSamplerFunction {
   private final Random gen;
   private final boolean exceedMinimum;
   private final boolean exceedMaximum;
 
   private final double[] x;
   private final double[] y;
   private final int n;

  
Sets up a sampler for a specified empirical cumulative distribution function. The distribution can have optional exponential tails on either or both ends, but otherwise does a linear interpolation between known points.

Parameters:
exceedMinimum Should we generate samples less than the smallest quantile (i.e. generate a left tail)?
exceedMaximum Should we generate samples greater than the largest observed quantile (i.e. generate a right tail)?
samples The number of samples observed to get the quantiles.
ecdf Alternating values that represent which percentile (in the [0..1] range) and values. For instance, if you have the min, median and max of 1, 3, 10 you should pass 0.0, 1, 0.5, 3, 1.0, 10. Note that the list must include the 0-th (1.0-th) quantile if the left (right) tail is not allowed.
 
   public Empirical(boolean exceedMinimumboolean exceedMaximumint samplesdouble... ecdf) {
     Preconditions.checkArgument(ecdf.length % 2 == 0);
     Preconditions.checkArgument(samples >= 3);
 
     // if we can't exceed the observed bounds, then we have to be given the bounds.
     Preconditions.checkArgument(exceedMinimum || ecdf[0] == 0);
     Preconditions.checkArgument(exceedMaximum || ecdf[ecdf.length - 2] == 1);
 
      = RandomUtils.getRandom();
 
      = ecdf.length / 2;
      = new double[];
      = new double[];
 
     double lastX = ecdf[1];
     double lastY = ecdf[0];
     for (int i = 0; i < ecdf.lengthi += 2) {
       // values have to be monotonic increasing
       Preconditions.checkArgument(i == 0 || ecdf[i + 1] > lastY);
       [i / 2] = ecdf[i + 1];
       lastY = [i / 2];
 
       // quantiles have to be in [0,1] and be monotonic increasing
       Preconditions.checkArgument(ecdf[i] >= 0 && ecdf[i] <= 1);
       Preconditions.checkArgument(i == 0 || ecdf[i] > lastX);
 
       [i / 2] = ecdf[i];
       lastX = [i / 2];
     }
 
     // squeeze a bit to allow for unobserved tails
     double x0 = exceedMinimum ? 0.5 / samples : 0;
     double x1 = 1 - (exceedMaximum ? 0.5 / samples : 0);
     for (int i = 0; i < i++) {
       [i] = [i] * (x1 - x0) + x0;
     }
 
     this. = exceedMinimum;
     this. = exceedMaximum;
   }
 
   @Override
   public Double sample() {
     return sample(.nextDouble());
   }
 
   public double sample(double u) {
     if ( && u < [0]) {
       // generate from left tail
      if (u == 0) {
        u = 1.0e-16;
      }
      return [0] + Math.log(u / [0]) * [0] * ([1] - [0]) / ([1] - [0]);
    } else if ( && u > [ - 1]) {
      if (u == 1) {
        u = 1 - 1.0e-16;
      }
      // generate from right tail
      double dy = [ - 1] - [ - 2];
      double dx = [ - 1] - [ - 2];
      return [ - 1] - Math.log((1 - u) / (1 - [ - 1])) * (1 - [ - 1]) * dy / dx;
    } else {
      // linear interpolation
      for (int i = 1; i < i++) {
        if ([i] > u) {
          double dy = [i] - [i - 1];
          double dx = [i] - [i - 1];
          return [i - 1] + (u - [i - 1]) * dy / dx;
        }
      }
      throw new RuntimeException(String.format("Can't happen (%.3f is not in [%.3f,%.3f]"u[0], [ - 1]));
    }
  }
New to GrepCode? Check out our FAQ X