Probleme beim Zufalls-Punkte erzeugen [gelöst]

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Benutzeravatar
heinz
Beiträge: 361
Registriert: 20.12.2007 01:43:49

Re: Probleme beim Zufalls-Punkte erzeugen [fast gelöst] (eigene Dummheit)

Beitrag von heinz » 10.01.2019 19:39:29

Hallo,

es hat mir einfach keine Ruhe gelassen...

Mein derzeitiger Stand ist:

Code: Alles auswählen

int radX=2000;
int radY=1000;
int radZ=500;
double rad_faktorY=(double)radX/(double)radY;
double rad_faktorZ=(double)radX/(double)radZ;

while(count < 10000)
{
	double winkel=(double)(rand()%36000000)/100000.0;
	double winkelZ=(double)(rand()%36000000)/100000.0;
	double radius=rand()%radX;

	double XX=sin(winkelZ*(Pi/180.0)) * cos(winkel*(Pi/180.0)) * radius;
	double YY=( ( sin(winkelZ * (Pi/180.0)) * sin(winkel * (Pi/180.0)) ) / rad_faktorY ) * radius;
	double ZZ=( cos(winkelZ * (Pi/180.0)) / rad_faktorZ ) * radius;
}

Das Ergebnis sieht in der x/y-Achse jetzt gut aus
2013
aber nun habe ich das Problem auf der z-Achse...
2014

Werde das Projekt wohl vorerst aufgeben.
Meine Mathekenntnisse sind einfach nicht ausreichend...

Vielen Dank Euch allen fuer Eure Unterstuetzung.

Gruss heinz

reox
Beiträge: 1633
Registriert: 06.06.2006 22:09:47
Lizenz eigener Beiträge: MIT Lizenz
Kontaktdaten:

Re: Probleme beim Zufalls-Punkte erzeugen [aufgegeben]

Beitrag von reox » 11.01.2019 08:56:27

Kann es sein, dass das nur ein Artefakt ist, weil du die Achsen unterschiedlich skalierst?

Ansonsten schaut die Variante 3 Zufallszahlen: 2 Winkel + Radius gut aus.

Benutzeravatar
heinz
Beiträge: 361
Registriert: 20.12.2007 01:43:49

Re: Probleme beim Zufalls-Punkte erzeugen [aufgegeben]

Beitrag von heinz » 11.01.2019 16:01:30

Hallo reox,
reox hat geschrieben: ↑ zum Beitrag ↑
11.01.2019 08:56:27
Kann es sein, dass das nur ein Artefakt ist, weil du die Achsen unterschiedlich skalierst?
leider nicht.

Ich habe fuer die letzten Bilder

Code: Alles auswählen

int radX=2000;
int radY=2000;
int radZ=2000;
verwendet, weil man es dann besser erkennt. (Habe vergessen es dazu zu schreiben...)
Es ist egal welche Werte ich fuer x,y und z verwende, in der z-Achse ist eine starke haeufung bei nahe 0.

Gruss heinz

reox
Beiträge: 1633
Registriert: 06.06.2006 22:09:47
Lizenz eigener Beiträge: MIT Lizenz
Kontaktdaten:

Re: Probleme beim Zufalls-Punkte erzeugen [aufgegeben]

Beitrag von reox » 11.01.2019 16:49:02

Mhh interessant, also ich sehe dieses Phänomen auch:
2015 2016

Generiert mit:

Code: Alles auswählen

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

N = 10000

r = 1

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

theta = np.pi * np.random.rand(N)
phi = 2 * np.pi * np.random.rand(N)
radius = r * np.random.rand(N)

x = np.sin(theta) * np.cos(phi) * radius;
y = np.sin(theta) * np.sin(phi) * radius;
z = np.cos(theta) * radius

ax.scatter(x, y, z)
plt.show()
Eine Frage wäre jetzt: Wie kann man zB ein Histogramm erzeugen aus den Koordinaten um zu schauen ob die Verteilung passt?

Also es schaut so aus, als ob die Verteilung an den Polen größer ist. Nur warum? Offenbar erzeugt die Verteilung von phi und radius das erwartete Bild. Nur theta scheint nicht das zu tun was wir erwarten.

Edit: Theta darf nur werte zwischen [0, pi] haben. Ändert aber auch nichts am Bild.

Benutzeravatar
heinz
Beiträge: 361
Registriert: 20.12.2007 01:43:49

