Javascript中的快速双曲正切逼近
我正在用javascript进行一些数字信号处理计算,我发现计算双曲正切(tanh)有点太贵了。这就是我目前估计tanh的方法:Javascript中的快速双曲正切逼近,javascript,performance,math,approximation,Javascript,Performance,Math,Approximation,我正在用javascript进行一些数字信号处理计算,我发现计算双曲正切(tanh)有点太贵了。这就是我目前估计tanh的方法: function tanh (arg) { // sinh(number)/cosh(number) return (Math.exp(arg) - Math.exp(-arg)) / (Math.exp(arg) + Math.exp(-arg)); } 有人知道一种更快的计算方法吗?您可以这样做: 不确定性能提升的幅度有多大,但是 (exp(x)
function tanh (arg) {
// sinh(number)/cosh(number)
return (Math.exp(arg) - Math.exp(-arg)) / (Math.exp(arg) + Math.exp(-arg));
}
有人知道一种更快的计算方法吗?您可以这样做:
不确定性能提升的幅度有多大,但是
(exp(x) - exp(-x))/(exp(x) + exp(-x)) = (exp(2x) - 1)/(exp(2x) + 1)
您将把
exp
s的数量减半。您始终可以在一定的精度级别上切断公式
function tanh (x) {
return arg - (x * x * x / 3) + (2 * x * x * x * x * x / 15);
}
从
函数有理数(x)
{
如果(x<-3)
返回-1;
如果(x>3),则为else
返回1;
其他的
返回x*(27+x*x)/(27+9*x*x);
}
这是一个合理的函数
近似棕褐色的软剪刀。
它基于帕德近似
使用调整的tanh函数的
系数
函数的范围为x=-3..3
并输出范围y=-1..1。超过
此范围必须限制输出
到-1..1
一阶导数
函数在-3和3处消失,因此
向硬剪裁区域的过渡
是连续的
Padé近似比Taylor展开好几个数量级。钳位也可能是一个问题(取决于您的范围)。在chrome上调用该函数所需的时间不到调用空
函数f(){}
所需时间的三倍,因此我认为您不会从任何重写中获得太多好处
问题在于函数开销,而不是公式。可能是内联,它可以保存一些更有趣的东西
编辑
为了进行测试,我只需在Chrome中打开一个控制台(ctrl-shift-C),并使用
timeit = function(f) {
var start=(new Date).getTime();
for (var i=0; i<100000; i++)
f(1);
return (new Date).getTime() - start;
}
timeit=function(f){
var start=(新日期).getTime();
对于(var i=0;i这是我对这个问题的答案
function tanh(x){
var e = Math.exp(2*x)
return (e-1)/(e+1)
}
Math.constructor.prototype.tanh=tanh;
document.write(Math.tanh(2))
要使用较少的Math.exp()
s获得准确的答案,可以使用tanh和之间的关系。tanh(x)
正好是2*logistic(2*x)-1
,并展开logistic函数,您可以得到:
function one_exp_tanh(x){
return 2.0 / (1.0 + exp(-2.0 * x)) - 1.0;
}
不过,我不知道在javascript中这是否更快。ES6本机提供了此方法和许多其他trig函数:
Math.sinh
–数字的双曲正弦
Math.cosh
–数字的双曲余弦
Math.tanh
–数字的双曲正切
Math.asinh
–数字的双曲弧正弦
Math.acosh
–数字的双曲弧余弦
Math.atanh
–数字的双曲正切
Math.hypot
–平方和的平方根
最有可能的是,它比大多数JS替代方案都快。泰勒展开式的精度是。同意。它快了一吨,但它确实取决于。我想arg是x?这非常有用。你能给我指出一条将公式切割到任意精度水平的一般规则吗?是的,对不起。x
是arg
一般泰勒展开式很好!如果我有一个任意的范围呢?简单地缩放系数是正确的?(例如:范围[-1,1]>返回x*(9+x*x)/(9+3*x*x)),我不这么认为。据我所知,选择3是因为前两个导数在-3和3处消失(请记住,我们只使用了近似值中的前3个元素)。我认为缩放系数不会得到期望的结果。@janesconference,我只是将其绘制为双重检查,是的,您不想这样做:)@janesconference对于外部范围系数使用taylorPlotted(在3处没有剪辑)我要试试。顺便问一下,你是如何分析的?(我在ff4上,我用firebug进行分析)在ff4中,你的解决方案的测试速度慢了41%:(@janesconference:哇!我在ff4中也看到了这一点-我看到了使用Chrome的性能提升。你需要指定两个关键信息(a)输入参数的域是什么,(b)你需要多精确,现在。
function tanh(x){
var e = Math.exp(2*x)
return (e-1)/(e+1)
}
Math.constructor.prototype.tanh=tanh;
document.write(Math.tanh(2))
function one_exp_tanh(x){
return 2.0 / (1.0 + exp(-2.0 * x)) - 1.0;
}