Practices for scientific programming
我想写一篇关于速度和准确性的好文章。如果我没记错的话,这一行:b=(a+1)*a产生了一个比这更好的程序:b=(a^2+a)。
这只是一个例子,可能是错误的,但现在不重要,问题是:在哪里我可以找到科学计算的良好实践的概要?
- 我的目标是可读性。只有当你有证据证明它不够好时,优化才是关键。编译器为您做了很多工作:)
- 不幸的是,在可读性旁边需要考虑数字稳定性,在这种情况下,可读版本应该在注释中。
- a^2和a*a不是一回事。
- 关于精确性,最重要的是对浮点运算有很好的理解。
- @你介意解释一下吗?我天真地认为他们是一样的
- @马可斯:前者是一个异或运算;后者是一个乘法,产生一个指数运算,相当于std::pow(a, 2)。在C++中,就是这样。你的问题被标记为c++。
- +迈克·西摩说的话。例如,在计算求和时,您知道按大小的升序添加数字更准确吗?做POW(sqrt(x),3)或sqrt(pow(x,3))或x*sqrt(x)更准确吗?为什么?对于浮点数和标准函数如何工作来回答这些问题,足够的了解将使您在理解准确性和错误方面处于领先地位。
你可以看看C语言中的数字配方。我不确定它是否介绍或教给你优化,但就C语言中的科学计算而言,它是一本非常流行的书。甚至还有一本C++的书。
- 最近的版本是C++。amazon.com/numeral-recipes-3rd-scientific-computing/dp/…
- @珍雅:太好了!我一直在找类似的东西很长时间了。
- 数字食谱是一本很好的书,是我最喜欢的书之一,但它的主要焦点是计算机上的线性代数、快速傅立叶变换(FFT)算法、编写特殊函数、解常微分方程和偏微分方程等。拿起它,但不要认为它是一本关于你的问题的书。
你在这里所做的被称为过早优化,它是许多邪恶的根源。您应该做的是,编写程序,然后对它们进行分析,并尝试优化关键部分。关于科学计算优化技术的完整概要可能是一本很厚的书,因此在寻找解决方案之前,您需要缩小您的问题范围。
- -1您似乎忽略了这一点——大多数实践都与"速度和准确度"的准确度有关,而确保程序产生正确结果并不是过早的优化。
- 的确。过早的优化是一回事;避免仔细的初始设计而不是生成正确的程序(即使用适当的数据结构并生成准确/正确的数学输出)是另一回事。还有一个平衡要做。我不完全确定这个问题会落在哪一边,请注意。
- +1@lightnessracesinorbit我同意你上面写的内容。当涉及到数值稳定性等问题时,最好尽可能地保持简单,直到证明需要复杂化为止。最关键的是,不要试图自己编写代码,而是依靠数字专家,他们已经提供了几乎任何你想要的东西。例如,@sriram回答
一种有用的技术是在基准类型上创建所有函数模板,然后使用间隔算术类型而不是浮点类型运行算法。这为您提供了一个给定输入集结果精度的上限,而无需进行广泛的数值分析。
了解你的结果和任何中间产物的预期数量也是很重要的,这样你就可以快速判断出是否出了问题。
这不是通常的"过早优化"讨论。问题不在于性能,而在于准确性。我同意这一观点——这非常值得注意。
最需要注意的是舍入误差的累积。
如果可以,则应在添加数组之前按升序对数组进行排序:
网址:http://www.ibiblio.org/pub/languages/fortran/ch4-9.html
您可能会找到以下帮助:
http://www.codeproject.com/articles/25294/avointing-overflow-undflow-and-loss-of-precision
你需要阅读每个计算机科学家应该知道的关于浮点运算的知识
浏览一下https://sciccomp.stackexchange.com/甚至四处打听可能会让你受益匪浅。
祝你好运!