Author: tdunning
Date: Thu Sep  2 04:32:51 2010
New Revision: 991803

URL: http://svn.apache.org/viewvc?rev=991803&view=rev
Log:
MAHOUT-495 - Undeprecate Exponential distribution

Added:
    
mahout/trunk/math/src/test/java/org/apache/mahout/math/jet/random/ExponentialTest.java
Modified:
    
mahout/trunk/math/src/main/java/org/apache/mahout/math/jet/random/Exponential.java

Modified: 
mahout/trunk/math/src/main/java/org/apache/mahout/math/jet/random/Exponential.java
URL: 
http://svn.apache.org/viewvc/mahout/trunk/math/src/main/java/org/apache/mahout/math/jet/random/Exponential.java?rev=991803&r1=991802&r2=991803&view=diff
==============================================================================
--- 
mahout/trunk/math/src/main/java/org/apache/mahout/math/jet/random/Exponential.java
 (original)
+++ 
mahout/trunk/math/src/main/java/org/apache/mahout/math/jet/random/Exponential.java
 Thu Sep  2 04:32:51 2010
@@ -10,22 +10,30 @@ package org.apache.mahout.math.jet.rando
 
 import org.apache.mahout.math.jet.random.engine.RandomEngine;
 
-/** @deprecated until unit tests are in place.  Until this time, this 
class/interface is unsupported. */
-...@deprecated
-public class Exponential extends AbstractContinousDistribution {
+import java.util.Locale;
 
+public class Exponential extends AbstractContinousDistribution {
+  // rate parameter for the distribution.  Mean is 1/lambda.
   private double lambda;
 
-  // The uniform random number generated shared by all <b>static</b> methods.
-  private static final Exponential shared = new Exponential(1.0, 
makeDefaultGenerator());
-
-  /** Constructs a Negative Exponential distribution. */
+  /**
+   * Provides a negative exponential distribution given a rate parameter 
lambda and an underlying
+   * random number generator.  The mean of this distribution will be equal to 
1/lambda.
+   *
+   * @param lambda          The rate parameter of the distribution.
+   * @param randomGenerator The PRNG that is used to generate values.
+   */
   public Exponential(double lambda, RandomEngine randomGenerator) {
     setRandomGenerator(randomGenerator);
     setState(lambda);
   }
 
-  /** Returns the cumulative distribution function. */
+  /**
+   * Returns the cumulative distribution function.
+   * @param x  The point at which the cumulative distribution function is to 
be evaluated.
+   * @return Returns the integral from -infinity to x of the PDF, also known 
as the cumulative distribution
+   * function.
+   */
   public double cdf(double x) {
     if (x <= 0.0) {
       return 0.0;
@@ -33,18 +41,19 @@ public class Exponential extends Abstrac
     return 1.0 - Math.exp(-x * lambda);
   }
 
-  /** Returns a random number from the distribution. */
+  /**
+   * Returns a random number from the distribution.
+   */
   @Override
   public double nextDouble() {
-    return nextDouble(lambda);
-  }
-
-  /** Returns a random number from the distribution; bypasses the internal 
state. */
-  public double nextDouble(double lambda) {
-    return -Math.log(randomGenerator.raw()) / lambda;
+    return -Math.log(1 - randomGenerator.raw()) / lambda;
   }
 
-  /** Returns the probability distribution function. */
+  /**
+   * Returns the value of the probability density function at a particular 
point.
+   * @param x   The point at which the probability density function is to be 
evaluated.
+   * @return  The value of the probability density function at the specified 
point.
+   */
   public double pdf(double x) {
     if (x < 0.0) {
       return 0.0;
@@ -52,21 +61,19 @@ public class Exponential extends Abstrac
     return lambda * Math.exp(-x * lambda);
   }
 
-  /** Sets the mean. */
+  /**
+   * Sets the rate parameter.
+   * @param lambda  The new value of the rate parameter.
+   */
   public void setState(double lambda) {
     this.lambda = lambda;
   }
 
-  /** Returns a random number from the distribution with the given lambda. */
-  public static double staticNextDouble(double lambda) {
-    synchronized (shared) {
-      return shared.nextDouble(lambda);
-    }
-  }
-
-  /** Returns a String representation of the receiver. */
+  /**
+   * Returns a String representation of the receiver.
+   */
   public String toString() {
-    return this.getClass().getName() + '(' + lambda + ')';
+    return String.format(Locale.ENGLISH, "%s(%.4f)", 
this.getClass().getName(), lambda);
   }
 
 }

Added: 
mahout/trunk/math/src/test/java/org/apache/mahout/math/jet/random/ExponentialTest.java
URL: 
http://svn.apache.org/viewvc/mahout/trunk/math/src/test/java/org/apache/mahout/math/jet/random/ExponentialTest.java?rev=991803&view=auto
==============================================================================
--- 
mahout/trunk/math/src/test/java/org/apache/mahout/math/jet/random/ExponentialTest.java
 (added)
+++ 
mahout/trunk/math/src/test/java/org/apache/mahout/math/jet/random/ExponentialTest.java
 Thu Sep  2 04:32:51 2010
@@ -0,0 +1,93 @@
+/*
+ * 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.jet.random;
+
+import org.apache.mahout.math.jet.random.engine.MersenneTwister;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Locale;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Created by IntelliJ IDEA. User: tdunning Date: Aug 31, 2010 Time: 7:14:19 
PM To change this
+ * template use File | Settings | File Templates.
+ */
+public class ExponentialTest {
+  @Test
+  public void testCdf() {
+    Exponential dist = new Exponential(5.0, new MersenneTwister(1));
+    for (int i = 0; i < 1000; i++) {
+      double x = i / 50.0;
+      assertEquals(1 - Math.exp(-x * 5.0), dist.cdf(x), 1e-9);
+    }
+  }
+
+  @Test
+  public void testPdf() {
+    checkPdf(new Exponential(13.0, null), 13.0);
+  }
+
+  private void checkPdf(Exponential dist, double lambda) {
+    assertEquals(0, dist.pdf(-1), 0);
+    double sum = 0;
+    double dx = 0.001 / lambda;
+    for (double x = 0; x < 20/lambda;x+=dx) {
+      sum += x * dist.pdf(x) * dx;
+      assertEquals(Math.exp(-x * lambda) * lambda, dist.pdf(x), 1e-9);
+    }
+    assertEquals(1 / lambda, sum, 1e-6 / lambda);
+  }
+
+  @Test
+  public void testSetState() {
+    Exponential dist = new Exponential(13.0, null);
+    for (double lambda = 0.1; lambda < 1000; lambda *= 1.3) {
+      dist.setState(lambda);
+      checkPdf(dist, lambda);
+    }
+  }
+
+  @Test
+  public void testNextDouble() {
+    for (double lambda : new double[] {13.0, 0.02, 1.6}) {
+      Exponential dist = new Exponential(lambda, new MersenneTwister(1));
+      checkEmpiricalDistribution(dist, 10000, lambda);
+    }
+  }
+
+  private void checkEmpiricalDistribution(Exponential dist, int n, double 
lambda) {
+    double[] x = new double[n];
+    for (int i = 0; i < n; i++) {
+      x[i] = dist.nextDouble();
+    }
+    Arrays.sort(x);
+    for (int i = 0; i < n; i++) {
+      double cumulative = (double) i / (n - 1);
+      assertEquals(String.format("lambda = %.3f", lambda), cumulative, 
dist.cdf(x[i]), 0.02);
+    }
+  }
+
+  @Test
+  public void testToString() {
+    assertEquals("org.apache.mahout.math.jet.random.Exponential(3.1000)", new 
Exponential(3.1, null).toString());
+    Locale.setDefault(Locale.GERMAN);
+    assertEquals("org.apache.mahout.math.jet.random.Exponential(3.1000)", new 
Exponential(3.1, null).toString());
+  }
+}


Reply via email to