38 votos

Aproximación rápida de $\tanh(x)$

Esta es una especie de pregunta cruzada de procesamiento de señales/programación/matemáticas. En este momento me parece que está más relacionada con las matemáticas, pero si los moderadores consideran que pertenece a otro lugar, por favor, siéntanse libres de migrarla.

Estoy trabajando en un proyecto en el que tengo una potencia de cálculo limitada y necesito hacer una aproximación rápida de la función tangente hiperbólica sobre un rango bastante grande de argumentos de entrada. Suponiendo que los números se almacenan en punto fijo con una parte fraccionaria de 8 bits entonces la aproximación a $\tanh(x)$ debe trabajar hasta el límite que implica la resolución, o para los argumentos $\tanh^{-1}(\pm[1 - \frac{1}{2^8}]) \approx \pm3.1$ . Sé que las series de Taylor no convergen lo suficientemente rápido en este rango, y no lo he investigado a fondo, pero tampoco creo que una aproximación polinómica de Chebyshev converja lo suficientemente rápido. Por diversas razones tampoco es posible una búsqueda en la tabla.

$\tanh(x)$ es algebraicamente equivalente a $\mathrm{sgn}(x)(1 - \frac{2}{e^{2|x|} + 1})$ . Esto parece prometedor; una expansión en serie de $e^x$ converge mejor que $\tanh(x)$ . Para un cálculo numérico rápido en un hardware limitado, el "+ 1" en el denominador es un obstáculo, ya que significa que hay que realizar una división, y como muchos procesadores sencillos no tienen "división por hardware", la división tiene que hacerse por software mediante repetidos desplazamientos y sustracciones, lo que es terriblemente lento.

Para evitar esto estoy considerando el siguiente enfoque. En lugar de utilizar $\mathrm{sgn}(x)(1 - \frac{2}{e^{2|x|} + 1})$ para representar exactamente tanh(x), defina el siguiente tipo de función similar: $\mathrm{sgn}(x)A(1 - e^{-B|x|})$ para las constantes desconocidas A y B. A continuación, defina una función de pérdida:

$f(x) = \int_0^{3.1}[\tanh(x) - A(1 - e^{-Bx})]^2dx$

A continuación, utilice un método numérico (¿descenso de gradiente?) para encontrar los valores de A y B que minimizan la pérdida. El problema de la aproximación $\tanh(x)$ rápidamente se convierte en una aproximación $e^{-x}$ rápidamente más una resta y una multiplicación extra.

$e^{-x} = \dfrac{1}{e^x} = \dfrac{1}{2^{x \log_2(e)}} = \dfrac{2^{-x}}{2^y}$ donde y es la parte entera y x es la parte fraccionaria. Expresando $e^{-x}$ esta forma me permite reducir el rango del argumento de entrada; dividir un número sin signo por $2^y$ donde y es un número entero positivo, se puede realizar mediante un desplazamiento lógico. Para los argumentos entre 0 y -1 basta con mirar a ojo un Expansión en serie de Taylor de $2^x$ se ve muy bien para sólo 3 términos.

¿Le parece razonable este planteamiento, desde una perspectiva matemática? ¿Problemas que no he tenido en cuenta? Gracias por cualquier consejo.

Edición: Debo añadir que en esta aplicación (procesamiento de audio) estoy dispuesto a sacrificar la precisión absoluta del valor calculado a cambio de la velocidad de procesamiento y de una función que funcione "razonablemente" bien en todo el rango de argumentos de entrada - el valor de retorno para cada argumento en la aproximación no tiene que ser preciso al $2^{-8}$ límite que implica la resolución.

25voto

Andrew Puntos 140

Seguramente sabes que la tangente hiperbólica tiene una asíntota; como ningún polinomio ha tenido nunca una asíntota horizontal, es lógico que un polinomio siempre se aproxime mal al comportamiento cualitativo de la tangente hiperbólica.

Un enfoque viable sería considerar las funciones racionales que provienen de truncamientos de la fracción continua para la tangente hiperbólica :

$$\tanh\,z=\cfrac{z}{1+\cfrac{z^2}{3+\cfrac{z^2}{5+\cdots}}}$$

Aquí, por ejemplo, hay gráficos que comparan $\tanh\,z$ y el convergente

$$R(z)=\cfrac{z}{1+\cfrac{z^2}{3+\cfrac{z^2}{5+\cfrac{z^2}{7+\cfrac{z^2}{9+\cfrac{z^2}{11}}}}}}$$

comparison of hyperbolic tangent and CF convergent

