2010-07-21 8 views
26

J'ai besoin de manipuler des expressions comme 1 + sqrt (3) et de faire des opérations arithmétiques de base comme l'addition, la soustraction et la division. Je voudrais que le résultat soit sous une forme canonique de sorte qu'il puisse être utilisé comme une clé dans une carte. Transformer 1 + sqrt (3) en flotteur n'est pas réalisable en raison de problèmes d'arrondi.Bibliothèque Haskell comme SymPy?

J'ai utilisé SymPy pour cette tâche en Python. Y a-t-il une bibliothèque native équivalente pour Haskell?

+2

Voulez-vous '√2 - 1 == 1/(√2 + 1)'? – kennytm

Répondre

7

Veuillez consulter the numbers package. Si tout ce dont vous avez besoin est de stocker des nombres exacts comme "1 + √3", vous pouvez utiliser Data.Number.CReal au lieu de l'arithmétique symbolique. Il stocke les expressions et peut être calculé en un nombre arbitraire de chiffres si nécessaire.

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

Il y a également un module Data.Number.Symbolic dans le paquet mais la description dit « Il est surtout utile pour le débogage ».

+1

CReal ne vous donnera pas l'égalité, non? Donc je pense que c'est un non-go. – sclv

+0

@sclv: Il implémente CReal, sauf que cela peut durer infiniment si c'est fait correctement. Le '' '' de CReal se termine après 40 chiffres. – kennytm

+0

"Notez que les opérations de comparaison sur CReal peuvent diverger car il est (par nécessité) impossible de les implémenter correctement et toujours se terminer." Cela exclut CReal pour moi. J'ai besoin d'éviter la conversion en nombres réels afin de hacher ces valeurs. –

8

Il semble que vous soyez à la recherche de Computer Algebra System (CAS) dans Haskell. En dépit de tant de références à des objets algébriques dans les noms de paquets/modules Haskell, je n'ai jamais entendu parler d'un système d'AC généraliste et bien entretenu dans Haskell (comme SymPy ou Sage en Python).

Cependant, dans the list of Computer Algebra Systems sur Wikipédia que j'ai trouvé une référence à

DoCon. The Algebraic Domain Constructor

Il utilise un non-standard license, mais j'ose dire qu'il est encore Open Source (bien que les exigences de changement de nom et d'attribution). En Juillet 2010 docon-2.11 construit encore avec GHC 6.12.1 et exécute des démos/tests (j'ai seulement dû insérer un pragma LANGUAGE FlexibleContexts dans un fichier de la démo).

DoCon est bien documenté (362 pages du manuel). Son manuel est emballé à l'intérieur de la fermeture éclair avec des sources, donc je l'ai mis en ligne séparément pour des raisons pratiques:

DoCon 2.11 Manual.ps

S'il vous plaît regarder à travers pour vérifier si elle convient à vos besoins.

+0

DoCon semble un peu lourd pour l'objectif de l'affiche. – sclv

+0

Je suis d'accord, mais je ne connais rien d'autre pour Haskell. – sastanin

+0

DoCon semble assez formidable.Tout ce dont j'ai vraiment besoin, c'est d'une implémentation Haskell de l'algorithme de Landau pour dénerver les radicaux (et quelque chose pour faire de l'arithmétique basique avec des racines rationnelles et carrées et ainsi de suite). –

4

Extrayez le package cyclotomic, qui implémente l'arithmétique exacte sur les nombres cyclotomiques. Ceux-ci incluent tous les nombres algébriques (donc en particulier 1 + sqrt (3)) et les opérations clés (comme l'égalité) sont décidables.

Ils ne fournissent pas d'instance Ord (pour la même raison que les nombres complexes), mais on peut implémenter une instance non sémantique s'il suffit de les utiliser comme clés dans une table de recherche. Vous pouvez contacter l'auteur pour savoir comment le faire correctement, car il peut y avoir des invariants qui ne sont pas évidents (par exemple, il faut faire attention aux zéros dans la carte coeffs).