如果你正在做我認爲你是的那麼你想要乘以不同的波數傅立葉變換乘以拉普拉斯算子的特徵值導出的不同係數。
喜歡的東西
lambda(kx, ky, kz) = (kx**2 + ky**2 + kz**2)
通知的1,4和9中的 「矩陣」。他們是這些正方形kx**2
。
這不是一個矩陣求逆,它實際上只是用表格形式寫出的數字除以1.0。該表看起來像一個矩陣,因爲你的代碼是2D的,所以你只有lambda(kx, ky)
。
爲拉普拉斯算子,整個實際矩陣將是非常大的(N倍N,在2D其中N = nx*ny
和N = nx*ny*nz
在3D),希望對角和零其他地方的lambda
秒。逆矩陣將在對角線上具有1./labda
。因此,您的操作在某種意義上是矩陣求逆,但與您的想法不同。
你比什麼做是
FT(kx,ky,kz) = FT(kx,ky,kz)/(kx**2 + ky**2 + kz**2)
其也可以寫成
FT = FT * inv_laplacian
其中
inv_laplacian = 1./laplacian
其中laplacian
是係數(特徵值)陣列。
這不是矩陣求逆,它只是將數字除以1.0。
現在,用0特徵值做什麼?如果不啓用浮點異常捕獲的,我建議你反對讓他們,那麼你只是做:
FT = FT * inv_laplacian
因爲inv_laplacian(0,0,0)
是0,FT(0,0,0)是除以0和未定義(NaN或類似物)。你可以將它設置爲任何你想要的。 FT(0,0,0)
的含義是您的字段的平均值,這是任意的。所以,只是
FT(0,0,0) = 0 !or any number you want
就是這樣。
BTW,我看到了一個真實的世界科學的代碼,甚至極端的做法,如:
for i =0, nkx-1
for j =0, nkx-1
for k =0, nkx-1
FT(i, j, k) = FT(i, j, k)/(cos(i*ax) + cos(j*ay) + cos(k*az)
end
end
end
它經歷了千百年來計算。這與你的情況非常相似,你的特徵值不是餘弦,而是正方形。
問題是係數在時間上是恆定的,可分離的。
人們可以只計算一次:
lambdax(i) = i**2 !or cos(ax*i)
lambday(i) = j**2 !or cos(ay*j)
lambdaz(i) = k**2 !or cos(az*k)
,然後做
FT(kx,ky,kz) = FT(kx,ky,kz)/(lambdax(kx) + lambday(ky) + lambdaz(kz))
你可以看看我的快速泊松求解程序PoisFFT的源代碼,看看一個例子https://github.com/LadaF/PoisFFT/blob/master/src/poisfft-solvers-inc.f90並找到適當的邊界條件。您的情況很可能是第152行的PoisFFT_Solver2D_FullPeriodic。
您很少想要在科學計算中反轉矩陣。即使設法獲得矩陣求逆,在計算之後使用也比使用LU分解要慢。最後你想解決一個線性系統,不是嗎?你不需要矩陣求逆。 –
我同意弗拉基米爾。不僅是反向不必要的,它們傾向於在數值上不穩定 - 原始矩陣中的小改變可以在反轉中產生大的變化,所以舍入誤差被放大。而L-U分解是一種更好的方法。 – Jack