Zufälliges Golf des Tages Nr. 2: Zahlen aus einer Normalverteilung

12

Über die Serie

Zunächst einmal können Sie dies wie jede andere Code-Golf-Herausforderung behandeln und beantworten, ohne sich Gedanken über die Serie zu machen. Es gibt jedoch eine Rangliste für alle Herausforderungen. Sie finden die Rangliste zusammen mit weiteren Informationen zur Serie im ersten Beitrag .

Obwohl ich eine Menge Ideen für die Serie habe, sind die zukünftigen Herausforderungen noch nicht in Stein gemeißelt. Wenn Sie Vorschläge haben, teilen Sie mir dies bitte auf dem entsprechenden Sandbox-Post mit .

Loch 2: Zahlen aus einer Normalverteilung

Ich kann nicht glauben, dass dies noch nicht geschehen ist! Sie generieren Zufallszahlen aus einer Normalverteilung . Einige Regeln (die meisten von ihnen werden wahrscheinlich automatisch von den meisten Einreichungen abgedeckt, einige sind jedoch vorhanden, um die Konsistenz der Ergebnisse zwischen sehr unterschiedlichen Sprachen zu gewährleisten):

  • Sie sollten zwei nicht negative Ganzzahlen als Eingabe verwenden : einen Startwert Sund die Anzahl Nder zurückzugebenden Zahlen. Die Ausgabe sollte eine Liste von NGleitkommazahlen sein, die aus einer Normalverteilung mit dem Mittelwert 0 und der Varianz 1 erstellt wurden . Immer wenn Ihr Beitrag den gleichen Samen erhält S, sollte er die gleiche Nummer ergeben. Insbesondere wenn es einmal mit und einmal mit aufgerufen wird , sollten die ersten Einträge der beiden Ausgänge identisch sein. Zusätzlich sollten mindestens 2 16 unterschiedliche Werte unterschiedliche Sequenzen erzeugen.(S, N1)(S, N2)min(N1, N2)S

  • Sie können jeden eingebauten Zufallszahlengenerator verwenden, der dokumentiert ist, um Zahlen aus einer (ungefähren) gleichmäßigen Verteilung zu ziehen, vorausgesetzt, Sie können Ssie weitergeben und er unterstützt mindestens 2 16 verschiedene Startwerte. Wenn Sie dies tun, sollte der RNG in der Lage sein, mindestens 2 20 verschiedene Werte für eine bestimmte Nummer zurückzugeben, die Sie von ihm anfordern.

  • Wenn Ihr verfügbares einheitliches RNG eine geringere Reichweite hat, nicht aussaatfähig ist oder zu wenig Samen enthält, müssen Sie entweder zuerst ein einheitliches RNG mit einer ausreichend großen Reichweite über dem eingebauten RNG aufbauen oder Ihr eigenes geeignetes RNG mit implementieren der Samen. Diese Seite kann hilfreich sein.
  • Wenn Sie keinen etablierten Algorithmus zur Erzeugung von Normalverteilungen implementieren, fügen Sie bitte einen Korrektheitsnachweis bei. In beiden Fällen muss der von Ihnen gewählte Algorithmus eine theoretisch genaue Normalverteilung ergeben (mit Ausnahme von Einschränkungen des zugrunde liegenden PRNG- oder Datentyps mit begrenzter Genauigkeit).
  • Ihre Implementierung sollte entweder Gleitkommazahlen (mindestens 32 Bit breit) oder Festkommazahlen (mindestens 24 Bit breit) verwenden und zurückgeben, und alle arithmetischen Operationen sollten die volle Breite des ausgewählten Typs verwenden.
  • Sie dürfen keine eingebauten Funktionen verwenden, die in direktem Zusammenhang mit der Normalverteilung oder Gaußschen Integralen stehen, wie z. B. die Fehlerfunktion oder deren Inverse.

Sie können ein vollständiges Programm oder eine Funktion schreiben und Eingaben über STDIN, Befehlszeilenargument, Funktionsargument oder Eingabeaufforderung vornehmen und Ausgaben über Rückgabewerte oder durch Drucken an STDOUT (oder die nächstgelegene Alternative) erzeugen.

Sund Nes handelt sich um nicht negative ganze Zahlen mit jeweils weniger als 2 20 . Die Ausgabe kann in einem beliebigen praktischen, eindeutigen Listen- oder Zeichenfolgenformat erfolgen.