Re: Probleme beim Zufalls-Punkte erzeugen [aufgegeben]

Beitrag von heinz » 11.01.2019 17:53:15

reox hat geschrieben: ↑ zum Beitrag ↑
11.01.2019 16:49:02
Eine Frage wäre jetzt: Wie kann man zB ein Histogramm erzeugen aus den Koordinaten um zu schauen ob die Verteilung passt?
Also wenn ich die Z-Koordinaten aus der erzeugten POV-Datei mal nach der Haeufigkeit aufliste, erkennt man sehr gut
wie sie in der naehe von 0 zunimmt.
Habe die Nachkommastellen mal weggelassen und dann die Haeufigkeit der Werte ermittelt.

Code: Alles auswählen

grep '^translate' ./zufall.pov |cut -f3 -d','|tr -d '>'|cut -f1 -d'.'|sort -g|uniq -c >./z-h.txt
NoPaste-Eintrag40584
Erste Spalte=Haeufigkeit
Zweite Spalte=Z-Werte

Meintest Du sowas?

Gruss heinz

[Edit:]
Sorry, das war Quatsch.
Das zeigt nur die Anhaeufung um die Mitte.

reox
Beiträge: 1633
Registriert: 06.06.2006 22:09:47
Lizenz eigener Beiträge: MIT Lizenz
Kontaktdaten:

Re: Probleme beim Zufalls-Punkte erzeugen [aufgegeben]

Beitrag von reox » 11.01.2019 19:38:18

also was man schon sieht, ist ja dass x und y jeweils von 3 zufallszahlen abhängt aber z nur von zweien.
Und wenn man aus der Z Richtung drauf schaut, schauts ja gut aus.
Aber mir leuchtet das nicht ein warum das einen unterschied machen sollte...

Benutzeravatar
smutbert
Beiträge: 6525
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: Probleme beim Zufalls-Punkte erzeugen [aufgegeben]

Beitrag von smutbert » 11.01.2019 20:56:43

hab das einmal in r nachgestellt und im Histogramm ist der Unterschied deutlich zu sehen. Zum Nachdenken wieso bin ich noch nicht gekommen...

Bild

reox
Beiträge: 1633
Registriert: 06.06.2006 22:09:47
Lizenz eigener Beiträge: MIT Lizenz
Kontaktdaten:

Re: Probleme beim Zufalls-Punkte erzeugen [aufgegeben]

Beitrag von reox » 11.01.2019 21:01:41

smutbert hat geschrieben: ↑ zum Beitrag ↑
11.01.2019 20:56:43
hab das einmal in r nachgestellt und im Histogramm ist der Unterschied deutlich zu sehen. Zum Nachdenken wieso bin ich noch nicht gekommen...

Bild
Ok, 3 histogramme (dichteschätzer) sind besser als einer ;)
Gibt es eigentlich eine Möglichkeit Kreis oder Kugelkoordinaten (oder sagen wir n-dimensionale koordinaten) in einer einzigen Zahl zusammenzufassen? Gibt es da eine Ordnung die zB Koordinaten in Rationale Zahlen umbaut?

Benutzeravatar
Lohengrin
Beiträge: 3201
Registriert: 29.08.2004 00:01:05
Wohnort: Montsalvat

Re: Probleme beim Zufalls-Punkte erzeugen [aufgegeben]

Beitrag von Lohengrin » 15.01.2019 01:18:05

reox hat geschrieben: ↑ zum Beitrag ↑
11.01.2019 16:49:02

Code: Alles auswählen

theta = np.pi * np.random.rand(N)
phi = 2 * np.pi * np.random.rand(N)
radius = r * np.random.rand(N)

x = np.sin(theta) * np.cos(phi) * radius;
y = np.sin(theta) * np.sin(phi) * radius;
z = np.cos(theta) * radius
Also es schaut so aus, als ob die Verteilung an den Polen größer ist. Nur warum? Offenbar erzeugt die Verteilung von phi und radius das erwartete Bild. Nur theta scheint nicht das zu tun was wir erwarten.
Beachte die Fläche auf der Kugel zwischen dem theta-ten und dem (theta + epsilon)-ten Breitengrad!
Das hängt von theta ab. Je näher am Pol, desto kleiner diese Fläche.
Harry, hol schon mal das Rasiermesser!

Benutzeravatar
smutbert
Beiträge: 6525
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: Probleme beim Zufalls-Punkte erzeugen [aufgegeben]

