2009-03-04 8 views
7

Ich habe ein kleines mathematisches Problem. Ich möchte eine Funktion mit diesen Eigenschaften haben:Welche einfache mathematische Funktion f (x) hat diese Eigenschaften?

  1. für x viel größer als 0: lim f (x) = x
  2. für x viel kleiner als 0: lim f (x) = 0
  3. und f (0) = 1 (sorry, ich hatte hier f (1) = 1, die falsch war!)
  4. f (x) monotonically increasing

sein sollte, so sollte die Funktion etwas aussehen dies:

 ^
     | /
     |/
     |/
    ___.-+´ 
--´-----+------> 
     | 

Das beste, was ich bisher bekommen habe, ist x/(1 + e^(-x)), aber dann erkannte ich, dass es unter 0 fällt und nicht monoton ansteigt.

Eine große Hilfe zum Spielen mit diesen Funktionen ist GraphFunc Online.

Es wäre auch hilfreich, wenn die Funktion schnell berechnet wird, da ich sie sehr oft ausführen muss.

EDIT: Ich verwende dies in einem Programm, um Werte zu begrenzen. Ich habe einen Optimierungsalgorithmus, der Kurvenanpassung mit einem Levenberg-Marquardt Algorithmus verwendet. Aber dieser Algorithmus erlaubt keine Beschränkungen und optimiert über den gesamten Bereich der realen Werte. Also brauche ich eine Funktion wie diese, so dass ich eine künstliche Einschränkung hinzufügen kann, so dass die Funktion größer als 0 ist. Ein einfacher Ansatz wäre die Verwendung von f(x) = x², aber dann ist die Funktion nicht monoton steigend und hat zwei Minimas.

Die Levenberg-Marquardt nähert Derivate, so denke ich, es wäre am besten, wenn die Funktion auch glatt ist. Aber ich bin mir nicht sicher, ob das unbedingt notwendig ist.

+0

Ich sehe nicht, wie das Programmieren ist. –

+0

An dieser Stelle würde ich erwarten, mehr als ein Sprach-Tag zu sehen. Erkläre, warum du das programmatisch oder so machst. – EBGreen

+0

Ich könnte leicht sehen, wie das Programmieren ist, aber vielleicht könnte das OP einen Kontext hinzufügen, um andere zu befriedigen. –

Antwort

5

Bis auf eine Unterbrechung bei 0 funktioniert x/(1 - e^(-x)). Definieren Sie also f (0) als 1 und Sie sind festgelegt.

#define E 2.71828183 
double SimpleFunc(double x) 
{ 
    if (x == 0) 
     return 1; 
    return x/(1 - pow(E, (-x))); 
} 

wahrscheinlich schneller:

double SimpleFunc2(double x) 
{ 
    if (x < 0) 
    return 1/(1 - x); 
    return x+1; 
} 

Beide kontinuierlich sind in der ersten Ableitung, aber die zweite hat einen Sprung in 1 in der zweiten Ableitung)

Wenn Sie wirklich nicht wollen, die stückweise Funktion zu tun, versuchen Sie dies: (x^2+.1)^.5/((1 - e^(-x))^2+.1)^.5

+0

nett! etwas schneller wäre natürlich x/(1 - e^(- x)), weil kein neg. –

+0

.. und in Ihrer "wahrscheinlich schneller" Variante, auf x> 0, geben Sie x + 1 zurück, um die Diskontinuität zu verringern. –

+0

Ja, ich wollte auch x/(1 - e^(- x)) vorschlagen, aber Iraimbilanja hat mich dazu geschlagen. :) – grieve

3

f (x) = abs (x/2) + x/2

wobei abs (x) der absolute Wert von x ist

Diese einfache Funktion wäre offensichtlich schnell zu berechnen und erfüllt alle vier Kriterien.

+0

Er bat darum, dass f (1) 1 ist, nicht f (0) (obwohl sein Graph, ohne Skala, hier irreführend sein kann). –

+0

Es fehlt # 4: f (-10) = 10> 0 = f (0) –

0

Ich weiß nicht, wofür Sie es genau verwenden; Was stimmt mit einer stückweisen Funktion nicht? Wenn Sie vorhaben, es viel zu Ausführung, so etwas wie das wird schneller sein als tun Exponenten:

f(x) = -1/x, x < -1 
f(x) = 1, -1 <= x <= 1 
f(x) = x, x > 1 

EDIT: es wurde behoben, so dass es tatsächlich funktioniert.

+0

undefiniert bei x = 0 und negativ, wenn x <0 –

+0

@Patrick: D'oh! Vielen Dank. – Pesto

+0

Auch für die meisten Zwecke möchten Sie normalerweise reibungslose Übergänge von einem zum anderen. –

1

Nur um Ihnen Ideen zu geben, ist dies eine Lösung ohne die Einschränkung f (1) = 1 und nicht monoton steigend.

Grundsätzlich möchten Sie zwischen zwei Funktionen mischen: f1 (x) = 0 für x < 0, und f2 (x) = x für x> 0. Sie möchten das glatt mischen. Eine einfache Schrittfunktion mit einer konstanten Grenze bei -inf und + inf ist atan (Grenzen sind -pi/2 bzw. + pi/2).

So eine atan Vermischungsfunktion mit f1 und f2 kombiniert, bekommt man:

Mischung (x) = atan (x)/pi + 0,5 f (x) = (1 - Mischung (x)) * f1 (x) + Mischung (x) * f2 (x)

Welche gibt:

f (x) = (atan (x)/pi + 0,5) * x

Es gibt wahrscheinlich andere Mischfunktionen, die Sie anstelle von atan verwenden können. Beachten Sie auch, dass bei kleinen negativen Werten f (x) negativ ist.

Wenn Sie möchten, dass Ihre Kurve durchläuft (1,1), können Sie die Tatsache verwenden, dass atan (0) = 0 ist.

+0

10 DOH! Du hast mich um 40 Sekunden geschlagen! :) –

+0

Wenn die Funktion tatsächlich lim f (x) = x und f (x) = x bei x = 1 hat, muss die Funktion stückweise sein. – Doub

0

1/2 * (x + ABS (x))

Es ist monotonen.

f (1) = 1

Wenn x kleiner als null ist, f (x) = 0, andernfalls ist es gleich x.

8

Hier ist ein smooth function, die Ihre Anforderungen erfüllt:

f(x) = (x + sqrt(x^2 + 4))/2 

Für x = 0, Sie, dass f sehen (x) = 1. Für sehr große positive x, ist sqrt(x^2 + 4) etwa x, so f (x) ≈ x. Für sehr große negative x ist etwa sqrt(x^2 + 4) -X, so f (x) ≈ 0.

Die erste Ableitung

f'(x) = 1/2 + 1/2*x/sqrt(x^2 + 4) 

für x> 0, x/sqrt(x^2 + 4) > 0, so f '(x)> 0 für. < 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 

daher f '(x)> 0 für alle x, so f (x) monoton zunimmt, wie gewünscht.

+0

Vielen Dank, ich benutze das auch. Ich wünschte, ich könnte zwei Antworten akzeptieren :) – martinus