Dies ist Codegolf, daher gewinnt die kürzeste Übermittlung (in Byte). Und natürlich wird die kürzeste Einreichung pro Benutzer auch in die Gesamt-Bestenliste der Serie aufgenommen.

Bestenliste

Der erste Beitrag der Serie generiert eine Rangliste.

Um sicherzustellen, dass Ihre Antworten angezeigt werden, beginnen Sie jede Antwort mit einer Überschrift. Verwenden Sie dazu die folgende Markdown-Vorlage:

# Language Name, N bytes

Wo Nist die Größe Ihres Beitrags? Wenn Sie Ihren Score zu verbessern, Sie können alte Rechnungen in der Überschrift halten, indem man sich durch das Anschlagen. Zum Beispiel:

# Ruby, <s>104</s> <s>101</s> 96 bytes

(Die Sprache wird derzeit nicht angezeigt, das Snippet erfordert sie jedoch und analysiert sie. In Zukunft werde ich möglicherweise eine Bestenliste nach Sprachen hinzufügen.)

Martin Ender
quelle
Warten Sie, dürfen wir nicht ganzzahlige RNGs verwenden?
6.
PS 2-Antworten scheinen [0, 1] Gleitkomma-RNGs zu verwenden. Ist dies zulässig?
6.
@mniip Ja, Fließkomma-RNGs sind zulässig, vorausgesetzt, sie sind einheitlich, setzbar und können die erforderliche Anzahl unterschiedlicher Fließkommas zurückgeben.
Martin Ender

Antworten:

8

Dyalog APL, 33 Bytes

{(.5*⍨¯2×⍟?0)×1○○2×?0}¨⍳⎕⊣⎕rl←1+⎕

Box-Muller :

⎕         ⍝ evaluated input
⎕rl←1+⎕   ⍝ set APL's random seed to 1+⎕ (S)
          ⍝   add 1 because ⎕rl←0 has special meaning: sets the seed randomly
{ }¨⍳N    ⍝ do the thing in braces N times
?0        ⍝ random number 0≤x<1
1○○2×A    ⍝ sin(2πA)
.5*⍨¯2×⍟B ⍝ sqrt(-2lnB)
ngn
quelle
Ich bin mir ziemlich sicher, dass dies von keiner anderen Sprache übertroffen werden kann.
Zero Fibre
2
Dies entspricht nicht dieser Regel: "Insbesondere wenn es einmal mit (S, N1) und einmal mit (S, N2) aufgerufen wird, sollten die ersten min (N1, N2) Einträge der beiden Ausgänge identisch sein."
Marinus
@marinus Danke, behoben. Ich habe mich auch geändert ⎕rl, S+1weil es ⎕rl←0eine besondere Bedeutung hat.
8.
Sie brauchen das wahrscheinlich gar nicht +1, es heißt nur, dass Sie mindestens 2 ^ 16 verschiedene Werte unterstützen müssen. Das korrekte Arbeiten im Bereich [1..2 ^ 16] sollte also in Ordnung sein.
Marinus
S = 0 würde die Berechnung nicht wiederholbar machen, was gegen die oben angegebene Regel verstößt.
8.
8

R, 68 Bytes

function(S,N){set.seed(S);sqrt(-2*log(runif(N)))*cos(2*pi*runif(N))}

Hierbei wird die runif()Funktion verwendet, die zufällige Abweichungen von einer Gleichverteilung erzeugt. Der Startwert für die Zufallszahlengenerierung wird mit angegeben set.seed(), wobei standardmäßig der Mersenne-Twister-Algorithmus mit einer Periode von 2 ^ 19937-1 verwendet wird.

Das Ergebnis ist ein R-Vektor der Länge N, der die berechneten Standardnormalabweichungen enthält.

Hierbei wird die Box-Muller-Methode verwendet: Für zwei unabhängige, einheitliche Zufallsvariablen U und V Bildbeschreibung hier eingeben

Alex A.
quelle
Wenn diese Syntax in R gültig ist, können Sie die weglassen f=(die Funktion muss nicht unbedingt benannt werden, wenn unbenannte Funktionen in Ihrer Sprache vorkommen).
Martin Ender
@ MartinBüttner: Ich schätze den Vorschlag, aber meines Wissens würde R nicht wissen, was mit einer unbenannten Funktion zu tun ist.
Alex A.
Außerdem erhalte ich immer eine Fehlermeldung. Sind Sie Error: unexpected '}' in "f=fu...sicher, dass Sie die gleichen ersten Nummern erhalten, wenn Sie anrufen f(0,1)und f(0,2)?
Fehler
4

