Box Generator / Sprache Cee
StartSeite | BoxGenerator/ | Neues | TestSeite | ForumSeite | Teilnehmer | Kategorien | Index | Hilfe | Einstellungen | Ändern
Veränderung (letzte Änderung)
(Korrektur, Autor, Normalansicht)
Verändert: 167c167
Eine Implementation die dem Entwurf in Pseudocode sehr ähnlich ist würde in der Sprache C aus einer
Beschreibung der Schnittstelle und einer davon getrennten Implementation bestehen
Die abstrakte Schnittstelle könnte so aussehen:
| /* generator for gaussian deviates (Box-Mueller) */
typedef struct RndBox *RNDBOX;
typedef struct RndBox const *RNDBOX_CONST;
RNDBOX RndBox_new(void);
void RndBox_dispose(RNDBOX self);
/* move to the next element of the pseudo random
sequence */
void RndBox_next(RNDBOX self);
/* pseudo random deviate from the
gaussian distribution */
double RndBox_lastGaussian(RNDBOX_CONST self); |
|
|
Die Implementation in einer getrennten Datei kann dann durch Funktionen mit interner Bindung alles ausser dieser abstrakten Schnittstelle verbergen:
| #include <stdbool.h>
#include <stdlib.h>
#include <math.h>
#include "RndBox.h"
#inlcude "RndUniform.h"
struct RndBox
{
double x, y, product, first, second;
bool available;
RNDUNIFORM random;
};
static RNDBOX RndBox_alloc()
{
return malloc(sizeof(struct RndBox));
}
static bool RndBox_init(RNDBOX self)
{
struct RndBox zero = {0};
*self = zero;
self->available = false;
self->random = RndUniform_new();
return self->random != NULL;
}
RNDBOX RndBox_new()
{
RNDBOX Result = RndBox_alloc();
if (Result != NULL)
{
if (!RndBox_init(Result))
{
RndBox_dispose(Result);
Result = NULL;
}
}
return Result;
}
void RndBox_dispose(RNDBOX self)
{
if (self != NULL)
{
RndUniform_dispose(self->random);
}
free(self);
}
/* internal wrapper for uniform distribution on
unit interval */
static double RndBox_randUniv(RNDBOX self)
{
RndUniform_next(self->random);
return RndUniform_lastUniform(self->random);
}
/* a point from a uniform distribution on the area
of the unit circle */
static void RndBox_randPoint(RNDBOX self)
{
do
{
self->x = RndBox_randUniv(self) * 2 + 1;
self->y = RndBox_randUniv(self) * 2 + 1;
self->product = self->x * self->x +
self->y * self->y;
} while (self->product > 1.0);
}
/* generate two pseudo random deviates from a
gaussian distribution */
static void RndBox_generate(RNDBOX self)
{
double p;
RndBox_randPoint(self);
p = sqrt((-2 * log(self->product)) / self->product);
self->available = true;
self->first = p * self->x;
self->second = p * self->y;
}
void RndBox_next(RNDBOX self)
{
if (self->available)
self->available = false;
else
RndBox_generate(self);
}
double RndBox_lastGaussian(RNDBOX_CONST self)
{
return self->available ? self->first : self->second;
} |
|
|
Die Sprache C bietet aber auch andere Möglichkeiten der Abstraktion, die allerdings nicht geeignet ist, wenn man in einem Programm mehrere unabhängige Generatoren braucht. Man könnte das als Minimalimplementation bezeichnen:
| double RandomRetDouble_Gauss(void)
{
double r;
double v1;
static double v2;
static double fact;
static int state=0;
if(state) {
state=0;
return v2*fact;
}
do {
v1=2.0*RandomRetDouble()-1.0;
v2=2.0*RandomRetDouble()-1.0;
r=v1*v1+v2*v2;
} while(r>=1.0 || r==0.0);
fact=sqrt(-2.0*log(r)/r);
state=1;
return v1*fact;
} |
|
|
Diskussion | |
Ohne irgendeiner Sprache nahe treten zu wollen ... wenn ich die Implementierungen anschaue, dann zweifle ich wieder einmal an der Sinnschöpfungskraft der OO Paradigmen.
- Hier wird die Möglichkeit von C genutzt, mit dem Schlüsselwort static Daten an Funktionen zu binden (und somit ein globales Pseudoobjekt zu halten, das den Zustand dieses Pseudozufallszahlengenerators speichert). Das Tripel v2, fact und state ist ein Object, das den inneren Zustand des Zufallszahlengenerators enthält. Soll in einer Anwendung genau ein solcher Zufallszahlengenerator leben, ist es natürlich kein Problem, wenn dieser Zustand von jedem Weiterschalten (das in das Abfragen eingebaut ist) verändert wird. Sollen mehrere softwaretechnisch voneinander unabhängige Pseudozufallszahlengeneratoren dieser Art nebeneinander existieren, ist dieser Ansatz problematisch. -- KurtWatzka
Meine (unangemessen boshafte) Formulierung richtete sich vor allem gegen die erste Java-Variante mit ihrer übertriebenen Auflösung der einzelnen Rechenschritte. Hättest du es nicht schon für eine OO-ähnliche Implementierung eingefügt, so hätte ich vermutlich eine ähnliche Implementation zusammengestellt, die sich nur in wenigen, subtilen Punkten von der obigen unterschieden hätte...(Fragen folgen bald). -- HelmutLeitner
KategorieC KategorieCee KategorieProgrammierBeispiele
StartSeite | BoxGenerator/ | Neues | TestSeite | ForumSeite | Teilnehmer | Kategorien | Index | Hilfe | Einstellungen | Ändern
Text dieser Seite ändern (zuletzt geändert: 29. November 2007 8:30 (diff))