zoukankan      html  css  js  c++  java
  • 编程珠玑2第14章 编写数值计算程序

    在工程实践过程中,有时候是离不开数值计算的。

    有时专门针对手头问题编写一个数值函数用来代替库函数,可能会提高程序的运行速度。

    本章从一个计算三围空间中点之间的距离开始(数据挖掘中十分常见)

    程序1计算了用向量A[1..K]和B[1..K]表示的点之间的距离。

    1 Sum:=0.0
    2 for J:=1 to K do
    3 T:=A[J]-B[J]
    4 Sum:=Sum+T*T
    5 return sqrt(Sum)

    程序1的优点是简单,容易理解。但它也有一些缺点:

    1.即使输入中间的计算的都在有效范围,它也可能产生溢出。

    2.程序开销比较大

    我们的目标是提供更快速的用于计算距离的程序。

    如果我们只需要对距离的大小进行比较,那么由sqrt的单调性可以知道它是多余的。

    但是这里我们不能使用这个方法。

    给出牛顿迭代法。牛顿迭代法是一种比较常见的求解方法,我这个就不细讲了。

    为了计算 根号a,由牛顿迭代法可知此处的迭代方程为x=(x+a/x)/2。

    下面给出一个牛顿迭代程序2

     1 T:=abs(A[1]-B[1])
    2 Max:=T;Sum:=T*T
    3 for J:=2 to K do
    4 T:=abs(A[J]-B[J])
    5 if T>Max then Max:=T
    6 Sum:=Sum+T*T
    7 if Sum=0.0 then return 0.0
    8 /*find sqrt(Sum), starting at Max*/
    9 Eps=1.0e-7
    10 Z:=Max
    11 loop
    12 NewZ:=0.5*(Z+Sum/Z)
    13 if abs(NewZ-Z)<=Eps*NewZ then break
    14 Z:=NewZ
    15 return NewZ

    当K=2的时候,程序2比程序1快大约56%。但是当K=16时,程序2只比程序1快大约1.5%。

    此时瓶颈不是平方根,循环以及收敛测试抵消了大部分省出的时间。

    改进方法就是选取一个较好的迭代初始值并固迭代次数。

    假设K<=a2,设D是最大差,那么距离至多为aD。所以所求的值在区间[D,aD]内。

    于是我们可以令初始x为D和aD的几何平均值,即 D*√a。

    当a=4时,x=2D。且作者通过脚手架发现将程序2中的循环展开四次就可以计算出精确结果了。

    需要指出的是,一个快速的距离程序的过程受到很多因素的影响。

    例如,本章的工作对于一个具有硬件平方根指令的系统可能适得其反。

    对于较大的K值,平方根的开销就显得次要了。

    --------------------------------------------------------------------------------------

    编程珠玑II到这里就全部结束了,悲剧的是昨天有个同学跟我说。

    我看的编程珠玑II不是编程珠玑第2版,有机会的话在整个第2版的。
     

  • 相关阅读:
    学Java需要了解的linux系统和unix系统
    51Nod 1649: 齐头并进(最短路)
    51Nod 1694: 两条路径(图论)
    The Preliminary Contest for ICPC Asia Shanghai 2019
    牛客练习赛52 A:数数(快速幂)
    The Preliminary Contest for ICPC Asia Shenyang 2019
    The 2019 Asia Nanchang First Round Online Programming Contest
    2019 年百度之星·程序设计大赛
    2019中国大学生程序设计竞赛(CCPC)
    2019 年百度之星·程序设计大赛
  • 原文地址:https://www.cnblogs.com/2010Freeze/p/2371648.html
Copyright © 2011-2022 走看看