Dyalog APL, 42 34

{⎕RL←⍺⋄{(.5*⍨¯2×⍟⍺)×1○⍵×○2}/?⍵2⍴0}

Dies ist eine Funktion, die Sals linkes Argument und Nals rechtes Argument verwendet wird.

     5{⎕RL←⍺⋄{(.5*⍨¯2×⍟⍺)×1○⍵×○2}/?⍵2⍴0}10
3.019132549 ¯0.2903143175 ¯0.7353414637 1.421417015 2.327544764 ¯0.00005019747711 ¯0.9582127248 ¯0.2764568462
      ¯0.1602736853 ¯0.9912352616
     5{⎕RL←⍺⋄{(.5*⍨¯2×⍟⍺)×1○⍵×○2}/?⍵2⍴0}20
3.019132549 ¯0.2903143175 ¯0.7353414637 1.421417015 2.327544764 ¯0.00005019747711 ¯0.9582127248 ¯0.2764568462
      ¯0.1602736853 ¯0.9912352616 0.642585109 ¯0.2450019151 ¯0.415034463 0.03481768503 ¯0.4621212815 ¯0.760925979
      0.2592913013 1.884867889 ¯0.9621252731 0.3062560446

Es ist eine Implementierung der Box-Muller-Transformation unter Verwendung des in Dyalog APL integrierten Zufallsoperators ? , der standardmäßig ein Mersenne-Twister ist, der 64-Bit-Werte zurückgibt. sollte ausreichen.

Erläuterung:

  • ⎕RL←⍺: setze den zufälligen Startwert auf .
  • ?⍵2⍴0: erzeugt Zufallszahlenpaare zwischen 0 und 1.
  • {... }/: Wende die folgende Funktion auf jedes Paar an:
    • (.5*⍨¯2×⍟⍺)×1○⍵×○2: berechne den Z0Wert ( sqrt(-2 ln ⍺)×cos(2π⍵)).
Marinus
quelle
1
In V14.0 ?0kehrt eine Gleitkommazahl zwischen 0 und 1
NGN
3

Perl, 67

sub f{srand$_[0];map{cos(atan2(1,1)*rand 8)*sqrt-2*log rand}1..pop}

Box-Müller wie in anderen Einträgen. fNimmt die Parameter in die richtige Reihenfolge S, N.

Verwenden:

$ perl -le 'sub f{srand$_[0];map{cos(atan2(1,1)*rand 8)*sqrt-2*log rand}1..pop}print for f(5,3)'
-1.59212831801942
0.432167710756345
-0.533673305924252
nutki
quelle
3

Java, 164 161 Bytes

class B extends java.util.Random{B(int s,int n){super(s);for(;n-->0;System.out.println(Math.sqrt(-2*Math.log(nextDouble()))*Math.cos(2*Math.PI*nextDouble())));}}

Dies nimmt die Eingabe über die Funktion und die Ausgabe über stdout auf. Es verwendet die Box-Muller-Methode.

Die Nummer eins
quelle
5
s=0;s++<n;-> ;n-->0;?
Geobits
1
@ Geobits Sieht aus wie ein Lambda: D
TheNumberOne
3

Commodore 64 Basic, 76 70 63 Bytes

1INPUTS,N:S=R/(-S):F┌I=1TON:?S●(-2*LOG(R/(1)))*S╮(2*π*R/(1)):N─

Da der PETSCII-Zeichensatz einige in Unicode nicht vorhandene Symbole enthält, habe ich Ersetzungen vorgenommen: /= SHIFT+N, = SHIFT+O, = SHIFT+Q, = SHIFT+I, = , = =SHIFT+E

Dies implementiert die Standard-Box-Muller-Transformation, um die Zahlen zu erzeugen. Ich habe die sin (x) -Hälfte der Transformation ausgewählt, weil Commodore 64 Basic eine zweistellige Abkürzung für hat sin(), aber nicht für cos().

