Vin*_*ent 2 c++ math optimization
考虑以下形式的收敛系列:
sum(((-1)^n)*something)
Run Code Online (Sandbox Code Playgroud)
n
迭代索引在哪里(n
从哪里1
开始infinity
).
如果我们实现direclty公式,我们std::pow(-1, n)
有一个更"快速"的算法技巧来实现它?
Dan*_*her 13
检查n
是偶数还是奇数,
(n % 2 == 0) ? 1 : -1;
Run Code Online (Sandbox Code Playgroud)
可以.如果你想避免分支,
1 - 2*(n & 1)
Run Code Online (Sandbox Code Playgroud)
小智 6
我假设它sum(((-1)^n)*something)
是伪代码,并且n
是一个由sum限制的变量.
让我们把这个符号扩展到sum(n <- [0,1,2,3..], ((-1)^n)*f(n))
.你最好的选择可能是首先将它分成两个,你加在一起:
sum(n <- [0,2..], ((-1)^n)*f(n)) + sum(n <- [1,3..], ((-1)^n)*f(n))
Run Code Online (Sandbox Code Playgroud)
在第一个任期,n
总是平均的,所以(-1)^n
永远都是+1
.类似地,在第二个任期,它将永远是-1
.我们现在可以重写如下:
sum(n <- [0,2..], f(n)) + sum(n <- [1,3..], -f(n))
Run Code Online (Sandbox Code Playgroud)
由于第二个和中的每个项乘以一个常数,我们可以将该常数移出总和:
sum(n <- [0,2..], f(n)) - sum(n <- [1,3..], f(n))
Run Code Online (Sandbox Code Playgroud)
现在,让我们确保这些资金采取指数相同的序列,并替代2*m
和2*m+1
为n
:
sum(m <- [0,1..], f(2*m)) - sum(m <- [0,1..], f(2*m+1))
Run Code Online (Sandbox Code Playgroud)
现在我们可以再次统一这些总和:
sum(m <- [0,1..], f(2*m) - f(2*m+1))
Run Code Online (Sandbox Code Playgroud)
或者,如果你想要伪C:
T result = 0;
for(m = 0; m < limit; m+=2) {
result += f(m);
result -= f(m+1);
}
Run Code Online (Sandbox Code Playgroud)
这可以为您节省乘法,+1
或者-1
像大多数人似乎在这里建议的那样.由于你的序列是收敛的,所以加一个额外的术语不应该对答案的正确性产生负面影响.