どのような単純な数学関数f(x)にこれらのプロパティがありますか?
質問
ちょっとした数学の問題があります。これらのプロパティを持つ関数が必要です:
- xが0より大きい場合:lim f(x)= x
- xが0より小さい場合:lim f(x)= 0
- and f(0)= 1 (申し訳ありませんが、ここではf(1)= 1でしたが間違っていました!)
- f(x)は単調に増加する
したがって、関数は次のようになります。
^
| /
| /
| /
___.-+´
--´-----+------>
|
これまでのところ最高のものはx/(1 + e^(-x))
ですが、0未満に低下し、単調に増加していないことを認識しました。
GraphFunc Online は、これらの機能をいじるのに非常に役立ちます。
また、非常に頻繁に実行する必要があるため、関数の計算が速い場合に役立ちます。
編集:値を制限するためにプログラムでこれを使用しています。 Levenberg-Marquardt アルゴリズムで曲線近似を使用する最適化アルゴリズムがあります。ただし、このアルゴリズムは制約を許可せず、実際の値の全範囲にわたって最適化します。したがって、関数が0より大きくなるように人為的な制約を追加するには、このような関数が必要です。単純なアプローチはf(x) = x²
を使用することですが、関数は単調に増加せず、2つの最小値を持ちます。
Levenberg-Marquardtは導関数を近似するため、関数も滑らかなときに最適だと思います。しかし、これが絶対に必要かどうかはわかりません。
解決
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次導関数では両方とも連続ですが、2番目の導関数では1にジャンプがあります)
ピース単位の機能を本当に実行したくない場合は、これを試してください:(x^2+.1)^.5 / ((1 - e^(-x))^2+.1)^.5
他のヒント
要件を満たすスムーズ関数は次のとおりです。
f(x) = (x + sqrt(x^2 + 4)) / 2
x = 0の場合、f(x)= 1であることがわかります。非常に大きな正のxの場合、sqrt(x^2 + 4)
は約xなので、f(x)<!>#8776;バツ。非常に大きな負のxの場合、x/sqrt(x^2 + 4) > 0
は約-xなので、f(x)<!>#8776; 0。
一次導関数は
f'(x) = 1/2 + 1/2*x/sqrt(x^2 + 4)
x <!> gt;の場合0、<=>、したがってf '(x)<!> gt; 0. x <!> lt;の場合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
したがって、f '(x)<!> gt;すべてのxが0であるため、f(x)は必要に応じて単調に増加しています。
f(x)= abs(x / 2)+ x / 2
abs(x)はxの絶対値です
この単純な関数は明らかに計算が速く、4つの基準すべてを満たします。
アイデアを提供するために、これは制約f(1)= 1のないソリューションであり、単調増加ではありません。
基本的に、2つの関数をブレンドします。f1(x)= 0 for x <!> lt; 0、およびx <!> gtの場合f2(x)= x 0.それをスムーズにブレンドしたい。 -infと+ infに一定の制限がある単純なステップ関数はatanです(制限はそれぞれ-pi / 2と+ pi / 2です)。
したがって、atanブレンド関数をf1およびf2と組み合わせると、次のようになります。
blend(x)= atan(x)/ pi + 0.5 f(x)=(1-blend(x))* f1(x)+ blend(x)* f2(x)
次の内容:
f(x)=(atan(x)/ pi + 0.5)* x
おそらく、atanの代わりに使用できる他のブレンド関数があります。また、小さな負の値ではf(x)が負になることに注意してください。
曲線を(1,1)にしたい場合は、atan(0)= 0という事実を使用できます。
私はあなたがそれを正確に何のために使っているのかわかりません。区分的関数の何が問題になっていますか?あなたがそれをたくさん実行するつもりなら、このようなものは指数を行うよりも速くなります:
f(x) = -1/x, x < -1
f(x) = 1, -1 <= x <= 1
f(x) = x, x > 1
編集:実際に機能するように修正しました。
1/2 *(x + ABS(x))
単調です。
f(1)= 1。
xがゼロ未満の場合、f(x)= 0、それ以外の場合はxと等しくなります。