《数值计算方法》勘误

书籍信息

        主编    郑成德

        出版    清华大学出版社

        版次    2010年8月第1版

        印次    2013年8月第3次印刷

        ISBM    978-7-302-23282-7

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

        注:以下所有补充意见,仅代表个人观点。如果需要,本文会继续更新。——代号4101

        最近更新:2013-10-31 01:45

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


第一章    基本概念与数学软件MATLAB简介

        1、(第14页:班级同学发现)

        原文:plot(x,x^3-x-1;hold off

        更正:plot(x,x.^3-x-1);hold off

        错误解释:此处x是向量,不能进行矩阵相乘运算;而且原意就是进行点乘运算。


        2、(第15~16页)

       (3)if 和 break 循环语句 ,代码和求解结果都错了。

        书上的代码:

        ①第三行第一个条件是第二个条件的子集,属多余,而第二个条件是正解的充分必要条件

        ②第9行的break是多余的

        ③作者的算法,会造成n1,n2更新不及时

        ④代码没有考虑无解的情况,会有无限循环的风险

        参考代码:

a = 36; b = 100; i = 1;             % a 头总数,b 脚总数
while i*2 + (a-i)*4 ~= b && i <= a
    i = i + 1;
end

if i > a, fprintf('No solution.\n');
else
    fprintf('The number of chicken is %d.\n', i);
    fprintf('The number of rabbit is %d.\n', a - i);
end

        运行结果:

        >> chicken

        Thenumber of chicken is 22.

        Thenumber of rabbit is 14.

 

        3、(第16页:主观意见、老师解释)

        习题第1题问到“绝对误差”,其实这里计算不了“绝对误差”,应该改为“误差限”。

        问题的来源可能是不同的书籍定义不同,而从其他书籍引用习题时没有注意,但同一本书中,各概念的定义、使用应该统一一致。

 

        4、(第17页)

        习题第9题,226页给的参考答案选(4),但从精确度的角度考虑该题的话,应该选择(2)。

        证明略,MATLAB验证代码如下:   

f0 = (sqrt(2) - 1)^6; t = 1.414;
f(1) = 1/(t+1)^6;
f(2) = 1/(3+2*t)^3;
f(3) = (3-2*t)^3;
f(4) = 99 - 70*t;

fprintf('结果与精确解的差值放大100倍\n')
for i = 1:4
    fprintf('方案%d: \t%f\n',i,(f(i) - f0)*100)
end

        运行结果:

        结果与精确解的差值放大100倍

               方案1: 0.000268

               方案2: 0.000111

               方案3: 0.003781

               方案4: 1.494937


第二章    解线性方程组的直接方法

        1、(第23页:个人建议)

       gauss.m代码倒数第二行的    x(k,:)=...

        也可以改为                 x(k)=...


        2、(第25页)
        例4的测试数据不太好。

        这里使用到书中gauss,lgauss函数做测试。
        
        运行以下代码:

a=[0.03 58.9;5.31 -6.1]; b = [59.2 47]';
gauss(a,b), lgauss(a,b)

        从中得知,书中的 -1,05×10^4是错误的,应该也是-1.04×10^4。虽然作者想表达的意思很清楚,但测试数据有瑕疵,会降低结论的说服力。

        如果想用计算机做这个实验,可以使用以下代码:

a=[1e-17 1;1 1]; b=[1 2]';   % 要注意double数据类型精度比较高,要让计算机产生舍入误差,数量级要差大一些
gauss(a,b), lgauss(a,b)        

        3、(第26页)

        lgauss.m代码,“%消元”的前一行代码,a(k,:)=a(p,:)后面应该写分号,而不是逗号。如果要输出该中间步骤,也应该是a(p,:)=t后分号改为逗号。


        4、(第44页)

        第6题,227页参考答案有误,应该是x1=1,x2=1/2,x3=1/3

A=[3 2 3;2 2 0;3 0 12];
b=[5 3 7]';
u=chol(A);
x=inv(u'*u)*b

第三章    解线性方程组的迭代法

        0、这章我想吐槽下代码,请同学们仔细区分代码中是数字"1"还是字母“l”,数字"1"左上方一小横是斜向上的,同样位置"l"是水平的。

        1、(第52页)

        jacobi函数中,m=200;后面那个“e=1e-6”改为"e=1e-5"。

        2、(第60页)

        为什么前面jacobi和Segauss函数都用矩阵运算,这里SOR函数突然换成元素运算?书上也没错,但还是贴下我的代码吧。

function [x, k] = SOR(a, b, om, x0, e, m)
% 求解线性方程组的逐次超松弛迭代法,a为系数矩阵,b为常向量
% om为松弛因子,e为精度要求(默认1e-5),m为迭代次数上限(默认200)
    n = length(b); 
    if nargin < 6, m    = 200;          end
    if nargin < 5, e    = 1e-5;         end
    if nargin < 4, x0   = zeros(n,1);   end
    if nargin < 3, om   = 1.5;          end
    
    k = 0; x = x0; 
    x0 = x + 2*e; % 首次要置误差,防止跳出循环
    d = diag(diag(a)); l = tril(a,-1); u = triu(a,1);
    L = inv(d + om*l)*((1-om)*d-om*u); f = om*inv(d + om*l)*b;
    while ( norm(x0-x, inf) > e ) & ( k < m )
        k   = k + 1;
        x0  = x;
        x   = L*x + f;
        k, disp(x')
    end
    if k==m, error('失败或已迭代次数上限');end
end

        3、(第62页)

        习题9,程序跑出的答案和227页的参考答案不同,应该是参考答案错了。

        习题10,同上,这次可以算精确解证明答案确实错了,程序运行结果如下:

>> format rat
>> [5 2 1;-1 4 2;2 -3 -10]\[-12 20 3]'

ans =

      -4       
      91/17    
     -46/17  
        用我的SOR函数跑出的结果是:
>> SOR([5 2 1;-1 4 2;2 -3 -10], [-12 20 3]', 0.9,[0 0 0]', 1e-4);

k =
    11

  -3.999980918435375   5.352923364121614  -2.705870420169305

 

你可能感兴趣的:(matlab,数值分析)