我有一点数学问题.我想要一个具有这些属性的函数:
对于大于0的x:lim f(x)= x
对于远小于0的x:lim f(x)= 0
和f(0)= 1 (对不起,我在这里f(1)= 1这是错的!)
f(x)应该单调递增
所以函数应该看起来像这样:
^ | / | / | / ___.-+´ --´-----+------> |
到目前为止我得到的最好的是x/(1 + e^(-x))
然后我认识到它低于0并且没有单调增加.
使用这些功能的一个很好的帮助是GraphFunc Online.
此外,如果函数快速计算,因为我需要经常执行它,这将是有帮助的.
编辑:我在程序中使用它来限制值.我有一个优化算法,它使用Levenberg-Marquardt算法进行曲线拟合.但是这种算法不允许约束,并且优化了整个实际值范围.所以我需要一个这样的函数,这样我就可以添加一个人工约束,使函数大于0.一个简单的方法就是使用f(x) = x²
但是函数不是单调递增的,它有两个最小值.
Levenberg-Marquardt近似于衍生物,所以我认为当函数也很平滑时也是如此.但我不确定这是否绝对必要.
这是一个满足您要求的平滑功能:
f(x) = (x + sqrt(x^2 + 4)) / 2
对于x = 0,你可以看到f(x)= 1.对于非常大的正x,sqrt(x^2 + 4)
大约是x,所以f(x)≈x.对于非常大的负x,sqrt(x^2 + 4)
大约是-x,所以f(x)≈0.
一阶导数是
f'(x) = 1/2 + 1/2*x/sqrt(x^2 + 4)
对于x> 0,x/sqrt(x^2 + 4) > 0
所以f'(x)> 0.对于x <0,
0 < x^2/(x^2 + 4) < 1 0 < |x|/sqrt(x^2 + 4) < 1 -1 < x/sqrt(x^2 + 4) < 0 -1/2 < 1/2*x/sqrt(x^2 + 4) < 0 1/2 + 1/2*x/sqrt(x^2 + 4) > 0
因此,对于所有x,f'(x)> 0,因此f(x)根据需要单调增加.
除了0的停止,x/(1 - e^(-x))
工作.所以将f(0)定义为1,然后设置.
#define E 2.71828183 double SimpleFunc(double x) { if (x == 0) return 1; return x / (1 - pow(E, (-x))); }
可能更快:
double SimpleFunc2(double x) { if (x < 0) return 1/(1 - x); return x+1; }
两者在一阶导数中是连续的,但在二阶导数中第二个在1处跳跃)
如果你真的不想做分段功能,试试这个: (x^2+.1)^.5 / ((1 - e^(-x))^2+.1)^.5