Domanda

Ho un piccolo problema di matematica. Vorrei avere una funzione con queste proprietà:

  1. per x molto più grande di 0: lim f (x) = x
  2. per x molto più piccolo di 0: lim f (x) = 0
  3. ef (0) = 1 (scusate, avevo qui f (1) = 1 che era sbagliato!)
  4. f (x) dovrebbe essere aumentare monotonicamente

Quindi la funzione dovrebbe apparire in questo modo:

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

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

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

Inoltre, sarebbe utile se la funzione fosse veloce da calcolare poiché devo eseguirla molto spesso.

MODIFICA : lo sto usando in un programma per limitare i valori. Ho un algoritmo di ottimizzazione, che utilizza l'adattamento della curva con un Levenberg-Marquardt . Ma questo algoritmo non consente vincoli e ottimizza su tutta la 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 maggiore di 0. Un approccio semplice sarebbe usare f(x) = x² ma poi la funzione non sta aumentando monotonicamente e ha due minimas.

Levenberg-Marquardt approssima i derivati, quindi penso che sarebbe meglio quando anche la funzione è regolare. Ma non sono sicuro che ciò sia assolutamente necessario.

È stato utile?

Soluzione

Ad eccezione di una sospensione 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)));
}

Probabilmente più veloce:

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

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

Se davvero non vuoi svolgere la funzione pezzo saggio, prova questo: (x^2+.1)^.5 / ((1 - e^(-x))^2+.1)^.5

Altri suggerimenti

Ecco una funzione smooth che soddisfa le tue esigenze:

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

Per x = 0, puoi vedere che f (x) = 1. Per x positivo molto grande, sqrt(x^2 + 4) è approssimativamente x, quindi f (x) & # 8776; X. Per x negativo molto grande, x/sqrt(x^2 + 4) > 0 è approssimativamente -x, quindi f (x) & # 8776; 0.

La prima derivata è

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

Per x > 0, <=>, quindi f '(x) & Gt; 0. Per 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

Quindi, f '(x) > 0 per tutti x, quindi f (x) aumenta monotonicamente come desiderato.

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.

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

Fondamentalmente si desidera fondere tra due funzioni: f1 (x) = 0 per x < 0 e f2 (x) = x per x & Gt; 0. Vuoi fonderlo uniformemente. Una semplice funzione di passaggio con un limite costante in -inf e + inf è atan (i limiti sono rispettivamente -pi / 2 e + pi / 2).

Quindi combinando una funzione di fusione atan con f1 e f2, ottieni:

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

Che dà:

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

Probabilmente ci sono altre funzioni di fusione che puoi usare al posto di atan. Nota anche che con piccoli valori negativi, f (x) sarà negativo.

Se vuoi che la tua curva passi attraverso (1,1), puoi usare il fatto che atan (0) = 0.

Non so per cosa lo stai usando esattamente; cosa c'è di sbagliato in una funzione a tratti? Se lo eseguirai molto, qualcosa del genere sarà più veloce rispetto agli esponenti:

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

EDIT: risolto in modo che funzioni davvero.

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

È monotonico.

f (1) = 1.

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top