2010-07-21 8 views
26

Necesito manipular expresiones como 1 + sqrt (3) y hacer aritmética básica como suma, resta y división. Me gustaría que el resultado esté en algún tipo de forma canónica para que pueda usarse como clave en un mapa. Convertir 1 + sqrt (3) en un flotante no es factible debido a problemas de redondeo.biblioteca de Haskell como SymPy?

Utilicé SymPy para esta tarea en Python. ¿Hay una biblioteca nativa equivalente para Haskell?

+2

¿Desea '√2 - 1 == 1/(√2 + 1)'? – kennytm

Respuesta

7

Por favor, echa un vistazo a the numbers package. Si todo lo que necesita es almacenar números exactos como "1 + √3", puede usar Data.Number.CReal en lugar de aritmética simbólica. Almacena las expresiones y puede calcularse para una cantidad arbitraria de dígitos cuando sea necesario.

Prelude Data.Number.CReal> let cx = 1 + sqrt (3 :: CReal) 
Prelude Data.Number.CReal> showCReal 400 cx 
"2.7320508075688772935274463415058723669428052538103806280558069794519330169088000370811461867572485756756261414154067030299699450949989524788116555120943736485280932319023055820679748201010846749232650153123432669033228866506722546689218379712270471316603678615880190499865373798593894676503475065760507566183481296061009476021871903250831458295239598329977898245082887144638329173472241639845878553977" 

También hay un módulo de Data.Number.Symbolic en el paquete pero la descripción dice que "es principalmente útil para la depuración".

+1

CReal no le dará igualdad, ¿verdad? Entonces, creo que eso es un no-go. – sclv

+0

@sclv: Implementa CReal, excepto que puede tomar infinitamente mucho tiempo si se hace correctamente. CReal '==' termina después de 40 dígitos. – kennytm

+0

"Tenga en cuenta que las operaciones de comparación en CReal pueden diferir ya que es (por necesidad) imposible implementarlas correctamente y siempre terminar". Eso descarta a CReal para mí. Necesito evitar la conversión a números reales para obtener estos valores. –

8

Parece que está buscando Sistema de Algebra Informática (CAS) en Haskell. A pesar de tantas referencias a objetos algebraicos en los nombres de los paquetes/módulos de Haskell, nunca he oído hablar de un sistema CA de propósito general y bien mantenido en Haskell (como SymPy o Sage en Python).

Sin embargo, en the list of Computer Algebra Systems en la Wikipedia he encontrado una referencia a

DoCon. The Algebraic Domain Constructor

Utiliza un non-standard license, pero me atrevo a decir que sigue siendo de código abierto (aunque con los requisitos de cambio de nombre y atribución). A partir de julio de 2010, docon-2.11 sigue compilando con GHC 6.12.1 y ejecuta demostraciones/pruebas (solo tuve que insertar un pragma LANGUAGE FlexibleContexts en un archivo de la demostración).

DoCon está bien documentada (362 páginas del Manual). Su manual es empaquetado dentro de la postal con las fuentes, por lo que lo puso en línea por separado para mayor comodidad:

DoCon 2.11 Manual.ps

Por favor, revise para comprobar si se adapta a sus necesidades.

+0

DoCon parece un poco pesado para el propósito del póster. – sclv

+0

Estoy de acuerdo, pero no sé nada más sobre Haskell. – sastanin

+0

DoCon se ve bastante formidable.Todo lo que realmente necesito es una implementación de Haskell del algoritmo de Landau para eliminar los radicales (y algo para hacer aritmética básica con racionales, raíces cuadradas, etc.). –

4

Eche un vistazo al paquete cyclotomic, que implementa la aritmética exacta en los números ciclotómicos. Estos incluyen todos los números algebraicos (por lo tanto, en particular 1 + sqrt (3)) y las operaciones clave (como la igualdad) son decidibles.

No proporcionan una instancia Ord (por la misma razón los números complejos no), pero uno puede implementar una instancia no semántica si todo lo que necesita es usarlos como claves en una tabla de búsqueda. Puede ponerse en contacto con el autor para saber cómo hacerlo correctamente, ya que puede haber invariantes que no son obvios (por ejemplo, uno debe tener cuidado con los ceros en el mapa coeffs).

Cuestiones relacionadas