Autor |
Beitrag |
AXMD
      
Beiträge: 4006
Erhaltene Danke: 7
Windows 10 64 bit
C# (Visual Studio 2019 Express)
|
Verfasst: Mo 19.01.09 12:39
Hallo!
Ich suche eine Möglichkeit, gleichverteilte Zufallszahlen vom Typ double in C# zu erzeugen. Random.NextDouble gibt eine Zahl zwischen 0.0 und 1.0 - ich möchte aber den gesamten double-Bereich abdecken. Hintergrund ist die Generierung beliebig verteilter Zufallsvariablen, wobei ich eine Gleichverteilung über den gesamten double-Bereich als Grundgerüst benötige.
Jemand eine Idee?
AXMD
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Mo 19.01.09 12:48
AXMD hat folgendes geschrieben : | eine Gleichverteilung über den gesamten double-Bereich |
Noch einmal nachgehakt: Das würde doch bedeuten, dass sich 99% der Zahlen in der Größenordnung von 10^306 bis 10^308 bewegen? Soll es nicht eher eine Exponentialverteilung sein?
_________________ >λ=
|
|
AXMD 
      
Beiträge: 4006
Erhaltene Danke: 7
Windows 10 64 bit
C# (Visual Studio 2019 Express)
|
Verfasst: Mo 19.01.09 13:24
Das Problem ist: wie kann man sonst sinnvoll einen prinzipiell unendlich großen Bereich auf einen endlich großen abbilden, ohne die Eigenschaften der jeweiligen Verteilung zu verlieren?
AXMD
|
|
jfheins
      
Beiträge: 918
Erhaltene Danke: 158
Win 10
VS 2013, VS2015
|
Verfasst: Mo 19.01.09 13:35
Mit einer abfallenden Exponentialverteilung. Das entspricht ja genau dem Double, da dieser ja kleine Zahlen viel besser auflöst als große Zahlen.
Du könntest also Exponent und Mantisse zufällig wählen und das dann in einen Double Konvertieren
Dann sind allerdings sehr viele sehr kleine Zahlen dabei ...
|
|
AXMD 
      
Beiträge: 4006
Erhaltene Danke: 7
Windows 10 64 bit
C# (Visual Studio 2019 Express)
|
Verfasst: Mo 19.01.09 13:46
jfheins hat folgendes geschrieben : | Dann sind allerdings sehr viele sehr kleine Zahlen dabei ... |
Das möchte ich ebenso wenig. Die Intention ist wie gesagt folgende: ich habe eine Funktion d(x), die gleichverteilte Zufallszahlen im Bereich [Double.Min,Double.Max] ausgibt. Wäre der Bereich [0,1] wäre das kein Problem, aber auf eine Gleichverteilung, die nur den Bereich [0,1] bedient, könnte ich beispielsweise keine Normalverteilung aufsetzen, da diese ja einen unendlich großen (x-)Wertebereich abdeckt. Die Normalverteilung war übrigens nur ein Beispiel - es geht natürlich auch um die Implementierung weiterer Verteilungen, die nicht nur den Bereich [0,1] bedienen.
AXMD
|
|
Horst_H
      