Beitrag von smutbert » 15.01.2019 12:53:03

@heinz

Darf man zwischendurch einmal fragen wie die Verteilung aussehen soll?
Die größere Dichte in der Mitte ist gewünscht?
(Entschuldige, falls es schon im Thread steht, aber ich hab nichts gefunden.)

Benutzeravatar
Lohengrin
Beiträge: 3201
Registriert: 29.08.2004 00:01:05
Wohnort: Montsalvat

Re: Probleme beim Zufalls-Punkte erzeugen [aufgegeben]

Beitrag von Lohengrin » 17.01.2019 22:38:27

smutbert hat geschrieben: ↑ zum Beitrag ↑
15.01.2019 12:53:03
Darf man zwischendurch einmal fragen wie die Verteilung aussehen soll?
Die größere Dichte in der Mitte ist gewünscht?
Ich denke, dass die Verteilung über eine Kugelsphäre gleich sein soll. Das mit dem Radius soll unabhängig davon sein.

Mit theta=pi*Zufall (Zufall ist gleichverteilt auf [0,1]) haut das nicht hin, weil ein Breitengrad die Länge radius*2*pi*sin(theta) hat. Die Verteilung der theta muss so sein, dass das bei gleichem Radius eine gleiche Verteilung auf der Kugelsphäre ergibt.
Nun ist in jedem Punkt der Kugelsphäre der Winkel zwischen dem Meridian und der Ebene parallel zum Äquator ebenfalls theta, also bei Veränderung des theta das Verhältnis von der Änderung in z-Richttung zur Änderung des theta sin(theta). Wenn man auf der z-Achse gleichverteilt, und das dann auf den Meridian abbildet, passt es. Also ist theta=acos(2*Zufall - 1) passend.
Harry, hol schon mal das Rasiermesser!

Benutzeravatar
heinz
Beiträge: 361
Registriert: 20.12.2007 01:43:49

Re: Probleme beim Zufalls-Punkte erzeugen [aufgegeben]

Beitrag von heinz » 18.01.2019 19:12:31

Danke erstmal an diejenigen die sich noch gedanken ueber diese "Sache" machen.
smutbert hat geschrieben: ↑ zum Beitrag ↑
15.01.2019 12:53:03
Darf man zwischendurch einmal fragen wie die Verteilung aussehen soll?
Die größere Dichte in der Mitte ist gewünscht?
Ich wäre schon zufrieden wenn die Betrachtung von oben
2013
und von der Seite
2014
gleich aussehen wuerde, also keine "seltsamen" Anhaufungen ausser die im Zentrum.

MMn. ist die groessere Dichte in der Mitte eine andere Baustelle um die ich mich noch nicht gekuemmert habe.
Es wurde ja schon von hikaru geschrieben:
Für eine gleichmäßige Dichte in der Fläche musst du dafür sorgen, dass deine Punkte gleichmäßig auf dem Quadrat des Radius' verteilt sind.
Nach meinem Verstaendnis, je groesser der Radius um so groesser die Wahrscheinlichkeit fuer einen gesetzten Punkt. (Quadratisch zunehmend)
(Vlt. eine rand-Funktion die (Quadratisch) mehr grosse Zahlen (Radien) liefert als kleine.)
Ich denke/hoffe, das bekomme ich hin. Wollte nur erst mal die eine "Baustelle" beenden, bevor ich mit der naechsten beginne.
Lohengrin hat geschrieben: ↑ zum Beitrag ↑
17.01.2019 22:38:27
Ich denke, dass die Verteilung über eine Kugelsphäre gleich sein soll. Das mit dem Radius soll unabhängig davon sein.
Am Ende waere ich froh, beides zu haben (an-/abschaltbar), einmal mit haeufung bei kleinen Radien und einmal ohne.
Aber Du hast recht, die 3 Radien (x,y,z) sollen einzeln bestimmbar sein.

Viele Gruesse,
heinz

Benutzeravatar
smutbert
Beiträge: 6525
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: Probleme beim Zufalls-Punkte erzeugen [aufgegeben]

Beitrag von smutbert » 18.01.2019 23:32:42

So habe ich es jetzt probiert, allerdings wieder in r, weil es zu lange dauert bis ich in C etwas lauffähiges hinbekomme (falls ich es überhaupt schaffe):

Code: Alles auswählen

