在javascript中优化复数的复数幂的计算以提高精度

在javascript中优化复数的复数幂的计算以提高精度,javascript,math,optimization,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:

我有一个计算复数的复数幂的代码:

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)。math.complex是复数的构造函数)

这并不特别复杂,我也不太精通效率/准确性分析


我想得到更好的结果,特别是复数的整数幂,因为用二项式展开可以更精确地得到。在我开始制作自己的脚本之前,有没有人已经用javascript编写了类似的东西?我不太担心速度,更担心准确性。

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

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

你说你担心准确性

我能想到三种不准确的来源

  • javascript数字:如果您使用的是javascript,那么担心准确性是很危险的。整数实际上是浮点数,如果使用非常大的数字,可能会因此而导致整数的精度错误。被警告
  • 数学函数:Math.pow和Math.atan2计算结果的准确程度。如果需要,你可以研究一下
  • 舍入误差:如果执行大量操作,从而扩大了操作相对于域/前映像的范围/映像,舍入误差可能会加剧
还有一个效率低下的原因值得关注:用多项式展开计算z^n将花费O(n)时间和O(n)空间,这是绝对可怕的

通过将指数n分解为二进制表示,可以使它占用O(log(n))时间和O(1)或O(log(n))空间(与之前的O(1)时间和空间相比,仍然非常糟糕)

最后,您仍然在计算浮点表示。当你可以只执行一个操作时,没有理由执行一系列的运算来计算它;除非该操作极其不准确,否则您应该期望执行的操作越少,错误就越小


对准确性有更深远影响的是您希望使用的数字的分布(非常小、非常大,两者都有,等等)和表示方式的选择(例如,如果您选择自然地以极坐标或笛卡尔形式表示它们)。例如,如果您计划进行大量的加法和减法运算,那么使用笛卡尔坐标可以获得更小的舍入误差和更快的速度。如果您计划进行大量的乘除和指数运算,或者在指数尺度上工作,则使用polar可以减少舍入误差并提高速度。

如果您只关心整数幂,最准确的方法是将它们相乘:

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;
}
var Re=0,Im=1;
var newRe=1,newIm=0;
var-retRe=1,retIm=0;
对于(变量i=0;i
你是什么意思
(1+i)^5
不等于
1^5+i^5
@ChristianPerfect:哦,对不起,我没看到你说“我不太担心速度,更担心准确性”;我假设你暗示你担心效率,因为你对效率/准确性分析的评论。我将编辑我的答案…这是一个通用数学软件包,作为基于浏览器的数学评估系统的一部分,所以我不希望使用特别大的数字。我认为整数系数在任何地方都是最常用的。这甚至是一个问题的原因是(1+i)^5使用日志和trig方法对{re:-4.0000000001,im:-4}进行了评估,这非常烦人。