Beiträge: 1654
Erhaltene Danke: 244
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: Mo 19.01.09 13:49
Hallo,
ich kann mir nicht vorstellen, wo der Sinn der exponentiellen Verteilung liegen soll, bzw, was das mit der Gleichverteilung zu tun hat.
Sollen dann die Zahl anschliessend logarithmiert werden, um Zahlen von -308 bis +308 zu erzeugen, die haben immer noch 64 Bit.
Wenn mehr Auflösung verlangt ist, als die 64 Bit von random dann muss der Zufallszahlengenerator gewechselt werden.
Die Skalierung des Bereiches ]0..1[ auf zum Beispiel ]-100..100[ ändert die "Gleichverteilung" nicht.
Aber "Normalverteilung" ist doch was ganz anderes. de.wikipedia.org/wiki/Normalverteilung
Was denn nun
Gruß Horst
|
|
AXMD 
      
Beiträge: 4006
Erhaltene Danke: 7
Windows 10 64 bit
C# (Visual Studio 2019 Express)
|
Verfasst: Mo 19.01.09 13:54
Vielleicht habe ich mich etwas falsch ausgedrückt. Es geht darum, dass du basierend auf gleichverteilten Zufallsvariablen jede beliebige Verteilung über ihre CDF nachgebildet werden kann, so auch z.B. eine Normalverteilung. Dann erhält man z.B. normalverteilte Zufallsvariablen.
AXMD
|
|
Reinhard Kern
      
Beiträge: 591
Erhaltene Danke: 14
|
Verfasst: Mo 19.01.09 14:10
AXMD hat folgendes geschrieben : |
Das möchte ich ebenso wenig. Die Intention ist wie gesagt folgende: ich habe eine Funktion d(x), die gleichverteilte Zufallszahlen im Bereich [Double.Min,Double.Max] ausgibt. ...
|
Hallo,
wo ist da ein Problem? Um [0,1] abzubilden auf [Xmin,Xmax] must du doch bloss rechnen:
Xmm = X01 * (Xmax - Xmin) + Xmin (Mit Xmin = Double.Min und Xmax = Double.Max)
Logischerweise muss man dann mit Extended rechnen.
Gruss Reinhard
|
|
AXMD 
      
Beiträge: 4006
Erhaltene Danke: 7
Windows 10 64 bit
C# (Visual Studio 2019 Express)
|
Verfasst: Mo 19.01.09 14:13
Reinhard Kern hat folgendes geschrieben : | Logischerweise muss man dann mit Extended rechnen. |
Dumm nur, dass es eben diesen Datentyp in C# nicht gibt - daher suche ich nach einer anderen Lösung, sofern es überhaupt eine gibt
AXMD
|
|
Reinhard Kern
      
Beiträge: 591
Erhaltene Danke: 14
|
Verfasst: Mo 19.01.09 14:33
AXMD hat folgendes geschrieben : | Reinhard Kern hat folgendes geschrieben : | Logischerweise muss man dann mit Extended rechnen. |
Dumm nur, dass es eben diesen Datentyp in C# nicht gibt - daher suche ich nach einer anderen Lösung, sofern es überhaupt eine gibt
AXMD |
Hllo,
von so was darf man sich doch nicht aufhalten lassen - man könnte natürlich sich selbst einen erweiterten Zahlentyp basteln, aber wahrscheinlich hilft auch eine Umstellung:
Xmm = Xmin * (1 - X01) + Xmax * X01
Soweit ich das auf die Schnelle übersehen kann, liegen Zwischen- und Endergebnisse im erlaubten Bereich, notfalls kann man ja den Fall 0 (Xmm = Double.Min) und den Fall 1 (Xmm = Double.Max herausziehen. Alles mathematisch ziemlich elementar.
Gruss Reinhard
|
|
AXMD 
      
Beiträge: 4006
Erhaltene Danke: 7
Windows 10 64 bit
C# (Visual Studio 2019 Express)
|
Verfasst: Mo 19.01.09 14:48
Hallo Reinhard!
Danke für den Hinweis - oft übersieht man die offensichtlichsten Ansätze
Nun tritt dumerweise das auf, was Kha bereits angedeutet hat (alle Werte liegen um 10^307). Verfälscht es nicht beispielsweise eine Normalverteilung, wenn nur derart hohe Werte vorkommen, sodass sie (wie im Falle der Normalverteilung) quasi immer 0 sind? Je mehr ich mich mit diesem quasi kontinuierlichen Bereich auseinandersetze desto verwirrender wird es
AXMD
|
|
Horst_H
      
Beiträge: 1654
Erhaltene Danke: 244
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: Mo 19.01.09 14:50
Hallo,
es bleiben doch immer nur 64 Bit-Genauigkeit von random, auch wenn man akaliert auf den Umfang von 2x1024 Bit.-1e308 bis 1e308 und das sind nur die Ganzzahlen.
Bei einer solchen Skalierung wären nur wenige Werte besetzt.(eben 64 von 2048)
Wieso per CFD rechnen, wenn es für die stetigen Versteilungen doch fertige Formeln gibt.
de.wikipedia.org/wik...nlichkeitsverteilung
Wie hilft denn dort CDF .
Um eine beliebige Funktion selbst zu realisieren musst Du doch ernorm viele Durchläufe/Versuche machen.
Es ist mit nicht klar, was Dein Ziel ist.
Gruß Horst
|
|
AXMD 
      
Beiträge: 4006
Erhaltene Danke: 7
Windows 10 64 bit
C# (Visual Studio 2019 Express)
|
Verfasst: Mo 19.01.09 15:05
Hallo Horst!
Es geht wie gesagt darum, verschiedene Wahrscheinlichkeitsverteilungen für Zufallsgeneratoren zu implementieren. Ausgangspunkt dafür ist eine Zufallszahl aus einer Gleichverteilung, nennen wir sie einfach einmal r. Setze ich diese in die CDF meiner gewünschten Verteilung (z.B. einer Normalverteilung) ein, also y = CDF(r), so ist y eine normalverteilte Zufallsvariable, sofern ich genügend verschiedene y erzeuge.
Es geht nicht darum, die Verteilungen selbst möglichst genau zu berechnen, sondern lediglich darum, Zufallszahlen zu generieren, die möglichst exakt den Verteilungen folgen.
AXMD
|
|
Boldar
      
Beiträge: 1555
Erhaltene Danke: 70
Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
|
Verfasst: Mo 19.01.09 16:37
Kann man nicht einfach statt Trennung in Mantisse und Exponent eine trennung in Ganzzahl und Nachkommastellen vornehmen? Dann wären die Zahlen doch linear verteilt? Und die Genauigkeit des Cokmputersystems ist ja sowieso beschränkt?
Oder verstehe ich jetzt hier was von Grund auf falsch??
|
|
AXMD 
      
Beiträge: 4006
Erhaltene Danke: 7
Windows 10 64 bit
C# (Visual Studio 2019 Express)
|
Verfasst: Mo 19.01.09 16:44
Hallo Boldar!
Das löst das Problem nicht, da die eigentliche Schwierigkeit darin besteht, aus einem sehr großen (rein theoretisch unendlich großen) Bereich gleichverteilte Zufallszahlen zu gewinnen.
AXMD
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Mo 19.01.09 17:06
Ich habe Schwierigkeiten, mir eine Zufallsvariable über ganz R überhaupt vorzustellen (was auch daran liegen könnte, dass Wahrscheinlichkeitsrechnung in der Schule kein wirklich großes Thema ist  ). Mathematisch nicht, weil die Dichtefunktion doch eigentlich für jedes x 0 sein müsste, und auf einem Computer mit endlich viel Speicher erst recht nicht  . Das Intervall der Normalverteilung ist unendlich groß, ja, aber dahin kommt man imho nur mit endlichen Gleichverteilungen, wie sie eben Random liefert, z.b. darüber: de.wikipedia.org/wik...g#Box-Muller-Methode
_________________ >λ=
|
|
AXMD 
      
Beiträge: 4006
Erhaltene Danke: 7
Windows 10 64 bit
C# (Visual Studio 2019 Express)
|
Verfasst: Mo 19.01.09 17:33
Danke für den Hinweis. Werd ich mir mal genauer ansehen
AXMD
|
|
Martok
      
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: Mo 19.01.09 18:16
Kha hat folgendes geschrieben : | (was auch daran liegen könnte, dass Wahrscheinlichkeitsrechnung in der Schule kein wirklich großes Thema ist ) |
Hast dus gut
In einer der letzten c'ts des vergangenen Jahres wurde eine Bibliothek für den ganzen Kram bezüglich verschiedenen Verteilungen vorgestellt. Die Frage ist nur, ob das die C++-Neuerungen waren oder etwas echtes...
Und die Sache ist eben, dass man unendlich viele Zahlen generieren müsste, um auf eine gleichverteilung in R zu kommen. Großzahlarithmetik wär da noch ne Variante, das erspart dir die Ungenauigkeit von Reellen Datentypen. Aber ist eh akademisch das alles.
Der Link von Kha ist schon ganz passend 
_________________ "The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
|
|
Reinhard Kern
      
Beiträge: 591
Erhaltene Danke: 14
|
Verfasst: Di 20.01.09 02:07
AXMD hat folgendes geschrieben : |
Nun tritt dumerweise das auf, was Kha bereits angedeutet hat (alle Werte liegen um 10^307).
|
Hallo,
nicht dummerweise - das muss genau so sein. Der Bereich 10 ^ 307 umfasst ja 90% des zulässigen Intervalls, also müssen bei Gleichverteilung auch 90% der generierten Zahlen drin liegen. Wenn dich das stört, hast du deine eigenen Absichten nicht verstanden.
Gruss Reinhard
Nachtrag: würdest du deine Zufallszahlen wirklich auf die reellen Zahlen abbilden, würden im Durchschnitt garkeine mehr in den Double-Bereich fallen, denn sie müssen sich ja gleichmässig auf die Unendlichkeit verteilen. Es ist halt verdammt schwierig, eine Unendlichkeit zu füllen...
Nachtrag2: zur Klarifizierung: Zahlen der Grösse 10^307 machen 90% des von dir definierten Intervalls aus, Zahlen der Grösse 10^306 weitere 9%, 10^305 nochmal 0.9% usw usw.
|
|