C++ C++/哈斯克尔

C++ C++/哈斯克尔,c++,math,haskell,lazy-evaluation,arbitrary-precision,C++,Math,Haskell,Lazy Evaluation,Arbitrary Precision,最近,我在读了很多书之后,偶然发现了精确实数的问题 我已经找到了一些讨论使用有符号数字流实现精确算法的论文。使用无限流实现任意精度,可以在函数式语言(如Haskell)中使用惰性列表实现出色的实用实现。然而,用函数式语言讨论此类实现的论文似乎得出了性能非常差的结论 现在,我了解到,与标准浮点表示法相比,精确的非硬件实现通常会有相对较差的性能,但我感兴趣的是用命令式语言(特别是C++)和一系列操作/函数提供更高效的实现(算术运算、三角函数、exp、log等) < > >我的问题(s):对于一个有符

最近,我在读了很多书之后,偶然发现了精确实数的问题

我已经找到了一些讨论使用有符号数字流实现精确算法的论文。使用无限流实现任意精度,可以在函数式语言(如Haskell)中使用惰性列表实现出色的实用实现。然而,用函数式语言讨论此类实现的论文似乎得出了性能非常差的结论

现在,我了解到,与标准浮点表示法相比,精确的非硬件实现通常会有相对较差的性能,但我感兴趣的是用命令式语言(特别是C++)和一系列操作/函数提供更高效的实现(算术运算、三角函数、exp、log等)

< > >我的问题(s)<强>:对于一个有符号的数字/懒惰流表示,是否有一些固有的慢,导致了性能不佳,或者是Haskell?是什么使它变慢?是否可以用C++中的惰性流实现有符号的数字流表示,从而实现(显著)?性能比Haskell的同类产品更好,或者这是一个徒劳的练习?也许是重建为迭代

我知道有两个C++库,RealLIB和IrRAM,它们都能实现有效的实数计算,然而,这些算法似乎使用区间算术,把实数表示为收缩嵌套区间,它看起来不像是“纯”的无限流(请指正,如果你不同意的话!).但也许只有这些方法才能取得良好的效率

欢迎任何输入!

我担心“数字是一个懒惰的数字流”方法注定比更直接的方法效率低,即使数字基数很大(比如2^64或更多):

  • 惰性评估意味着,最终,你所认为的数字实际上是代表导致它的计算的DAG。要求多出一个数字可能会重新触发该DAG每个节点的计算。一天结束时,你花在内部管理上的时间远远多于计算上的时间

  • 您可能无法使用更复杂的算法进行基本计算。例如,乘法的FFT方法显然是不可能的

  • 这并不意味着算法会很简单。想想如何在加法中处理当前99999的结果。你需要准备好为所有这些9加上一个进位。现在试着想想如何做乘法。一种带有惰性表达式的语言可能有助于表达它,但第一个问题会让你更加困难;我很高兴得知编译器能够为此进行优化,但我担心他们不能

是否有一个符号数字/懒惰流表示固有的慢,导致性能不佳,或者是Haskell?是什么使它变慢?是否可以用C++中的懒惰流实现有符号的数字流表示,从而实现(显著)?性能比Haskell的同类产品更好,或者这是一个徒劳的练习?也许是重建为迭代

懒惰流最有效地表示为具有延迟函数组件的数据。这是GHC使用中相当有效的Haskell实现的表示,而C++中无论如何都需要使用它。没有特殊的“快速”。你可以用C++编写的懒惰版本,这在哈斯克尔编译器研究的20年中还没有被尝试过,而且更多的是回到Algol。

有关如何最有效地实现惰性数据结构的研究的更多详细信息,请参阅

现在,鉴于缺乏关于基准的信息,有几个可能的答案:

  • 代码编写得很糟糕(更好的实现可能不会太慢)
  • 将大数字表示为标记的惰性位是空间效率低下的,会导致各种硬件瓶颈
  • 数字的延迟流表示只允许某些线性算法。更密集的表示可能允许具有更高复杂性或绝对性能的算法

我猜是后两点。C++版本的懒惰只不过是努力达到GHC已经开始的同一点,所以为什么不玩文章中的代码,看看你是否能更快地完成它。就是错了。要么某个东西符合你的要求,要么不符合。我的意思是,你怎么定义纯度?这完全是浪费时间。@DeadMG,纯度有一个非常具体的技术含义:一个函数的结果必须只取决于它的参数,而不取决于系统中的其他状态。我认为惰性评估指的是使用infin使用符号数字表示法,我们可以将x=1/3表示为[0,3,3,…],y=2/3表示为[0,6,6,…],x+y表示为[1,0,0,0,…]由于使用区间分析,我们可以猜测第一个数字为1,并使用负数字(有符号数字表示)纠正我们的猜测是否不正确。所以我们存储的是实际数字,而不是代表计算的DAG?谢谢。谢谢你的回答,唐。我想我已经确信嵌套区间方法更适合于精确实数算术的高效命令式实现,就像有符号数字一样优雅在Haskell中的代表可能是!