library("scatterplot3d")
library("car")

N=50
rx=1
ry=2
rz=1.5

phi=2*pi*runif(N)
theta=acos(2*runif(N)-1)

x=rx*cos(phi)*sin(theta)
y=ry*sin(phi)*sin(theta)
z=rz*cos(theta)

scatter3d(x, y, z, surface=FALSE)
Damit berechne ich, wie Logengrinn es geschrieben hat, Punkte, die auf der Oberfläche eines Ellipsoids gleich(mäßig) verteilt sind.
runif erzeugt gleich verteilte Zufallszahlen zwischen 0 und 1, das heißt da kommen Vektoren mit der Länge N (50) heraus. Mit dem letzten Befehl wird das Ergebnis geplottet, allerdings erscheint es wieder als Kugel, weil die Achsen einzeln automatisch skaliert werden (und ich habe es auf die Schnelle nicht geschafft die Skalierung fix vorzugeben).

Bild

Um nun das ganz Volumen gleichmäßig mit Punkten zu füllen, führe ich das ganze in einer Schleife aus und zwar mit einem Skalierungsfaktor, den ich mit den Werten im Beispiel in Hundertstelschritten von 1/100 bis 1 durchlaufen lasse und plotte jedes Mal die erzeugten Punkte.
Mit N=10 und den Nr=100 Skalierungsfaktoren sollten am Ende 1000 Punkte herauskommen.

Code: Alles auswählen

library("rgl")

N=10
Nr=100
rx=1
ry=2
rz=1.5

for(i in 1:Nr) {
	scale=i/Nr
	phi=2*pi*runif(N)
	theta=acos(2*runif(N)-1)

	x=scale*rx*cos(phi)*sin(theta)
	y=scale*ry*sin(phi)*sin(theta)
	z=scale*rz*cos(theta)
	
	plot3d(x, y, z, add=TRUE)
}
Bild

Es gibt keine bevorzugte Richtung mehr. Innen häufen sich die Punkte, weil bei den früheren Schleifendurchläufen trotz kleinerem Skalierungsfaktor/Radius gleich viele Punkte gibt wie bei den späteren Schleifendurchgängen. Ohne es jetzt genau durchdacht zu haben, wird man die Häufung los, indem man das Quadrat des Skalierungsfaktors in die Zahl der Zufallszahlen pro Schleifendurchgang einfließen lässt

Code: Alles auswählen

library("rgl")

N=20
rx=1
ry=2
rz=1.5

Nr=100

for(i in 1:Nr) {
	scale=i/Nr
	phi=2*pi*runif(N*scale^2)
	theta=acos(2*runif(N*scale^2)-1)

	plot3d(scale*rx*cos(phi)*sin(theta), scale*ry*sin(phi)*sin(theta), scale*rz*cos(theta), add=TRUE)
}
(das mit N*scale^2 als Anzahl der Zufallszahlen funktioniert in r, anderswo müsste man diese Zahl wohl auf einen Integerwert runden)
Bild

In weiterer Folge könnte man die Abhängigkeit der Dichte vom Radius beliebig ändern, zum Beispiel normalverteilte Zufallszahlen erzeugen und die dann als Skalierungsfaktoren verwenden oder ähnliches.
Zuletzt geändert von smutbert am 19.01.2019 20:39:50, insgesamt 1-mal geändert.

Benutzeravatar
Lohengrin
Beiträge: 3201
Registriert: 29.08.2004 00:01:05
Wohnort: Montsalvat

Re: Probleme beim Zufalls-Punkte erzeugen [aufgegeben]

Beitrag von Lohengrin » 19.01.2019 12:20:43

heinz hat geschrieben: ↑ zum Beitrag ↑
18.01.2019 19:12:31
Nach meinem Verstaendnis, je groesser der Radius um so groesser die Wahrscheinlichkeit fuer einen gesetzten Punkt. (Quadratisch zunehmend)
(Vlt. eine rand-Funktion die (Quadratisch) mehr grosse Zahlen (Radien) liefert als kleine.)
Ja, du brauchst eine Zufallsvariable, die eine Verteilung hat, wo die Wahrscheinlichkeitsdichte quadratisch wächst.
So etwas kannst du aus einer Gleichverteilung auf [0,1] erzeugen, indem zu das mit etwas Passendem auf [0,R] abbildest.

