Schnelle Exp-Berechnung: mögliche, um Genauigkeit zu verbessern, ohne zu viel Leistung?

Ich versuche aus dem schnellen Exp(x) Funktion, die vorher beschrieben wurde, diese Antwort auf eine Frage ALSO auf die Verbesserung der Geschwindigkeit der Berechnung, die in C#:

public static double Exp(double x)
{
  var tmp = (long)(1512775 * x + 1072632447);
  return BitConverter.Int64BitsToDouble(tmp << 32);
}

Wird der Ausdruck mit IEEE-floating-point "tricks" und ist hauptsächlich für die Verwendung in neuronalen sets. Die Funktion ist etwa 5-mal schneller als die normalen Math.Exp(x) Funktion.

Leider, ist die numerische Genauigkeit ist nur -4% -- +2% gegenüber dem regulären Math.Exp(x) Funktion, idealerweise würde ich gerne eine Genauigkeit von innerhalb mindestens der sub-Prozent-Bereich.

Habe ich gezeichnet, der quotient zwischen dem ungefähren und dem regulären Exp Funktionen, und wie gesehen werden kann, in der Grafik die relative Differenz scheint wiederholt zu werden, mit praktisch konstanter Frequenz.

Schnelle Exp-Berechnung: mögliche, um Genauigkeit zu verbessern, ohne zu viel Leistung?

Ist es möglich, dies zu nutzen Regelmäßigkeit zur Verbesserung der Genauigkeit der "schnelle exp" - Funktion weiter, ohne erhebliche Verringerung der Geschwindigkeit der Berechnung, oder würde der rechnerische Aufwand eine Genauigkeit Verbesserung überwiegen die rechnerische Verstärkung des ursprünglichen Ausdrucks?

(Wie sehen a side note, ich habe auch versucht, eine alternative Ansätzen, die in der gleichen Frage ALSO, aber mit diesem Ansatz nicht zu sein scheinen sehr effizient in C#, zumindest nicht für den Allgemeinen Fall.)

UPDATE MAI 14

Auf Wunsch von @Adriano, ich habe mir nun vorgenommen einen sehr einfachen Maßstab. Habe ich durchgeführt 10 Millionen Berechnungen unter Verwendung jeder der alternativen exp Funktionen für Gleitkomma-Werte im Bereich [-100, 100]. Da der Bereich der Werte, die ich bin daran interessiert, es erstreckt sich von -20 bis 0 habe ich auch explizit aufgeführt ist der Wert für die Funktion an der Stelle x = -5. Hier sind die Ergebnisse:

      Math.Exp: 62.525 ms, exp(-5) = 0.00673794699908547
Empty function: 13.769 ms
     ExpNeural: 14.867 ms, exp(-5) = 0.00675211846828461
    ExpSeries8: 15.121 ms, exp(-5) = 0.00641270968867667
   ExpSeries16: 32.046 ms, exp(-5) = 0.00673666189488182
          exp1: 15.062 ms, exp(-5) = -12.3333325982094
          exp2: 15.090 ms, exp(-5) = 13.708332516253
          exp3: 16.251 ms, exp(-5) = -12.3333325982094
          exp4: 17.924 ms, exp(-5) = 728.368055056781
          exp5: 20.972 ms, exp(-5) = -6.13293614238501
          exp6: 24.212 ms, exp(-5) = 3.55518353166184
          exp7: 29.092 ms, exp(-5) = -1.8271053775984
      exp7 +/-: 38.482 ms, exp(-5) = 0.00695945286970704

ExpNeural entspricht der Exp Funktion angegeben, die am Anfang dieses Textes. ExpSeries8 wird die Formulierung, dass ich ursprünglich behauptete, war nicht sehr effizient auf .NETTO; bei der Umsetzung ist es genau so wie Neil es war tatsächlich sehr schnell. ExpSeries16 wird die analoge Formel, aber mit 16 Multiplikationen statt 8. exp1 durch exp7 sind die verschiedenen Funktionen von Adriano ' s Antwort weiter unten. Die endgültige Variante des exp7 ist eine Variante, wo die Zeichen der x wird überprüft; wenn negativ, liefert die Funktion 1/exp(-x) statt.

Leider weder von der expN Funktionen aufgeführt, die durch Adriano sind ausreichend in der breiteren negativen Wertebereich überlege ich. Die Serie Erweiterung Ansatz von Neil Coffey scheint zu sein, mehr geeignet, "meine" Wert-Bereich, obwohl es zu stark erweiternde, mit größeren negativen x, vor allem, wenn Sie mit "nur" 8 Multiplikationen.

  • ich bin neugierig auf Ihre Referenz zu "neural-Sätzen". derzeit bin ich die Simulation eines neuronalen Netzes mit C++ und vor dem gleichen exp performance-Engpass, die Sie haben, konfrontiert. gibt es papers in computational neuroscience, die haben vorgeschlagen Ungefähre exp Funktionen, die sind sehr schnell?
Schreibe einen Kommentar