Obwohl die manuell nichts anderes ergibt, ist der Wert des Arguments RND tut Angelegenheit: Wenn eine negative Zahl übergeben wird, der Zufallszahlengenerator ist nicht nur neu ausgesät, ist es wieder ausgesät mit dieser Nummer . Dies macht das Seeding viel einfacher: Anstatt POKEfünf Speicherplätze zu benötigen , muss ich lediglich einen Notruf tätigenRND ausführen, wodurch der Code von zwei Zeilen / 121 Byte auf 1 Zeile / 76 Byte reduziert wird.

Bearbeiten: Golfed sechs Bytes aus, indem ich erkannte, dass ich die beiden kombinieren könnte INPUT Aussagen , und dass der Raum danachTO optional war.

Bearbeiten: Noch sieben Mal Golf gespielt: Commodore Basic hat Pi als eingebaute Konstante und kann sogar auf einer modernen Tastatur eingegeben werden ( SHIFT+PgDnfalls Sie sich fragen).

Kennzeichen
quelle
3

80386 Maschinencode, 72 Bytes

Hexdump des Codes:

60 8b 7c 24 24 33 ed 8d 75 fb 8d 46 79 f7 e2 f7
f6 8b da b3 7f 0f cb d1 eb 89 1f d9 07 d9 e8 de
e9 33 ee 75 e5 d9 ed d9 c9 d9 f1 dc c0 d9 e0 d9
fa d9 c9 d9 eb de c9 dc c0 d9 ff de c9 d9 1f 83
c7 04 e2 c6 61 c2 04 00

Hier ist der Quellcode (kann von Visual Studio kompiliert werden):

__declspec(naked) void __fastcall doit(int count, unsigned seed, float* output)
{
    _asm {
                                // ecx = count
                                // edx = seed
        // save registers
        pushad;
        mov edi, [esp + 0x24];  // edi = pointer to output
        xor ebp, ebp;           // ebp = 0
        lea esi, [ebp - 5];     // esi = 4294967291 (a prime number)

    myloop:
        // Calculate the next random number
        lea eax, [esi + 121];   // eax = 116
        mul edx;
        div esi;
        mov ebx, edx;

        // Convert it to a float in the range 1...2
        mov bl, 0x7f;
        bswap ebx;
        shr ebx, 1;

        // Convert to range 0...1 and push onto the FPU stack
        mov [edi], ebx;
        fld dword ptr [edi];
        fld1;
        fsubp st(1), st;

        // Make 2 such random numbers
        xor ebp, esi;
        jnz myloop;

        // Calculate sqrt(-2*ln(x))
        fldln2;
        fxch;
        fyl2x;
        fadd st, st(0);
        fchs;
        fsqrt;

        // Calculate cos(2*pi*y)
        fxch st(1);
        fldpi;
        fmul;
        fadd st, st(0);
        fcos;

        // Calculate and write output
        fmulp st(1), st;
        fstp dword ptr [edi];
        add edi, 4;

        // Repeat
        loop myloop

        // Return
        popad;
        ret 4;
    }
}

Hier benutze ich einen Lehmer Zufallsgenerator . Es verwendet den folgenden Algorithmus:

x(k+1) = 116 * x(k) mod 4294967291

Hier ist 4294967291 eine große (2 ^ 32-5) Primzahl, und 116 ist eine kleine (weniger als 128; siehe unten) Zahl, die ihre primitive Wurzel ist . Ich habe eine primitive Wurzel gewählt, die eine mehr oder weniger zufällige Verteilung von Nullen und Einsen in binärer Darstellung hat (01110100). Dieser RNG hat den maximal möglichen Zeitraum von 4294967290, wenn der Startwert ungleich Null ist.


Die relativ kleinen Zahlen, die ich hier verwendet habe (116 und 4294967291, die auch als -5 dargestellt werden können), ermöglichen es mir, die leaBefehlscodierung zu nutzen:

8d 46 79     lea eax, [esi+121]

Es wird zu 3 Bytes zusammengesetzt, wenn die Zahlen in 1 Byte passen.


Die Multiplikation und Division verwenden edxund eaxals Arbeitsregister, weshalb ich seedden zweiten Parameter zur Funktion gemacht habe ( fastcallAufrufkonvention verwendet edx, um den zweiten Parameter zu übergeben). Zusätzlich wird der erste Parameter übergeben ecx, der ein guter Platz für einen Zähler ist: Eine Schleife kann in einer Anweisung organisiert werden!

e2 c6        loop myloop

