JSL für das Video.
picpath = ""; // "D:\Chales\pic\m";
//http://www.fractalforums.com/mandelbrot-and-julia-set/good-coordinates-for-mandelbrot-zooms/
//
//Points on the boundary of the Mandelbrot set generally have the most interesting orbits. The easiest boundary points to compute are:
//
//* the spike along the negative real axis
//* the boundary of the main cardioid: r = (1 - cos(theta))/2, x = r*cos(theta)+0.25, y = r*sin(theta)
//* the boundary of the period 2 disk: r = 0.25, x = r*cos(theta)-1, y = r*sin(theta)
eps = 1.6; // slightly outside
deep = 10;
steps = 8000;
angle = 3;
scale = 2; // <<<<<<< video made with 20, very slow
xsize = 192 * scale;
ysize = 108 * scale;
diag = Sqrt( xsize ^ 2 + ysize ^ 2 );
mat = J( ysize, xsize, . );
New Window( "mandelbrot", bb = Border Box( Text Box( "wait" ) ) );
Wait( .2 );
num = 1e6;
For( t = 0, t < steps, t += 1,
If( eps > 1e-9, eps *= .997 );
deep += .3;
angle += eps / 50;
radius = (1 - Cos( angle )) / 2 + eps;
x = radius * Cos( angle ) + 0.25;
y = radius * Sin( angle );
top = y - eps;
bottom = y + eps;
left = x - eps * xsize / ysize;
right = x + eps * xsize / ysize;
d = Floor( Min( 1e5, deep ) );
Parallel Assign( {d = d}, mat[r( top, bottom ), c( left, right )] = Mandelbrot( d, 4, c, r ) );
mat = mat / d;
red = mat ^ .5;
green = mat ^ 9;
both = Loc( red :*</img> green == 1 );
red[both] = .1;
green[both] = .4;
blue = 1 - mat ^ .2;
blue[both] = .1;
img = New Image( "rgb", {red, green, blue} );
(bb << child) << delete;
bb << append( img );
num += 1;
If( picpath != "", img << saveimage( picpath || Char( num ) || ".png" ) );
bb << updatewindow;
Wait( 0 );
);
Es sieht so aus, als hätte ich das nie dokumentiert. Ich werde sehen, was ich tun kann.
Ja, es wird eine lineare Interpolation von 1..nrows nach oben..unten durchgeführt. (Ähnlich für c, ncols, left, right).
Wenn Sie das Bit (oben, unten) weglassen, ist der r-Wert im Ausdruck 1..nrows.
Auch der Teil {d = d} muss erklärt werden. Jeder Thread erhält eine eigene Kopie von allem, was er als Referenz benötigt; Die Variable auf der linken Seite ist der Name des Arbeitsthreads und die rechte Seite ist der Name des Hauptthreads. Auf einem 4-CPU-Rechner wird diese Zuweisung viermal durchgeführt. Wenn Sie eine große Matrix kopieren, sehen Sie möglicherweise keine Leistungsverbesserung.
Mandelbrot benötigt keine weiteren Daten und lässt sich gut skalieren. Die meisten echten Probleme erfordern das Lesen von einem anderen Array und möglicherweise auch eine Buchhaltung.
Wenn Sie einen Blick unter die Decke werfen möchten, versuchen Sie Folgendes:
m=J(10,10,0);
x=0;
parallelassign({x=x++},m[r,c]=x);
show(x,m);
Meine 8-CPU-Maschine erzeugt Folgendes:
x = 8;
m =
[ 0 1 2 3 4 5 6 7 0 1,
2 3 4 5 6 7 0 1 2 3,
4 5 6 7 0 1 2 3 4 5,
6 7 0 1 2 3 4 5 6 7,
0 1 2 3 4 5 6 7 0 1,
2 3 4 5 6 7 0 1 2 3,
4 5 6 7 0 1 2 3 4 5,
6 7 0 1 2 3 4 5 6 7,
0 1 2 3 4 5 6 7 0 1,
2 3 4 5 6 7 0 1 2 3];
Sie sollten natürlich keinen Code schreiben, der von diesem Muster abhängt.
Beachten Sie auch, dass die Zuweisung auf der rechten Seite der Matrix komplizierter sein kann.
m=J(400,600,0);
parallelassign({},m[r(-1,1),c(-1,1)]=(
z=sqrt(r^2+c^2);
z=if(z<.707,.707,z)-.5;
1-z; // last item in ; sequence is result
));
m=m/max(m); // for heat color
newwindow("example",newimage(heatcolor(m,"spectral")));
„z“ existiert nur innerhalb jedes Threads, für jeden eine separate Kopie.
That flat area, dark red, was created by the if statementThat flat area, dark red, was created by the if statementThat flat area, dark red, was created by the if statementThat flat area, dark red, was created by the if statementDieser flache, dunkelrote Bereich wurde durch die if-Anweisung erstellt
Und ja, Sie können for-Anweisungen verwenden. Sie sollten nicht versuchen, irgendeine Form von E/A durchzuführen, außer in das Protokoll zu schreiben. Erstellen Sie keine Anzeigeboxen, aktualisieren Sie keine Anzeigeboxen, lesen oder schreiben Sie keine Festplattendateien. Wenn es nicht abstürzt, ist es immer noch falsch.
Sie können Globals verwenden, diese verwenden jedoch einen Mutex, um den Zugriff zu serialisieren, und der Code ist möglicherweise nicht schneller als Code ohne Thread.
m=J(3,5,0);
global:words="";
parallelassign({},m[r(-1,1),c(-1,1)]=(
z=sqrt(r^2+c^2);
show(r+0,c+0,r+c,z); // r and c are special, use an expression
global:words||=char(z);
z=if(z<.707,.707,z)-.5;
1-z; // last item in ; sequence is result
));
show(words);
global:words wird in einer unvorhersehbaren Reihenfolge erstellt, die davon abhängt, wie schnell verschiedene Threads ausgeführt werden.
JSL ist (intern) kompliziert, ebenso wie das Threading. Die Parallelassign-Funktion versucht, alles in Ordnung zu halten (z. B. diese Kopien). Wenn Sie eine Möglichkeit finden, etwas zu umgehen, von dem Sie abgehalten werden sollen, beschädigen Sie möglicherweise interne Datenstrukturen, wenn zwei Threads gleichzeitig darauf zugreifen, und das führt irgendwann zum Absturz von JMP. Sparen Sie oft.
Oh ... eine letzte Anmerkung zu 1D-Matrizen: Verwenden Sie zwei Indizes! Es gibt einige verwirrende Situationen, wenn Sie einen 1xN-Zeilenvektor haben und versuchen, einen einzelnen Index zu verwenden. Verwenden Sie R,C und ignorieren Sie den konstanten Wert R==1.
Ich habe viel Spaß mit diesem Skript gehabt, einige Änderungen vorgenommen und die Bildserie erstellt, um sie in ein Video umzuwandeln, um meine eigenen Mandelbrot-Touren zu machen.
Frage: Die Parallel Assign()-Funktion – ich suche nach einer Syntaxreferenz dazu?Ich sehe es nicht in den JMP-Skriptbüchern, aber es gibt einen Eintrag im JMP-Skripthandbuch unter Hilfe.Mir ist nicht klar, was Sie mit der Parallel Assign-Funktion in Ihrem Skript machen.
Parallel Assign( {d = d}, mat[r( top, bottom ), c( left, right )] = Mandelbrot( d, 4, c, r ) );Was bewirken r(oben, unten) und c(links, rechts) für Sie?Oben, unten, links und rechts werden unmittelbar zuvor im Skript bestimmt, um die Koordinatengrenzen des Rahmens zu bestimmen, den Sie erstellen.Ich gehe davon aus, dass eine Art Interpolation zwischen oben, unten und links und rechts durchgeführt wird, um die zu verwendenden y- und x-Koordinaten zu erhalten.Gibt es irgendwo eine allgemeine Beschreibung dieser Syntax?