JSL 的影片。
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 );
);
酷,第一個是最難的。 我選擇了使用 Blender(內部使用 ffmpeg)而不是直接使用 ffmpeg 的稍微不同的路徑。 我放棄了對 ffmpeg 參數的一些控制(我不想花時間學習)並獲得一個非常酷的視訊序列編輯器作為交換(它有自己重要的學習曲線)。
感謝您提供有關並行分配()的詳細資訊!我的腦子裡充滿瞭如何使用它的想法。
看來我從未記錄過這一點,我會看看我能做什麼。
是的,它對 top..bottom 進行 1..nrows 的線性內插。 (與 c、ncols、左、右類似)。
如果省略 (top,bottom) 位,則表達式中的 r 值將為 1..nrows。
{d = d} 部分也需要解釋。 每個線程都會獲得自己需要引用的所有內容的副本;左側變數是工作執行緒的名稱,右側是主執行緒的名稱。 在 4 CPU 機器上,該分配完成四次。 如果您正在複製的恰好是一個巨大的矩陣,您可能不會看到效能改進。
Mandelbrot 不需要其他資料並且可以很好地擴展。 大多數實際問題需要從另一個陣列中讀取,並且可能還需要進行一些簿記。
如果你想一探究竟,試試看這個:
m=J(10,10,0);
x=0;
parallelassign({x=x++},m[r,c]=x);
show(x,m);
我的 8-cpu 機器產生這個:
x = 8;
米=
[ 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];
當然,您不應該編寫依賴該模式的程式碼。
另請注意,矩陣分配的右側可能更複雜。
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」僅存在於每個執行緒內,每個執行緒都有一個單獨的副本。
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 statement此平坦區域,深紅色,是由 if 語句創建的
是的,您可以使用 for 語句。 除了寫入日誌之外,您不應嘗試執行任何形式的 I/O。 不要製作顯示盒,不要更新顯示盒,不要讀取或寫入磁碟檔案。 如果不崩潰,它仍然會出錯。
您可以使用全域變量,但它們使用互斥體來序列化訪問,程式碼可能不會比非執行緒程式碼快。
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 是以不可預測的順序建構的,由不同執行緒的運行速度決定。
JSL 很複雜(內部),執行緒也很複雜。 ParallelAssign 函數嘗試保持一切正常(例如,那些副本)。 如果您找到一種方法來解決它試圖阻止您做的事情,那麼當兩個執行緒同時存取內部資料結構時,您可能會損壞內部資料結構,這將導致 JMP 在某些時候崩潰。 經常保存。
哦...關於一維矩陣的最後一點注意:使用兩個下標! 如果您有 1xN 行向量並嘗試使用單一下標,則會出現一些令人困惑的情況。 使用 R,C 並忽略常數 R==1 值。
我對這個腳本很感興趣,做了一些修改並創建了圖像系列以轉換為視頻以製作我自己的曼德布羅之旅。
問題:並行賦值()函數-我正在尋找它的語法參考?我在 JMP 腳本編寫書籍中沒有看到它,但在《JMP 腳本指南》的「幫助」下有一個條目。我不清楚您在腳本中使用並行分配函數做什麼。
Parallel Assign( {d = d}, mat[r( top, bottom ), c( left, right )] = Mandelbrot( d, 4, c, r ) );r(上、下)和c(左、右)對你有什麼作用?頂部、底部、左側和右側是在腳本之前確定的,以確定您正在建立的框架的座標邊界。我假設它正在頂部、底部和左、右之間進行某種插值以獲得要使用的 y 和 x 座標?某處有這個語法的一般描述嗎?
歡迎,謝謝! 該影片也花了幾個小時來渲染,但它是 4K 解析度和數千幀。
我開始創作吉克斯80 年代的節目。渲染分形需要數小時的 microVAX 計算時間。感謝分享。