2009-03-04 12 views
7

Ho un piccolo problema di matematica. Vorrei avere una funzione con queste proprietà:Quale semplice funzione matematica f (x) ha queste proprietà?

  1. per x molto più grandi di 0: lim f (x) = x
  2. per x molto più piccoli di 0: lim f (x) = 0
  3. ed f (0) = 1 (scusate, ho avuto qui f (1) = 1, che era sbagliato!)
  4. f (x) dovrebbe essere monotonically increasing

Quindi la funzione dovrebbe guardare un po 'come questo:

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

Il meglio che ho ottenuto finora è x/(1 + e^(-x)) ma poi ho riconosciuto che scende sotto 0 e non aumenta monotonicamente.

Un grande aiuto per giocare con queste funzioni è GraphFunc Online.

Inoltre, sarebbe utile se la funzione è veloce da calcolare in quanto ho bisogno di eseguirlo molto spesso.

EDIT: lo sto utilizzando in un programma per limitare i valori. Ho un algoritmo di ottimizzazione, che utilizza l'adattamento della curva con un algoritmo Levenberg-Marquardt. Ma questo algoritmo non consente vincoli e ottimizza l'intera gamma di valori reali. Quindi ho bisogno di una funzione come questa in modo da poter aggiungere un vincolo artificiale in modo che la funzione sia più grande di 0. Un approccio semplice sarebbe usare f(x) = x² ma la funzione non è monotonicamente crescente e ha due minimas.

Il Levenberg-Marquardt si avvicina alle derivate, quindi penso che sarebbe meglio quando anche la funzione è liscia. Ma non sono sicuro che sia assolutamente necessario.

+0

Non vedo come questo sia collegato alla programmazione. –

+0

A questo punto mi aspetto di vedere più di un tag di lingua. Spiega perché lo stai facendo a livello di programmazione o qualcosa del genere. – EBGreen

+0

Potrei facilmente vedere come questo è collegato alla programmazione, ma forse l'OP potrebbe aggiungere un contesto per soddisfare gli altri. –

risposta

5

Fatta eccezione per un discontinuo a 0, x/(1 - e^(-x)) funziona. Quindi definisci f (0) come 1 e sei pronto.

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

Probabile veloce:

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

Entrambi sono in continuo la derivata prima, ma la seconda ha un salto a 1 nella seconda derivata)

Se davvero non si vuole per eseguire la funzione a tratti, provate questo: (x^2+.1)^.5/((1 - e^(-x))^2+.1)^.5

+0

bello! leggermente più veloce sarebbe x/(1 - e^(- x)) ovviamente, a causa di nessun neg. –

+0

.. e nella tua variante "probabile più veloce", su x> 0 restituisce x + 1 per ridurre la discontinuità. –

+0

Sì, stavo per suggerire x/(1 - e^(- x)), ma Iraimbilanja mi ha battuto su di esso. :) – grieve

3

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

dove abs (x) è il valore assoluto di x

Questa semplice funzione sarebbe ovviamente veloce da calcolare e soddisfa tutti e quattro i criteri.

+0

Ha chiesto che f (1) sia 1, non f (0) (anche se il suo grafico, senza scala, potrebbe essere fuorviante qui). –

+0

Manca n. 4: f (-10) = 10> 0 = f (0) –

0

Non so esattamente per cosa lo stai usando; cosa c'è di sbagliato in una funzione a tratti? Se avete intenzione di essere l'esecuzione di un sacco, qualcosa di simile sta per essere più veloce di esponenti che fanno:

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

EDIT: Fisso esso in modo che funziona realmente.

+0

indefinito a x = 0 e negativo quando x <0 –

+0

@Patrick: D'oh! Grazie. – Pesto

+0

Anche per la maggior parte degli scopi di solito si desidera transizioni fluide da uno all'altro. –

1

Solo per darti idee, questa è una soluzione senza il vincolo f (1) = 1 e non aumenta monotonicamente.

Fondamentalmente si desidera fondere tra due funzioni: f1 (x) = 0 per x < 0 e f2 (x) = x per x> 0. Si desidera fondere in modo uniforme. Una semplice funzione di passo con un limite costante a -inf e + inf è atan (i limiti sono -pi/2 e + pi/2 rispettivamente).

Così combinando una funzione Atan si fondono con F1 e F2, si ottiene:

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

che dà:

f (x) = (atan (x)/pi + 0.5) * x

probabilmente ci sono altri funzioni di fusione che è possibile utilizzare al posto di atan. Si noti inoltre che con piccoli valori negativi, f (x) sarà negativo.

Se si desidera attraversare la curva (1,1), è possibile utilizzare il fatto che atan (0) = 0.

+0

DOH! Mi hai battuto di 40 secondi! :) –

+0

In realtà, se la funzione ha lim f (x) = xe f (x) = x in x = 1, la funzione deve essere a tratti. – Doub

0

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

E 'monotona.

f (1) = 1.

Quando x è minore di zero, f (x) = 0, altrimenti è uguale a x.

8

Ecco un smooth function che soddisfa le vostre esigenze:

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

Per x = 0, si può vedere che f (x) = 1. Per molto grandi x positivi, sqrt(x^2 + 4) è di circa x, quindi f (x) ≈ x. Per grandi x negative, sqrt(x^2 + 4) è approssimativamente -x, quindi f (x) ≈ 0.

La derivata prima è

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

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

quindi, f '(x)> 0 per ogni x, quindi f (x) è monotona crescente come desiderato.

+0

Grazie mille, lo uso anch'io. Vorrei poter accettare due risposte :) – martinus

Problemi correlati