优化javascript中复数复数幂的计算精度

时间:2012-04-26 11:01:48

标签: javascript math optimization

我有这个代码来计算复数的复杂权力:

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));

(复数看起来像{re:1,im:1},而math.arg只给出了Math.atan2(n.im.n.re).mathcomplex是复数的构造函数)

这并不是特别复杂,我对精度/准确度分析并不熟悉。

我希望得到更好的结果,特别是复数的整数幂,因为通过二项式扩展可以更精确地完成。在我自己创作之前,有没有人在javascript 中写过之类的内容?我并不十分担心速度,更关心准确性。

2 个答案:

答案 0 :(得分:0)

因此,您的代码将复数转换为极坐标形式,然后应用基本的指数规则。

你声称你更喜欢(a + bi)^ n = [n次多项式展开]

你说你关心准确性。

我可以想到三种不准确的来源

  • javascript号码:如果您使用的是javascript,那么关注准确性会很危险。整数实际上是浮点数,如果使用非常大的数字,则可以得到整数的精度错误。警告。
  • 数学函数:Math.pow和Math.atan2计算结果的准确程度。如果需要,你可以研究这个。
  • 舍入错误:如果执行大量操作来扩展与域/ preimage相关的操作范围/图像,则可能会加剧舍入错误。

还有一个低效率的问题需要关注:用多项式展开计算z ^ n将花费O(n)时间和O(n)空间,这是绝对可怕的。

你可以花费O(log(n))时间和O(1)或O(log(n))空间(仍然相当糟糕,而不是之前的O(1)时间和空间),将指数n分解为二进制表示。

最后,您仍在计算浮点表示。当你可以执行(基本上)一个操作时,没有理由执行一系列的操作来计算它;除非该操作非常不准确,否则您应该期望您的错误少于您执行的操作。

对准确性产生更深远影响的是你期望使用的数字的分布(非常小,非常大,两者等)和表示的选择(例如,如果你选择在极地中自然地表示它们)或笛卡尔形式)。例如,如果您计划进行大量的加法和减法,那么使用笛卡儿可以获得更少的舍入误差和更快的速度。如果你计划进行大量的乘法和除法和取幂,或者以指数标度工作,你可能会得到更少的舍入误差和更快的极性。

答案 1 :(得分: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;
}