Mathematica中如何對矩陣內元素並行計算?
首先有一個矩陣,中心元素的值為,其餘為. 稱大於等於的值為「冰」,其餘為「水」。
L = 9; alpha = 0.501; beta = 0.3; gamma = 0.0001;
a = ConstantArray[beta, {L, L}];
a[[Ceiling[L/2], Ceiling[L/2]]] = alpha;
初始化與
a1 = ParallelMap[If[# &>= alpha, # + gamma, 0] , a, {2}];
a2 = ParallelMap[If[# &< alpha, #, 0] , a, {2}];然後掃一遍中的元素,把「冰」和其周邊元素存入,把剩餘的存入,然後再在中的非零元素上加上(冰的增長率)。
Do[If[Total[
Boole[{a[[i, j]] &>= alpha, a[[i, j + 1]] &>= alpha,
a[[i, j - 1]] &>= alpha, a[[i + 1, j]] &>= alpha,
a[[i + 1, j + 1]] &>= alpha, a[[i + 1, j - 1]] &>= alpha,
a[[i - 1, j]] &>= alpha, a[[i - 1, j + 1]] &>= alpha,
a[[i - 1, j - 1]] &>= alpha}]] &>= 1,
a1[[i, j]] = a[[i, j]] + gamma; a2[[i, j]] = 0;,
a2[[i, j]] = a[[i, j]]; a1[[i, j]] = 0;], {i, 2, L - 1}, {j, 2,
L - 1}];
得到結果(當時)。
a1 // MatrixForm
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0.3001 0.3001 0.3001 0 0 0
0 0 0 0.3001 0.5011 0.3001 0 0 0
0 0 0 0.3001 0.3001 0.3001 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
a2 // MatrixForm
0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3
0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3
0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3
0.3 0.3 0.3 0 0 0 0.3 0.3 0.3
0.3 0.3 0.3 0 0 0 0.3 0.3 0.3
0.3 0.3 0.3 0 0 0 0.3 0.3 0.3
0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3
0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3
0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3
結果是正確的,但是當的值很大時,速度會變慢很多。
我嘗試用ParallelDo代替Do,但是有side-effect。
有沒有其他辦法並行計算呢?
應當避免在Mathematica中使用Do之類的函數。幾乎在所有情況下,Do都可以被其他函數替代,並且計算效率更高。
alpha = 0.501; beta = 0.3; gamma = 0.0001;
a = ReplacePart[ConstantArray[beta, {9, 9}], {5, 5} -&> alpha];
Block[{p1, p2},
p1 = UnitStep[a - alpha];
p2 = Sign@ListConvolve[BoxMatrix[1], p1, {{2, 2}}];
a1 = p2*(beta + gamma) + p1*(alpha - beta);
a2 = (1 - p2)*beta;]
p1挑選出了a中大於alpha的那些元素記1,其餘記0;
p2挑選出了a中任意相鄰元素大於alpha的那些元素記1,其餘記0。
ListConvolve可以用於快速的判斷相鄰元素的狀態。推薦閱讀:
※下面這個mathematica語句怎麼理解?
※Mathematica導入牆外網頁數據失敗,軟體內如何實現科學上網?
※理論物理學生如何用mathematica記錄筆記並進行管理?
※Matlab 怎麼填充曲線相交的區域呢?
※Mathematica如何導入某個csv或者excel文件的指定行和列?
TAG:演算法 | 數學 | WolframMathematica | 並行計算 |