2 puntos por GN⁺ 2024-10-06 | 1 comentarios | Compartir por WhatsApp
  • Chebyshev approximation calculator es una herramienta que genera en la web código de aproximación para funciones matemáticas
  • El usuario puede especificar la función a aproximar, el intervalo y la cantidad de términos mediante f(x), x min, x max y Terms
  • La opción Match x min x max y el área Coefficients ofrecen un flujo para revisar o ajustar los límites del intervalo y los valores de los coeficientes
  • En el área Generated code, el resultado del cálculo se muestra en forma de código; en la pantalla de ejemplo se ven los coeficientes desde c0 hasta c10
  • Tiene conectado un repositorio de GitHub, por lo que se puede consultar directamente el código de implementación de la herramienta web

Generador de código de aproximación de Chebyshev

  • Chebyshev approximation calculator genera código para aproximar de forma eficiente funciones matemáticas
  • En la UI web se ingresan las condiciones de aproximación
    • f(x): función a aproximar
    • x min: valor mínimo del intervalo
    • x max: valor máximo del intervalo
    • Terms: cantidad de términos a usar
    • Match x min x max: opción relacionada con los límites del intervalo

Revisión de coeficientes y código generado

  • La pantalla se divide en las áreas Coefficients y Generated code
  • Los coeficientes mostrados como ejemplo se pueden revisar desde c0 hasta c10
    • c0 = 0.16793649417016518
    • c1 = -0.12411164956092625
    • c2 = -0.09756341588422193
    • c3 = 0.1800765790518846
    • c4 = -0.06972963647223016
    • c5 = -0.09250127939333941
    • c6 = 0.18076946080324185
    • c7 = 0.15990613621816677
    • c8 = -0.028659588693985123
    • c9 = -0.09494966104347571
    • c10 = -0.04980429834982578
  • En la pantalla también aparecen elementos de coeficientes desde c11 hasta c39

Repositorio de código

