Решение уравнения Хаскелла в действительных числах - PullRequest
2 голосов
/ 13 февраля 2011

Я только начал играть с GHCi. Я вижу, что генераторы списков в основном решают уравнение в данном наборе:

Prelude> [x | x <- [1..20], x^2 == 4]
[2]

(находит только один корень, как и ожидалось)

Теперь, почему я не могу решить уравнения с результатами в ℝ, учитывая, что решение включено в указанный диапазон?

[x | x <- [0.1,0.2..2.0], x*4 == 2]

Как я могу решить такие уравнения в наборе действительных чисел?

Редактировать: Извините, я имел в виду 0.1, конечно.

Ответы [ 4 ]

8 голосов
/ 13 февраля 2011

Понимание списка не решает уравнения , оно просто генерирует список элементов, которые принадлежат определенным наборам. Если ваш набор определен как любой x в [1..20] такой, что x^2==4, это то, что вы получите.

Вы не можете сделать это с полным списком любого действительного числа от 0.01 до 2.0, потому что такой реальный список не может быть представлен в haskell (или лучше: его нельзя представить на любом компьютере), так как он имеет бесконечное числа с бесконечной точностью.

[0.01,0.2..2.0] - список из следующих чисел:

Prelude> [0.01,0.2..2.0]
[1.0e-2,0.2,0.39,0.5800000000000001,0.7700000000000001,0.9600000000000002,1.1500000000000004,1.3400000000000005,1.5300000000000007,1.7200000000000009,1.910000000000001]

И ни одно из этих чисел не удовлетворяет вашему поведению.


Обратите внимание, что вы, вероятно, имели в виду [0.1,0.2..2.0] вместо [0.01,0.2..2.0]. Тем не менее:

Prelude> [0.1,0.2..2.0]
[0.1,0.2,0.30000000000000004,0.4000000000000001,0.5000000000000001,0.6000000000000001,0.7000000000000001,0.8,0.9,1.0,1.1,1.2000000000000002,1.3000000000000003,1.4000000000000004,1.5000000000000004,1.6000000000000005,1.7000000000000006,1.8000000000000007,1.9000000000000008,2.000000000000001]
5 голосов
/ 14 февраля 2011

Как уже упоминалось, это не эффективный способ решения уравнений, но это можно сделать с помощью соотношений.

Prelude> :m +Data.Ratio 
Prelude Data.Ratio> [x|x<-[1%10, 2%10..2], x*4 == 2]
[1 % 2]

Считайте x % y как x divided by y.

4 голосов
/ 13 февраля 2011

Проблема с плавающей запятой может быть решена следующим образом:

Prelude> [x | x <- [0.1, 0.2 .. 2.0], abs(2 - x*4) < 1e-9]
[0.5000000000000001]

Для справки, почему числа с плавающей запятой могут создавать проблемы, смотрите это: Сравнение чисел с плавающей запятой

3 голосов
/ 13 февраля 2011

Прежде всего [0.01,0.2..2.0] не будет включать 0,5, даже если арифметика с плавающей запятой была точной. Я полагаю, вы имели в виду первый элемент 0.1.

Список [0.1,0.2..2.0] не содержит 0,5, потому что арифметика с плавающей запятой неточна, а 5-й элемент [0.1,0.2..2.0] равен 0.5000000000000001, а не 0,5.

...