El gráfico de la izquierda muestra que la aproximación racional y la función real son casi indistinguibles visualmente, mientras que el gráfico de la derecha representa la función $\tanh\,z-R(z)$ .

Otra posibilidad que se puede utilizar junto con la aproximación de funciones racionales es el uso de reducción de argumentos en particular, la identidad

$$\tanh\,z=\frac{2\tanh\frac{z}{2}}{1+\tanh^2\frac{z}{2}}$$

es muy útil aquí. Para esbozar un posible algoritmo: escala $z$ por $2^{-k}$ , donde $k$ se elige adecuadamente de forma que $\dfrac{z}{2^k}$ es "suficientemente pequeño", evaluar la fracción continua truncada en este argumento reducido, y luego aplicar repetidamente la identidad de doble argumento $k$ tiempos.

16voto

Andrew Puntos 140

Una vez más, para demostrar que siempre hay más de una forma de despellejar a un gato, presento un conjunto diferente de funciones racionales que se pueden utilizar en lugar de los convergentes de fracciones continuas que presenté en mi respuesta anterior.

La idea se basa en la Aproximaciones de Padé de $\exp\,z$ . Más concretamente, dejemos que el $(n,n)$ Aproximante de Padé de $\exp\,z$ estar representado por

$$\exp\,z\approx\frac{p_n(z)}{p_n(-z)}$$

donde

$$p_n(z)=\sum_{j=0}^n\frac{\binom{n}{j}}{j!\binom{2n}{j}}z^j$$

A partir de esto, encontramos que podemos aproximar $\tanh\,z=\dfrac{\exp\,2z-1}{\exp\,2z+1}$ con una función racional así:

$$\tanh\,z\approx\mathcal{T}_n(z)=\frac{p_n(z)^2-p_n(-z)^2}{p_n(z)^2+p_n(-z)^2}$$

Por ejemplo,

$$\mathcal{T}_3(z)=\frac{z(10+z^2)(60+z^2)}{600+270z^2+11z^4+\frac{z^6}{24}}$$

Aquí están los gráficos de comparación para $\tanh\,z$ et $\mathcal{T}_3(z)$ :

comparison plots of tanh(z) and Pade-derived approximant

El gráfico de la izquierda muestra $\tanh\,z$ et $\mathcal{T}_3(z)$ juntos, mientras que el gráfico de la derecha representa la función de error relativo $1-\dfrac{\mathcal{T}_3(z)}{\tanh\,z}$ . Nótese que el error es ligeramente menor aquí que en la respuesta anterior. Todavía se podría mejorar esta aproximación con una función racional con coeficientes suficientemente simples, pero esto es un comienzo.

8voto

Matthew Scouten Puntos 2518

La mejor aproximación racional a $\tanh(x)$ con numerador y denominador de grado 3 en el intervalo $[0, 3.1]$ (según la función minimax de Maple) es

(-.67436811832e-5+(.2468149110712040+(.583691066395175e-1+.3357335044280075e-1*x)*x)*x)/(.2464845986383725+(.609347197060491e-1+(.1086202599228572+.2874707922475963e-1*x)*x)*x)

Esto (llámalo $f(x)$ ) tiene un error máximo de .2735944241730870e-4, que es considerablemente menor que 2^(-8).
En el intervalo $[-3.1, 3.1]$ Utilizar $\text{sgn}(x) f(|x|)$ .

7voto

Philip Fourie Puntos 12889

$\tanh(x)$ es la solución de la ecuación diferencial $y'=1-y^2$ con la condición inicial $y(0)=0$ . Hay una gran cantidad de métodos muy rápidos para aproximar soluciones a ecuaciones diferenciales autónomas como ésta. El más famoso es Runge-Kutta 4 . Creo que debo enfatizar que este método generalmente proporciona muy buenas aproximaciones en muy poco tiempo de computación.

5voto

Emre Puntos 215

En esta página Varosound deriva una ecuación computacionalmente más sencilla (una división, muchas sumas y multiplicaciones) a partir de la fracción continua discutida aquí por J.M.:

http://varietyofsound.wordpress.com/2011/02/14/efficient-tanh-computation-using-lamberts-continued-fraction/

En C, se vería así:

float fast_tanh(float x){
  float x2 = x * x;
  float a = x * (135135.0f + x2 * (17325.0f + x2 * (378.0f + x2)));
  float b = 135135.0f + x2 * (62370.0f + x2 * (3150.0f + x2 * 28.0f));
  return a / b;
}

Debería añadir que si x puede ser grande (no es relevante para el OP), querrías sujetar la salida a +/-1 para x más allá de aproximadamente +/-4,97.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X