1 comentarios

 
GN⁺ 2024-10-06
Comentarios en Hacker News
  • Está genial. Por ahí de 1974 me pagaron por escribir una función para calcular raíces cuadradas en ensamblador de IBM 360
    Era mi último año de licenciatura, y me pidieron que la hiciera lo más eficiente posible. Escalé la entrada al rango entre 0 y 1, luego usé una aproximación de Chebyshev para la estimación inicial y apliqué 2 o 3 iteraciones desplegadas del método de Newton para obtener la solución. Fue el primer dinero que gané escribiendo código

    • Me encantan estas historias. Todavía recuerdo la primera vez que, en mi primer curso de análisis numérico, se me abrió por completo la mente al darme cuenta del potencial del cálculo
  • Está realmente muy bien hecho. Me fascinó lo eficientes que pueden ser estas aproximaciones, y también me ayudó a entender mucho mejor por qué las implementaciones de funciones trigonométricas y otras funciones matemáticas en computadoras de 8 bits eran así
    También hay un gran documento original de 1969 del BBC Research Department sobre por qué este enfoque es tan bueno: https://downloads.bbc.co.uk/rd/pubs/reports/1969-10.pdf
    Si solo has visto aproximaciones de Taylor, al principio esto puede parecer casi magia

    • Sí. La parte matemática ya lo hace ver así, pero también resulta bastante mágico que al final todo se reduzca a unas cuantas líneas de código
  • Antes obtuve buenos resultados con Sollya: https://www.sollya.org/
    Eso sí, aunque los resultados eran buenos, el software en sí es algo incómodo de usar

    • Sollya probablemente sea una de las mejores herramientas modernas para este tipo de trabajo. Internamente hace una aproximación de Remez y luego cuantiza a punto flotante con LLL; no usa Chebyshev directamente
  • Si aproximas Math.sin(x)/x, o sea la función sinc, con 7 términos en el intervalo [-3,3], todos los coeficientes c0...c6 salen como NaN. ¿Es un bug?
    Como solución temporal, simplemente forcé 1.0 cuando x está cerca de 0
    if(Math.abs(x) > 1e-8 ){ Math.sin(x)/x } else { 1.0 }

    • No diría que sea exactamente un bug. El código probablemente intenta calcular los coeficientes de Chebyshev evaluando la función en nodos tipo x_j = (xmin) + (xmax - xmin)/2(1 + cos(pi[0..j-1]/(j-1)), y si uno de ellos cae exactamente en 0, entonces termina evaluando Math.sin(0)/0, lo que da NaN
      Otra forma de evitarlo es usar un rango ligeramente asimétrico, como [-3,+3.0000001]
    • El problema aquí es que la primera expresión no está bien definida en x=0, y parece que el código de aproximación tropieza justo ahí. Está un poco chafa
    • Sí, es un bug. Si la función no está definida en todos los nodos de Chebyshev, la app debería mostrar un error. Como ya encontraste, por ahora se puede esquivar fácilmente
  • Los polinomios de Chebyshev son tan potentes y versátiles para aproximación que a la gente le encantan tanto que cree que es trampa y termina sin usarlos
    Chebyshev debería ser el primer método a intentar. Las redes neuronales deberían quedar como último recurso

  • Excelente. Hace poco quería hacer algo así, pero fue sorprendentemente difícil encontrar código para calcular aproximaciones
    Lo dejo guardado para la próxima vez que necesite aproximar una función rápido

    • A mí también me sorprendió lo difícil que fue encontrar código de aproximación de Chebyshev que de verdad funcionara. Ojalá este proyecto cambie eso
  • Chebyshev se siente como magia negra. Lo sigo sintiendo así incluso después de haber visto la derivación en una clase de posgrado

  • También hay que mencionar Chebfun, de Nick Trefethen y otros. Es una herramienta que llevó esta idea en casi todas las direcciones imaginables
    Los Chebfuns pueden verse como el equivalente para funciones de lo que son los números de punto flotante para los números matemáticos reales. Es software realmente impresionante
    https://www.chebfun.org

    • De acuerdo. Esos métodos son muy potentes y rápidos. Con técnicas basadas en Chebyshev y funciones ultrasféricas, puedes aproximar la mayoría de las funciones muy rápido hasta precisión de máquina y luego manipular esa representación con mayor facilidad
      Eso permite hacer muchas cosas, como encontrar soluciones de ecuaciones diferencial-algebraicas con precisión de máquina o hallar mínimos y máximos globales de funciones unidimensionales
      Según entiendo, ahora usan otros algoritmos, pero la metodología base que Chebfun usaba antes se puede ver en el capítulo 6 del libro de Trefethen Spectral Methods in Matlab. La metodología más reciente con funciones ultrasféricas está en el artículo de SIAM Review de Olver y Townsend A Fast and Well-Conditioned Spectral Method
  • Tengo curiosidad y no sé si este sea el lugar para preguntar. Vi una vez un video que decía que la Nintendo 64 no tenía capacidad para calcular la función seno, así que usaba una tabla de consulta de 0 a 2π, además de algunos trucos ingeniosos para reducir el tamaño de la tabla
    ¿Habría sido posible entrenar una red neuronal y guardar los pesos, o construir una función y guardar coeficientes para calcular seno y coseno?

    • Las redes neuronales muchas veces usan funciones trigonométricas internamente, así que meterían muchísimo más cómputo del necesario
      Si te sobran algunos ciclos de CPU, podrías usar una aproximación híbrida: tomar los valores de una tabla dispersa como estimación inicial y luego hacer unas cuantas iteraciones de un método de aproximación numérica. O bien, como en la publicación original, basta con guardar unos cuantos coeficientes iniciales de una aproximación polinómica
    • Si no te suena, vale la pena echarle un ojo a CORDIC. Antes era un truco muy común para trigonometría, y todavía se usa algo en sistemas embebidos
      Las redes neuronales pueden servir cuando tienes muestras de alguna función pero no sabes cómo aproximarla; aquí no es ese caso
    • Claro que puedes entrenar una red neuronal para calcular cualquier función, pero para una función tan conocida como el seno no tendría ningún sentido
      Las redes neuronales son una gran solución cuando necesitas evaluar algo que no es fácil de analizar matemáticamente, pero ya existen muchas técnicas conocidas para calcular y aproximar funciones trigonométricas
      Entrenar una red neuronal para calcular el seno sería la versión matemática de usar un LLM para invertir cadenas. Se puede hacer, pero es una idea que solo surge cuando no sabes que el problema ya se resuelve esencialmente con un enfoque más directo
      Antes de usar técnicas de IA/ML, siempre vale la pena buscar si los matemáticos ya tienen una solución. Hoy en día probablemente se esté gastando mucho esfuerzo en aplicar IA/ML a problemas para los que ya existe una solución conocida, eficiente e incluso óptima, aunque los desarrolladores no la conozcan
    • Una red neuronal es, en esencia, ajuste de curvas, así que sí se puede. Este video podría servir: https://www.youtube.com/watch?v=FBpPjjhJGhk But what is a neural network REALLY?
      La principal fortaleza de las redes neuronales aparece cuando tienes muchísimas entradas, no solo unas pocas. Para algo tan simple como sin(x), hay otros métodos, como la herramienta publicada aquí
    • El truco de ahorro que se suele usar es guardar en tabla solo de 0 a π/2 y usar 2 bits extra de índice para generar los otros tres cuadrantes
  • Está muy padre. Me dio curiosidad juguetear para ver qué tan rápido podía encontrar una función que no se aproximara bien
    Hasta ahora, la mejor que encontré fue Math.cos(x * Math.exp(Math.cos(x * x))). Tiene mucha composición, así que aparecen oscilaciones rápidas y pendientes pronunciadas, lo que hace que sea difícil de aproximar fácilmente con Chebyshev