Um eine Ganzzahl in eine Gleitkommazahl umzuwandeln, habe ich die Darstellung von Gleitkommazahlen mit einfacher Genauigkeit ausgenutzt: Wenn ich die hohen 9 Bits (Exponenten) auf das Bitmuster setze 001111111und die 23 niedrigen Bits zufällig belasse, werde ich Erhalte eine Zufallszahl im Bereich 1 ... 2. Ich habe die Idee von hier übernommen . Um die hohen 9 Bits einzustellen, habe ich ein bisschen herumgespielt ebx:

mov ebx, edx;    xxxxxxxx|yyyyyyyy|zzzzzzzz|aaaaaaaa
mov bl, 0x7f;    xxxxxxxx|yyyyyyyy|zzzzzzzz|01111111
bswap ebx;       01111111|zzzzzzzz|yyyyyyyy|xxxxxxxx
shr ebx, 1;      00111111|1zzzzzzz|zyyyyyyy|yxxxxxxx

Um zwei Zufallszahlen zu generieren, habe ich eine verschachtelte Schleife von 2 Iterationen verwendet. Ich habe es organisiert mit xor:

xor ebp, esi;    first time, the result is -5
jnz myloop;      second time, the result is 0 - exit loop

Der Gleitkomma-Code implementiert die Box-Muller-Transformation .

anatolyg
quelle
2

Haskell, 118  144 

import System.Random;h z=let(u,r)=random z in(cos$2*pi*fst(random r)::Float)*sqrt(-2*log u):h r;g=(.(h.mkStdGen)).take

Beispielverwendung:

*Main> g 3 0x6AE4A92CAFA8A742
[0.50378895,-0.20593005,-0.16684927]
*Main> g 6 0x6AE4A92CAFA8A742
[0.50378895,-0.20593005,-0.16684927,1.1229043,-0.10026576,0.4279402]
*Main> g 6 0xE09B1088DF461F7D
[2.5723906,-0.5177805,-1.3535261,0.7400385,3.5619608e-3,-8.246434e-2]

Der Rückgabetyp von randomist auf beschränkt Float, wodurch randomin [0, 1) ein gleichmäßiger Float erzeugt wird. Von da an ist es eine einfache Box-Muller-Formel mit etwas sinnloser Magie für die Listenerstellung.

mniip
quelle
2

Golflua, 63 70

Golflua Infos und Anleitungen.

