2012-04-26 54 views
0

計算我有了這個代碼,計算複數的複雜的權力:優化的JavaScript中複數的複雜權力的準確性

var ss = a.re*a.re + a.im*a.im; 
var arg1 = math.arg(a); 
var mag = Math.pow(ss,b.re/2) * Math.exp(-b.im*arg1); 
var arg = b.re*arg1 + (b.im * Math.log(ss))/2; 
return math.complex(mag*Math.cos(arg), mag*Math.sin(arg)); 

(複數看起來像{回覆:1,即時通訊:1} ,而math.arg只給出Math.atan2(n.im.n.re)。math.complex是複數的構造函數)

這不是特別複雜,我也不是很精通效率/準確度分析。

我希望在複數的整數次冪上得到更好的結果,因爲用二項式展開可以更準確地做到這一點。有沒有人有類似的東西寫在在JavaScript,在我離開之前做我自己的?我並不十分擔心速度,更關心準確性。

回答

0

因此,您的代碼將複數轉換爲極座標形式,然後應用基本的指數規則。

你說你喜歡的東西像(A + BI)^ N = [第n次多項式擴張]

你說你關心的準確性。

有不準確的三個來源,我能想到

  • JavaScript的數字:如果你正在使用JavaScript,這是很危險的關心準確性。整數實際上是浮點數,如果使用非常大的數字,則可以使用整數得到精度錯誤。被警告。
  • 數學函數:Math.pow和Math.atan2如何準確計算其結果。如果需要,你可以研究這個。
  • 四捨五入錯誤:如果執行大量操作來展開與域/原像相關的操作的範圍/圖像,則可能會導致舍入錯誤。

還有一個低效率的來源是關心:用多項式展開計算z^n將花費O(n)時間和O(n)空間,這絕對是可怕的。您可以使O(log(n))時間和O(1)或O(log(n))空間(與之前的O(1)時間和空間相反)變得很糟糕(仍然非常糟糕),通過將指數n分解爲其二進制表示。

最後,你仍然在計算一個浮點表示。當你可以執行(基本上)一個操作時,沒有理由執行一連串的操作來計算它;除非該操作非常不準確,否則您應該期望您的錯誤少於您執行的操作次數。

對準確性會有什麼更深刻的影響是您希望處理的數字的分佈(非常小,非常大,兩者等)和表示的選擇(例如,如果您選擇自然地表示它們極地或笛卡爾形式)。例如,如果您計劃進行大量的加減運算,則可能會減少笛卡兒的舍入誤差和速度。如果你打算做大量的乘法和除法運算,或者按照指數級進行工作,你可能會減少舍入誤差,加快極點速度。

+0

你是什麼意思? '(1 + i)^ 5'不等於'1^5 + i^5'。 – 2012-04-26 12:06:57

+0

@ChristianPerfect:哦,對不起,我沒有看到你說的話「我不是很擔心速度,更關心準確性」;由於您對效率/準確度分析的評論,我認爲您暗示您擔心效率。我將編輯我的答案... – ninjagecko 2012-04-26 12:46:10

+0

這是一個普通的數學軟件包,作爲基於瀏覽器的數學評估系統的一部分,所以我不希望使用特別大的數字。我認爲無處不在的整數係數將是最常見的用途。 這是一個問題,原因是(1 + i)^ 5使用logs-and-trig方法評估{re:-4.0000000001,im:-4},這非常煩人。 – 2012-04-26 13:26:55

0

如果你只關心的整數次冪,最準確的是隻將它們相乘:

var Re = 0, Im = 1; 
var newRe = 1, newIm = 0; 
var retRe = 1, retIm = 0; 
for(var i = 0; i < n; i++) 
{ 
    newRe = retRe * Re - retIm * Im; 
    newIm = retRe * Im + retIm * Re; 
    retRe = newRe; 
    retIm = newIm; 
} 
+0

這不是一個壞主意! – 2012-04-27 09:59:56