Решение уравнения Хаскелла в действительных числах

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

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

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

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

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

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

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


person PJK    schedule 13.02.2011    source источник
comment
Ах, под «R» вы имеете в виду настоящие числа, а не язык R! К сожалению, нет способа сгенерировать набор всех элементов R между двумя числами (или всех чисел с плавающей запятой), что было бы невероятно большим набором.   -  person Andrew Jaffe    schedule 13.02.2011
comment
@Andrew... более чем невероятно большой :-) давайте не будем больше скрывать от него Истину: между 0,001 и 0,01 существует бесконечное реальное значение. Бесконечный. Больше, чем смехотворно маленькое огромное количество частиц, которое может когда-либо содержать герметичная Вселенная. :)   -  person Stephane Rolland    schedule 13.02.2011
comment
Стоит отметить: понимание списка, подобное простому, которое вы дали, может быть записано просто как filter ((==2).(*4)) xs   -  person Dan Burton    schedule 14.02.2011
comment
@ Стефан ... Я имел в виду, что существует невероятно большое (но конечное) количество представляемых чисел с плавающей запятой от 0 до 2 определенного размера (например, 64-битных).   -  person Andrew Jaffe    schedule 14.02.2011


Ответы (4)


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

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.

person Dan Burton    schedule 13.02.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]
person peoro    schedule 13.02.2011
comment
И даже если бы вы могли сгенерировать список всех представлений с плавающей запятой от 0 до 2, это был бы невероятно неэффективный способ решения уравнения, поскольку он просто ищет одно за другим от начала до конца. - person Andrew Jaffe; 13.02.2011
comment
Вместо этого вы можете попробовать исправить тип на Rational. - person fuz; 13.02.2011
comment
@Эндрю Яффе, кроме того, решение может даже не существовать в числах с плавающей запятой. (sqrt 2)^2 == 2 ---> False. - person luqui; 14.02.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.

person sepp2k    schedule 13.02.2011