\g(n,s)`_ENV,b=M,{}rs(s)~@i=1,n b[i]=q(l(r()^-2))*c(r()*pi)$~b$

Gibt eine Tabelle mit den Werten zurück. In dem von mir verwendeten Beispiel ~T.u( )ist das dasselbe wie return table.unpack( )in lua.

> ~T.u(g(3,1234567))
0.89302672974232 0.36330401643578 -0.64762161593981
> ~T.u(g(5,1234567))
0.89302672974232 0.36330401643578 -0.64762161593981 -0.70654636393063 -0.65662878785425
> ~T.u(g(5,7654321))
0.3867923683064 -0.31758512485963 -0.58059120409317 1.2079459300077 1.1500121921242

Viele Zeichen wurden gespart, indem die Umgebung der Funktion auf M(aka math) gesetzt wurde.

mniip
quelle
2

SAS, 108

Ich habe bereits eine Antwort in R gepostet , die kürzer ist als diese, aber es gibt nur sehr wenige SAS-Antworten auf PPCG. Warum also nicht eine weitere hinzufügen?

%macro f(s,n);data;do i=1 to &n;x=sqrt(-2*log(ranuni(&s)))*cos(8*atan2(1,1)*ranuni(&s));put x;end;run;%mend;

Mit etwas Leerraum:

%macro f(s, n);
    data;
        do i = 1 to &n;
            x = sqrt(-2 * log(ranuni(&s))) * cos(8 * atan2(1, 1) * ranuni(&s));
            put x;
        end;
    run;
%mend;

Dies definiert ein Makro, das wie folgt aufgerufen werden kann %f(5, 3) . Das Makro führt einen Datenschritt aus, der die ganzen Zahlen 1 bis N durchläuft, und berechnet bei jeder Iteration eine zufällige normale Abweichung mit Box-Muller und druckt sie mit dem in das Protokollput Anweisung .

SAS hat kein eingebautes pi, so dass wir es am besten mit arctangent approximieren können.

Das ranuni() Funktion (die veraltet ist, aber ein paar weniger Zeichen benötigt als die neuere Funktion) gibt eine Zufallszahl aus einer Gleichverteilung zurück. Die SAS-Dokumentation enthält außer dem Zeitraum von 2 ^ 31-2 nur wenige Details zur RNG-Implementierung.

In SAS-Makros werden Makrovariablen mit einem vorangestellten Verweis versehen & Wert und zur Laufzeit in ihre Werte aufgelöst.

Wie Sie wahrscheinlich gesehen haben, ist SAS selten ein echter Konkurrent in einem Wettbewerb.

Alex A.
quelle
2

Java, 193 Bytes

Dies schlägt zwar nicht den aktuellen Java-Marktführer, aber ich habe mich trotzdem entschieden, einen Beitrag zu verfassen, um eine andere Berechnungsmethode zu zeigen. Es ist eine Golfversion von OpenJDK nextGaussian().

class N extends java.util.Random{N(int s,int n){super(s);for(float a,v;n-->0;System.out.println(v*Math.sqrt(-2*Math.log(a)/a)))for(a=0;a>=1|a==0;a=v*v+(v=2*nextFloat()-1)*v)v=2*nextFloat()-1;}}

Mit Zeilenumbrüchen:

class N extends java.util.Random{
    N(int s,int n){
        super(s);
        for(float a,v;
            n-->0;
            System.out.println(v*Math.sqrt(-2*Math.log(a)/a)))
                for(a=0;
                    a>=1|a==0;
                    a=v*v+(v=2*nextFloat()-1)*v)v=2*nextFloat()-1;
    }
}
Geobits
quelle
2
+1 für die Verwendung von Marsaglia (oder besser gesagt für die Nicht-Verwendung des unkomplizierten Box-Muller);)
Martin Ender
Kann das nicht ein Lambda sein? So etwas wie:(s,n)->{java.util.Random r=new java.util.Random(s);for(float a,v;n-->0;System.out.println(v*Math.sqrt(-2*Math.log(a)/a)))for(a=0;a>=1|a==0;a=v*v+(v=2*r.nextFloat()-1)*v)v=2*r.nextFloat()-1;}
Justin
2
@Quincunx Ich könnte für ein Byte. Aber ich mag es nicht, meine Funktionserklärungen in ungezähltem Code zu verstecken, ungeachtet des aktuellen Konsenses über Meta darüber. Es ist mir das eine Byte wert;)
Geobits
2

T-SQL, 155 Bytes

CREATE PROC R(@S BIGINT,@N INT)AS
DECLARE @ INT=0,@K INT=8388607WHILE @<@N
BEGIN
SELECT SQRT(-2*LOG(RAND(@S*@%@K)))*COS(2*PI()*RAND(@S*9*@%@K))SET @+=1
END

Verwendung mit EXEC RS, N, da in T-SQL keine STD_IN vorhanden ist, wobei S und N der Startwert bzw. N sind. S wird "zufällige" (RAND (seed) ist eine wirklich schlechte Zufallszahlenimplementierung) Sequenzen erzeugen, wenn S> 2 ^ 16 (möglicherweise vorher, aber ich kann es nicht garantieren). Verwendet Box-Muller wie die meisten bisherigen Lösungen. 8388607 ist 2 ^ 23-1, was hoffentlich 2 ^ 20 verschiedene Werte erzeugen sollte.

Markierungen
quelle
2

Powershell, 164 Bytes

Param($s,$n)$q=2147483647
$a=GET-RANDOM -SETSEED $s
FOR(;$n---gt0;){$a=GET-RANDOM
$b=GET-RANDOM
[math]::SQRT(-2*[math]::LOG($a/$q))*[math]::COS(2*[math]::PI*$b/$q)}

Wie die meisten Antworten bei Box-Muller. Mit Powershell nicht sehr erfahren, daher wäre jede Hilfe beim Golfen willkommen.

Markierungen
quelle
2

Ruby, 72 Bytes

->n,s{include Math;srand s;n.times{p sqrt(-2*log(rand))*sin(2*rand*PI)}}

Eingabe (als Lambda-Funktion):

f.(6, 12353405)

Ausgabe:

-1.1565142460805273
0.9352802655317097
1.3566720571574993
-0.9683973210257978
0.9851210877202192
0.14709635752306677

PS: Ich würde gerne wissen, ob dies weiter golfen werden kann. Ich bin nur ein Anfänger.

Zero Fibre
quelle
@ MartinBüttner Ich glaube, ich habe in diesen Tagen zu viel C verwendet. Völlig vergessen.
Zero Fibre
2

Matlab, 77

Der erste Eingang sollte nder zweite sein s.

a=input('');
rand('seed',a(2));
for i=1:a;
    (-2*log(rand))^.5*cos(2*pi*rand)
end
Fehler
quelle
2

Oktave, 91 96 88 Bytes

function r=n(s,n)rand("seed",s);x=rand(2,n);r=cos(2*pi*x(1,:)).*sqrt(-2*log(x(2,:)));end

Oder mit Leerzeichen:

function r=n(s,n)
  rand("seed",s);
  x=rand(2,n);
  r=cos(2*pi*x(1,:)).*sqrt(-2*log(x(2,:)));
end

Stellen Sie den Samen nach vorne und verwenden Sie die Box-Mueller-Methode.

Anmerkung: Octave ermöglicht die Erzeugung von Arrays mit Zufallszahlen und kann Standardoperationen für diese Arrays verwenden, die Arrayausgaben erzeugen. Der .*Operator ist eine elementweise Multiplikation zweier Arrays, um das Ergebnis zu erhalten.

dcsohl
quelle
Ich denke, das erfüllt nicht die Bedingungen, wenn Sie anrufen n(0,1)und n(0,2)unterschiedliche erste Nummern erhalten, oder?
Fehler
Mist, du hast recht. Ich habe es behoben, aber es hat mich 5 Bytes gekostet ...
dcsohl
2

Pyth, 32 Bytes

Wegen der neuen Funktionen, die Pyth jetzt hat, wird jetzt kein Python mehr in Super-Anführungszeichen verwendet. Noch ein Box-Müller.

 .xvzVQ*@_y.lOZ2.71 2.ty*3.14OZ1

Dieser Raum am Anfang ist wichtig.

.xvz             Seed RNG with evaluated input
VQ               For N in second input
*                Multiplication
 @       2       Square root
   _y            Times negative 2
    .l )         Natural log
     OZ          Of random float (RNG with zero give [0, 1) float)
 .t       1      Cosine from list of trig functions
  y              Double
   *             Multiplication
    .nZ          Pi from constants list
    OZ           Random Float

Das Seeding scheint im Online-Interpreter nicht zu funktionieren, funktioniert aber in der lokalen Version einwandfrei. Der Online-Interpreter scheint repariert zu sein. Hier ist ein Permalink: Permalink

Maltysen
quelle
1
Dies verwendet eine Funktion von Pyth ( .nZ), die bei der Beantwortung der Frage nicht implementiert war. (Es wurde heute tatsächlich implementiert.) Daher sollte diese Antwort nicht Teil des Wettbewerbs sein ( meta.codegolf.stackexchange.com/questions/4867/… ).
Jakube,
K, ich komme zurück auf die 32-
Zeichen-
Ja, das wäre besser. Sie können Ihre neue Lösung immer noch in einem separaten Abschnitt Ihrer Antwort vorstellen. Aber der Code, mit dem Sie konkurrieren, sollte derjenige sein, der mit dem alten Pyth arbeitet.
Jakube
1
Übrigens denke ich nicht, dass die 32-Lösung auch gültig sein sollte. Da wird der zufällige Startwert initialisiert, der erst vor ca. 5 Tagen hinzugefügt wurde.
Jakube,
1

STATA, 85 Bytes

di _r(s)_r(n)
set se $s
set ob $n
g a=sqrt(-2*ln(runiform()))*cos(2*runiform()*_pi)
l

Übernimmt die Eingabe über den Standardeingang (erste Zahl ist S, dann N). Setzt den Startwert auf S. Setzt die Anzahl der Beobachtungen auf N. Erstellt eine Variable und setzt ihren Wert auf den Box-Muller-Transformationswert (danke an @Alex für die Anzeige). Listet dann alle Beobachtungen in einer Tabelle mit der Spaltenüberschrift a und den Beobachtungsnummern daneben auf. Wenn dies nicht in Ordnung ist, lassen Sie es mich wissen und ich kann Überschriften und / oder Beobachtungsnummern entfernen.

Markierungen
quelle
1

R, 89 Bytes

Ich weiß, dass R schon einmal gemacht wurde, aber ich wollte einen anderen Ansatz zeigen als der Box-Müller, den alle anderen benutzten. Meine Lösung verwendet den zentralen Grenzwertsatz .

f=function(S,N){set.seed(S);a=1000;for(i in(1:N)){print(sqrt(12/a)*(sum(runif(a))-a/2))}}
Michal
quelle
1
Ich fürchte, der zentrale Grenzwertsatz erfüllt nicht "den Algorithmus, den Sie wählen, muss eine theoretisch genaue Normalverteilung ergeben". Egal wie viele einheitliche Variablen Sie addieren, solange die Summe endlich ist, ist die Normalverteilung immer ungefähr. (Obwohl der zentrale Grenzwertsatz eine gute Idee ist, musste ich ihn genau ausschließen, da nicht klar ist, welcher Wert ain Ihrem Code verwendet werden soll, damit das Ergebnis "fair" ist.)
Martin Ender
1
Es war einen Versuch wert;)
Michal
1

TI-Basic, 74 Bytes

Prompt S,N:S→rand:For(X,1,N:0→A:0→V:0→W:While A≥1 or A=0:2rand-1→V:2rand-1→W:V²+W²→A:End:Disp VW√(Aֿ¹-2log(A:End

1      1111111   11   1111111111111111111     1111   111111   1111111   11111111111111  11    111111111   111

Das ¹ist eigentlich der inverse Operator.

Ypnypn
quelle
1

Perl, 150 108 107 Bytes

Dies nutzt die Marsaglia Polar Methode . Wird mit f (S, N) aufgerufen.

Verschoben die Zuordnung von $a in die Berechnung von $c.

107

sub f{srand$_[0];map{do{$c=($a=-1+2*rand)**2+(-1+2*rand)**2}until$c<1;print$a*sqrt(-2*log($c)/$c)}1..$_[1]}

Reservenummernspeicher und die Definition von entfernt $b.

108

sub f{srand$_[0];map{do{$a=-1+2*rand,$c=$a**2+(-1+2*rand)**2}until$c<1;print$a*sqrt(-2*log($c)/$c)}1..$_[1]}

150

sub f{srand$_[0];map{$h?$h=!print$s:do{do{$a=-1+2*rand,$b=-1+2*rand,$c=$a*$a+$b*$b}until$c<1;$d=sqrt(-2*log($c)/$c);$s=$b*$d;$h=print$a*$d;}}1..$_[1]}
Bonsaigin
quelle
1

Swift, 144 142

Nichts Schlaues, nur zu sehen, wie Swift funktioniert.

import Foundation;func r(s:UInt32,n:Int){srand(s);for i in 0..<n{println(sqrt(-2*log(Double(rand())/0xffffffff))*sin(2*Double(rand())*M_PI))}}

Ich hatte gehofft, ich könnte (0 ... n) .map {} verwenden, aber der Compiler scheint map {} nur zu erkennen, wenn Sie einen Parameter verwenden.

GoatInTheMachine
quelle
natürlich...? Es ist,forEach wenn Sie keinen Rückgabewert möchten, und ich bin mir ziemlich sicher, dass dies _ inobligatorisch ist
ASCII
Was ist das /0xfffffffffür BTW
ASCII
1

Haskell , 97 Bytes

import System.Random
h(a:b:c)=sqrt(-2*log a::Float)*cos(2*pi*b):h c
f a=take a.h.randoms.mkStdGen

Probieren Sie es online!

Nur Ihre grundlegende Box-Muller-Transformation auf einer unendlichen Liste von Zufallszahlen.

Angs
quelle
0

SmileBASIC, 81 Bytes

Nun, nachdem ich die erste Frage beantwortet habe, muss ich den Rest erledigen ...

Das Erzeugen von Zufallszahlen ist billig, aber das Seeding des RNG verwendet die längste in der Sprache eingebaute Funktion RANDOMIZE.

DEF N S,N
RANDOMIZE.,S
FOR I=1TO N?SQR(-2*LOG(RNDF()))*COS(PI()*2*RNDF())NEXT
END

Vielleicht gibt es eine Möglichkeit, die Formel zu optimieren. Ich verstehe nicht, wie es erforderlich ist, zwei RNG-Aufrufe zu verwenden.

12Me21
quelle
Es ist erforderlich , um zwei unabhängige Proben für die Box-Muller - Transformation haben
ASCII-only