2010-07-21 1 views
26

Мне нужно манипулировать выражениями как 1 + sqrt (3) и выполнять базовые арифметические операции, такие как сложение, вычитание и деление. Я хотел бы, чтобы результат был в какой-то канонической форме, чтобы его можно было использовать в качестве ключа на карте. Поворот 1 + sqrt (3) в поплавок невозможен из-за проблем округления.Библиотека Haskell, такая как SymPy?

Я использовал SymPy для этой задачи в Python. Есть ли эквивалентная родная библиотека для Haskell?

+2

Вы хотите '√2 - 1 == 1/(√2 + 1)'? – kennytm

ответ

7

Пожалуйста, проверьте the numbers package. Если вам нужно хранить точные цифры, такие как «1 + √3», вы можете использовать Data.Number.CReal вместо символической арифметики. Он хранит выражения и может быть вычислен на произвольное количество цифр при необходимости.

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

Существует также Data.Number.Symbolic модуль в пакете, но описание говорит: «Это в основном полезно для отладки».

+1

CReal не даст вам равноправия, верно? Поэтому я думаю, что это не гонка. – sclv

+0

@sclv: Он реализует CReal, за исключением того, что он может длиться бесконечно долго, если все сделано правильно. CRyal '==' заканчивается после 40 цифр. – kennytm

+0

«Обратите внимание, что операции сравнения на CReal могут расходиться, поскольку (по необходимости) невозможно реализовать их правильно и всегда заканчивать». Это исключает CReal для меня. Мне нужно избегать преобразования в реальные числа, чтобы хэшировать эти значения. –

8

Возможно, вы ищете компьютерную алгебраическую систему (CAS) в Хаскелле. Несмотря на столько ссылок на алгебраические объекты в именах пакетов/модулей Haskell, я никогда не слышал об общей цели и ухоженной системе CA в Haskell (например, SymPy или Sage в Python).

Однако в the list of Computer Algebra Systems в Википедии я нашел ссылку на

DoCon. The Algebraic Domain Constructor

Он использует non-standard license, но я осмелюсь сказать, что это до сих пор открытый исходный код (хотя и с требованиями переименовывать и атрибуцию). По состоянию на июль 2010 года docon-2.11 по-прежнему строит с GHC 6.12.1 и запускает демонстрационные версии/тесты (мне нужно было только вставить прагму LANGUAGE FlexibleContexts в один файл демо).

DoCon хорошо документирован (362 страницы Руководства). Его Руководство упакована внутри молнии с источниками, так что я положил его в Интернете отдельно для удобства:

DoCon 2.11 Manual.ps

Пожалуйста, полистать, чтобы проверить, если он соответствует вашим потребностям.

+0

DoCon кажется немного тяжеловесом для цели плаката. – sclv

+0

Согласен, но я ничего не знаю о Хаскелле. – sastanin

+0

DoCon выглядит довольно грозным.Все, что мне действительно нужно, это реализация алгоритма Ландау для определения радикалов (и что-то, что делает базовую арифметику с рациональными и квадратными корнями и т. Д.). –

4

Ознакомьтесь с пакетом cyclotomic, который реализует точную арифметику по круговым числам. К ним относятся все алгебраические числа (следовательно, в частности 1 + sqrt (3)), а ключевые операции (например, равенство) разрешимы.

Они не предоставляют экземпляр Ord (по той же причине, что и комплексные числа), но можно реализовать не семантический экземпляр, если все, что нужно, - использовать их в качестве ключей в таблице поиска. Вы можете связаться с автором о том, как это сделать правильно, так как могут быть некоторые инварианты, которые не являются очевидными (например, может быть нужно быть осторожным относительно нулей на карте coeffs).