【问题标题】:Haskell equation solving in the real numbers实数中的 Haskell 方程求解
【发布时间】:2011-02-13 12:00:01
【问题描述】:

我刚开始玩 GHCi。我看到列表生成器基本上解决了给定集合中的方程:

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

(按预期只找到一个根)

现在,考虑到解 包含在指定范围内,为什么我不能求解结果为 ℝ 的方程?

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

如何在实数集中求解此类方程?

编辑:对不起,我的意思是0.1,当然。

【问题讨论】:

  • 啊,“R”是指实数,而不是语言 R!不幸的是,没有办法在两个数字(或所有浮点数)之间生成 R 的所有成员的集合,这将是一个非常大的集合。
  • @Andrew... 比难以置信的大 :-) 我们不要再隐藏他的真相了:在 0.001 和 0.01 之间有 无限 实数值。无限的。不仅仅是一个密封的宇宙所能容纳的数量惊人的大量粒子。 :)
  • 值得注意的是:像你给出的简单的列表推导式可以简单地写成filter ((==2).(*4)) xs
  • @Stephane... 我的意思是,在特定大小(例如 64 位)的 0 和 2 之间有非常多(但有限)的可表示浮点数。跨度>

标签: haskell math list-comprehension precision equation-solving


【解决方案1】:

列表推导不解方程,它只是生成属于特定集合的项目列表。如果您的集合被定义为[1..20] 中的任何x,例如x^2==4,这就是您所得到的。

你不能用从0.012.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]

【讨论】:

  • 即使您可以生成 0 到 2 之间所有浮点表示的列表,这也是“求解”方程的一种非常低效的方法,因为它只是从从头到尾。
  • 您可以尝试将类型修复为Rational
  • @Andrew Jaffe,此外,浮点数中甚至可能不存在解决方案。 (sqrt 2)^2 == 2 ---&gt; False.
【解决方案2】:

正如其他人所提到的,这不是求解方程的有效方法,但可以通过比率来完成。

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

【讨论】:

    【解决方案3】:

    浮点问题可以这样解决:

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

    有关为什么浮点数会产生问题的参考,请参见:Comparing floating point numbers

    【讨论】:

    • 这确实适用于特定示例,但是 10⁻⁹ 的固定 epsilon 确实不是很可靠,因为浮点不准确性不是绝对的。 (如果数字太小,您可能会得到一大堆误报,如果它们再次太大,则可能无法满足。)要使用浮点数求解方程,应该使用适当的求解器(Newton-Raphson)或至少比较相对偏差。
    【解决方案4】:

    首先[0.01,0.2..2.0] 不会包含 0.5,即使浮点运算是准确的。我假设您的意思是第一个元素是0.1

    [0.1,0.2..2.0] 列表不包含 0.5,因为浮点运算不精确,[0.1,0.2..2.0] 的第 5 个元素是 0.5000000000000001,而不是 0.5。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-11
      • 1970-01-01
      • 2023-03-12
      相关资源
      最近更新 更多