Box Generator / Sprache Java
 
StartSeite | BoxGenerator/ | Neues | TestSeite | ForumSeite | Teilnehmer | Kategorien | Index | Hilfe | Einstellungen | Ändern

Eine Implementation in SpracheJava, die möglichst dicht an dem Entwurf in Pseudocode bleibt

/** generator for gaussian deviates (Box-Mueller) */

class RndBox
{
  public RndBox()
  {
    random = new java.util.Random();
    available = false;
  }

  /** move to the next element of the pseudo random 
      sequence */

  public synchronized void next() 
  {
    if (available)
      available = false;
    else
      generate();
  }
   
  /** pseudo random deviate from the gaussian 
      distribution */
 
  public double lastGaussian()
  {
    return available ? first : second;
  }

  // generate two pseudo random deviates from a 
  // gaussian distribution 

  private void generate()
  {
    randpoint();
    double p = Math.sqrt((-2.0 * Math.log(product)) / 
                         product);
    first = p * x;
    available = true;
    second = p * y;
  }

  // a point from a uniform distribution on the area 
  // of the unit circle 

  private void randpoint() 
  {
    do
    {
      x = randuniv() * 2 - 1;
      y = randuniv() * 2 - 1;
      product = x * x + y * y;
    } while (product > 1.0);
  }

  private double x, y, product, first, second;   
  private boolean available;

  // internal wrapper for uniform distribution on 
  // unit interval 

  private double randuniv()
  {
    return random.nextDouble();
  }

  private java.util.Random random;
}

Eine alternative Implementation in Java, die generische Funktionalität des Zwischenlagerns von erzeugten Zahlen von der eigentlichen Implementierung des BoxGenerators trennt. Dabei kann über das Interface die Logik des NumberCaches auch für andere Generatoren weiterverwendet werden.

public class NumberCache
{
  private RandomNumberGenerator generator;
  public NumberCache(RandomNumberGenerator rng)
  {
    generator = rng;
  }

  private int index;
  private double[] cache = new double[0];
  public synchronized double retrieveNext()
    throws RandomNumberGeneratorException
  {
    // Hinzugefügt
    if (generator == null) 
    {
      String msg = "No RandomNumberGenerator available.";
      throw new RandomNumberGeneratorException(msg);
    }

    if (index >= cache.length)
    {
      cache = generator.nextBatch();
      index = 0;
      if ((cache == null) || (cache.length <= 0))
      {
        String msg = "The RandomNumberGenerator (" +
                     generator + ") returned nothing";
        throw new RandomNumberGeneratorException(msg);
      }
    }
    return cache[index++];
  }

  public String toString()
  {
    StringBuffer result = new StringBuffer(1024);
    result.append("NumberCache { id=");
    result.append(super.toString());
    result.append(", index=");
    result.append(index);
    if (cache == null) 
    {
      result.append(", cache=null");
    }
    else 
    {
      for (int i = 0; i < cache.length; ++i)
      {
        result.append(", cache[");
        result.append(i);
        result.append("]=");
        result.append(cache[i]);
      }
    }
    result.append(", generator=");
    result.append(generator);
    result.append("}");
    return result.toString();
  }

  public static void printRandom(RandomNumberGenerator rng, int count)
    throws RandomNumberGeneratorException
  {
    NumberCache cache = new NumberCache(rng);
    for (int i = 0; i < count; i++)
    {
      System.out.println(cache);
      System.out.println(cache.retrieveNext());
    }
  }
}

public interface RandomNumberGenerator
{
  /**
   * Returns a array of random numbers of 
   * a certain distribution.
   */
  public double[] nextBatch() throws RandomNumberGeneratorException;
}

import java.util.Random;

public class BoxGenerator
implements RandomNumberGenerator
{

  private Random generator = new Random();

  public synchronized double[] nextBatch()
  {
    // Erzeugen eines Punktes im Einheitskreis
    double x = getUniform();
    double y = getUniform();
    //     |x| > 1  <=>  x^2 > 1
    //     |x| < 1  <=>  x^2 < 1
    // Daher kann man sich hier das Wurzelziehen sparen
    while (getSquaredRadius(x, y) > 1) 
    {
      x = getUniform();
      y = getUniform();
    }

    // Berechnen des Transformationsfaktors
    double transformation = Math.log(getSquaredRadius(x,y));
    transformation *= -2.0;
    transformation /= getSquaredRadius(x,y);
    transformation = Math.sqrt(transformation);

    return new double[] 
    { 
      x * transformation, 
      y * transformation 
    };
  }

  protected double getSquaredRadius(double x, double y)
  {
    return x*x + y*y;
  }

  protected double getUniform()
  {
    return (generator.nextDouble() - 0.5) * 2;
  }
}


KategorieProgrammierBeispiele

Diskussionen

Aus dieser Seite sind einige Diskussionen entstanden, die aber nicht direkt mit dem Thema dieser Seite zu tun haben.


KategorieJava KategorieProgrammierBeispiele KategorieDiskussion
StartSeite | BoxGenerator/ | Neues | TestSeite | ForumSeite | Teilnehmer | Kategorien | Index | Hilfe | Einstellungen | Ändern
Text dieser Seite ändern (zuletzt geändert: 6. August 2002 17:42 (diff))
Suchbegriff: gesucht wird
im Titel
im Text