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