Ein Fachbegriff dazu ist Bildmaß. Eine Verteilung (zB Gleichverteilung auf [0,1]) wird durch die Zufallsvariable auf einen anderen Bereich (zB [0,R]) übertragen.
Auf diese Tour kann man auch Verteilungen erzeugen, die so sind, wie etwas, das man gerade gemessen hat. Wenn man zB tausend Messwerte hat, kann man sich 500 davon zufällig auswählen, damit die passende Zufallsvariable bauen, und dann mit Zufallswerten, die so sind wie diese 500, an den anderen 500 herumspielen. Aber man darf da nicht zu viel hineininterpretieren. Wenn man Pech hat, waren die einen 500 und die anderen 500 doch nicht voneinander unabhängig, man publiziert eine Sensation, und dann korreliert das doch nur mit dem Fahrplan der Straßenbahn (pünktlich alle 10 Minuten hat da was vibriert).

Wenn du etwas haben willst, wo "größeres aus [0,1] auf größeres in [0,R]" gilt, gibt es nur eine Lösung.
Beim Kreis (2-dimensional) geht das mit Wurzel.
Beweis: 0 wird auf 0 abgebildet, 1 auf R. Irgend ein x wird auf r abgebildet, also das Stück [0,x] auf das Stück [0,r]. Das Verhältnis der Kreisflächen mit r und R ist (r/R)^2. Im Kreis mit Radius r soll (r/R)^2 der Punkte liegen. Weil bei Gleichverteilung auf [0,1] das Stück von [0,(r/R)^2] das Gewicht (r/R)^2 hat, muss x=(r/R)^2 auf r abgebildet werden. Nach r aufgelöst ergibt das r=R*Wurzel(x).

Bei der Kugel (3-dimensional) geht es genauso. Das Verhältnis der Volumen mit Radius r und R ist (r/R)^3. Also muss x=(r/R)^3 auf r abgebildet werden. Nach r aufgelöst ergibt das r=R*Kubikwurzel(x).
heinz hat geschrieben: ↑ zum Beitrag ↑
18.01.2019 19:12:31
Lohengrin hat geschrieben: ↑ zum Beitrag ↑
17.01.2019 22:38:27
Ich denke, dass die Verteilung über eine Kugelsphäre gleich sein soll. Das mit dem Radius soll unabhängig davon sein.
Am Ende waere ich froh, beides zu haben (an-/abschaltbar), einmal mit haeufung bei kleinen Radien und einmal ohne.
Aber Du hast recht, die 3 Radien (x,y,z) sollen einzeln bestimmbar sein.
Was für drei Radien? Meinst du drei Radien vom Ellipsoid?
Das mit acos für theta geht nur, wenn das eine Kugel ist. Wenn du die Kugel verzerrst, dann hast du in jedem Ellipsoidsektor so viele Punkte, wie es der Raumwinkel der Elipsoidsphäre verlangt, und das ist dann je nach Richtung verschieden großes Volumen. Du müsstest da je nach Raumwinkel unterschiedlich viel reinwerfen.

Ich empfehle immernoch Montecarlo. Gleichverteilung im Raum geht mit kartesischen Koordinaten ganz leicht. Und was draußen liegt, ist leicht zu erkennen.
smutbert hat geschrieben: ↑ zum Beitrag ↑
18.01.2019 23:32:42
Damit berechne ich, wie Logengrinn es geschrieben hat, Punkte, die auf der Oberfläche eines Ellipsoids gleich(mäßig) verteilt sind.
Die sind auf den Raumwinkeln gleichmäßig verteilt. Auf der Fläche sind sie es nicht, weil du die Kugel verzerrt hast.
Wenn du es geschafft hast, Gleichverteilung auf einer Ellipsoidsphäre zu bauen, passt es im Volumen wieder nicht, weil je nach Richtung die Schalen unterschiedlich dicht liegen.

Dass du theta und phi vertauscht hast, könnte verwirren.
Harry, hol schon mal das Rasiermesser!

Benutzeravatar
smutbert
Beiträge: 6525
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: Probleme beim Zufalls-Punkte erzeugen [aufgegeben]

Beitrag von smutbert » 19.01.2019 20:47:09

Danke für die Erklärungen. Ich habe mir beim Übergang von der Kugel zu dem Ellipsoid zu wenig (eigentlich gar nichts) gedacht. (zumindest habe ich jetzt das phi/theta-Chaos aufgeräumt)

Antworten