误差和残量

数值求解方程\(f(x)=0\)的根,有多种方法测算结果的近似程度。最直接的方法是计算误差。第\(n\)步迭代结果与真值\(x^\*\)的差即为第\(n\)步迭代的误差:

\begin{equation*}
e_n=x_n-x^*
\end{equation*}

但是,我们一般是不知道真实值\(x^\*\)的,否则,我们也不会费劲去算了。所以,直接计算误差是不可能的,需要我们另辟蹊径。

一个可能的方法是,程序一直运行,直到结果不再变化。这个方法通常还是很管用的。有时候,程序结果不再变化并不意味着\(x_n\)接近真实值,这时候这个方法就不灵了。

对于牛顿法,我们也可以采用这样的方法:每一步结果有效数字位数加倍。这个方法在程序里难以应用。

在很多情况下,我们不是测算\(x_n\)逼近\(x^\*\)的程度,而是采用另外一个很实用的方法,计算\(x_n\)满足方程的程度,即计算\(y_n=f(x_n)\)与0接近的程度,用\(r_n=f(x_n)-0\)来表征,这个量称为残量(residual)。大多数情况下,我们只关心\(r_n\)的绝对值,所以我们只需要考察\(\mid r_n \mid=\mid f(x_n)\mid\)。

if ... end 语句

我们设定一个公差\(\mid r_n \mid=\mid f(x_n)\mid\),然后我们通过if ... end 语句,将收敛条件包括在牛顿法程序里。程序如下:

function x = mynewton (f,f1 ,x0 ,n,tol )
% Solves f(x) = 0 by doing n steps of Newton ’s method starting at x0.
% Inputs : f -- the function , input as an inline
% f1 -- it ’s derivative , input as an inline
% x0 -- starting guess , a number
% tol -- desired tolerance , prints a warning if |f(x)|> tol
% Output : x -- the approximate solution
x = x0; % set x equal to the initial guess x0
for i = 1:n % Do n times
x = x - f(x)/ f1(x) % Newton ’s formula
end
r = abs (f(x))
if r > tol
warning (’The desired accuracy was not attained ’)
end

程序里,if ... end 为条件语句。if 后面的条件 abs(y) > tol 如果满足,则执行后面的语句,如果不满足,程序直接跳至与if 对应的end。

下面我们在命令窗口操练一下。

>> f = inline('x.^3-5','x')
f =
Inline function:
f(x) = x.^3-5
>> f1 = inline('3*x.^2','x')
f1 =
Inline function:
f1(x) = 3*x.^2
>> mynewton(f,f1,2,5,0.01)
ans =
1.709975946676697
>> mynewton(f,f1,2,5,1e-10)
ans =
1.709975946676697
>>

补充:如果选\(n=3\),才会看到tol取得很小时出的警告信息。可能以前的版本算法落后,\(n=5\)还能看到警告信息。

循环: while ... end 语句

前面这一版牛顿法程序可以告诉我们是不是收敛到指定精度的结果,但是我们还是需要输入迭代步数\(n\)。即便对于不太奇异的函数,如果步数\(n\)太小,也可能达不到指定的精度,然后就得增大\(n\),重新计算。如果步数\(n\)太大,就会做不必要的迭代,浪费时间。

控制迭代步数的一个方法是,使迭代一直进行,直到残量\(\mid r_n \mid =\mid f(x) \mid=\mid y \mid\)足够小。在Matlab里,这可以通过 while ... end 循环实现:

function x = mynewtontol (f,f1 ,x0 , tol )
x = x0; % set x equal to the initial guess x0
y = f(x);
while abs (y) > tol % Do until the tolerence is reached .
x = x - y/f1(x) % Newton ’s formula
y = f(x)
end

语句 while ... end是个循环,与for ... end类似,只是前者循环次数不是固定的,会一直进行到条件 abs(y) > tol满足为止。

上述程序的一个缺点是,abs(y)可能永远都不会比tol小,这就会导致程序会一直运行下去,直到我们手动终止。比如把公差设置的非常小:

>> tol = 10^(-100)

然后对函数\(f(x)=x^3-5\)再运行下该程序。

你可以用快捷键Ctrl-c结束程序。

要避免无限循环,可以再增加一个计数变量,比如i,控制迭代次数的上限。

于是,我们可写出如下程序:

function x = mynewtontol (f,f1 ,x0 , tol )
x = x0; % set x equal to the initial guess x0.
i =0; % set counter to zero
y = f(x);
while abs (y) > tol && i < 1000
% Do until the tolerence is reached or max iter .
x = x - y/f1(x) % Newton ’s formula
y = f(x)
i = i +1; % increment counter
end

练习

1 几何级数满足如下关系:

\begin{equation*}
\sum_{i=0}^{\infty}\frac{1}{r^i}=\frac{1}{1-r},\mid r \mid \lt \mid
\end{equation*}

下面是一个计算几何级数的脚本程序,但遗漏了一行,请补充完整,并验证程序是否可行。对于\(r=0.5\),迭代步数需要达到多少程序才能收敛?结果与精确值2相差多少?

% Computes a geometric series until it seems to converge
format long
format compact
r = .5;
Snew = 0; % start sum at 0
Sold = -1; % set Sold to trick while the first time
i = 0; % count iterations
while Snew > Sold % is the sum still changing ?
Sold = Snew ; % save previous value to compare to
Snew = Snew + r^i;
i=i +1;
Snew % prints the final value .
i % prints the # of iterations .

在程序尾部增加一行,计算相对误差。计算\(r = 0.9,\quad 0.99,\quad 0.999,\quad 0.9999,\quad 0.99999,\quad 0.999999\)等情况,并将每个\(r\)所对应的迭代步数和相对误差填在一个表格内。

2 修改第3讲中的练习2的程序,计算当球跳起高度低于\(1\mathrm {cm}\)时,球走过的距离。要求用while 循环,不能用for 循环和if 语句。

Todd's Matlab讲义第4讲:控制误差和条件语句的更多相关文章

  1. Todd's Matlab讲义第5讲:二分法和找根

    二分法和if ... else ... end 语句 先回顾一下二分法.要求方程\(f(x)=0\)的根.假设\(c = f(a) < 0\)和\(d = f(b) > 0\),如果\(f ...

  2. Todd's Matlab讲义第3讲:牛顿法和for循环

    方程数值求解 下面几讲,我们将聚集如下方程的解法: \begin{equation} f(x)=0 \tag{3.1}\label{3.1} \end{equation} 在微积分课程中,我们知道,许 ...

  3. Todd's Matlab讲义第2讲:Matlab 编程

    Matlab也可以编程,可存为以.m为后缀的文件,称为M文件.M文件有两种:函数和脚本. 函数程序 点击新建图标,在打开的窗口里输入如下内容: function y = myfunc (x) y = ...

  4. Todd's Matlab讲义第1讲:向量,函数和作图

    向量 Matlab 中最基本的对象是矩阵,向量是特殊的矩阵.行向量是\(1\times n\)矩阵,列向量是\(m\times 1\)矩阵.输入如下行向量: >> v=[0 1 2 3] ...

  5. Todd's Matlab讲义第6讲:割线法

    割线法 割线法求解方程\(f(x)=0\)的根需要两个接近真实根\(x^\*\)的初值\(x_0\)和\(x_1\),于是得到函数\(f(x)\)上两个点\((x_0,y_0=f(x_0))\)和\( ...

  6. Python基础6- 流程控制之if条件语句

    Python条件语句是通过判断一条或多条条件语句的执行结果来决定执行哪条代码块的.Python 中if 语句用于控制程序的执行,基本形式为:if 判断条件: 执行语句……else: 执行语句…… #c ...

  7. Excel VBA入门(三) 流程控制1-条件选择

    VBA中的流程控制分为两种,其一是条件结构式的,即根据条件判断的结果去选择性执行相应的语句(块):另一种是循环,即循环地执行语句(块).本节介绍第一种. 1. IF if 语句其实包含有几种形式: ① ...

  8. java基础 流程控制和条件语句,循环语句

    顺序结构 程序的顺序结构: 如果代码里没有流程控制,程序是按照书写的格式从上而下一行一行执行的, 一条语句执行完之后继续执行下一条语句,中间没有判断和跳转,直到程序的结束. if语句 if语句使用bo ...

  9. Java基础—控制流程语句(条件语句与循环结构)

    与任何程序设计语言一样,Java使用条件语句和循环结构确定控制流程.Java的控制流程结构与C和C++的控制流程机构一样,只有很少的例外情况.没有goto语句,但break语句可以带标签,可以利用它实 ...

随机推荐

  1. Socket与SocketServer结合多线程实现多客户端与服务器通信

    需求说明:实现多客户端用户登录,实现多客户端登录一般都需要使用线程技术: (1)创建服务器端线程类,run()方法中实现对一个请求的响应处理: (2)修改服务器端代码,实现循环监听状态: (3)服务器 ...

  2. BZOJ1031: [JSOI2007]字符加密Cipher

    传送门 后缀数组模板题 //BZOJ 1031 //by Cydiater //2016.9.21 #include <iostream> #include <cstring> ...

  3. EmguCV 一些基本操作

    http://www.cnblogs.com/alsofly/p/3524866.html?utm_source=tuicool&utm_medium=referral 一.先是在程序中图像的 ...

  4. 点亮第一个LED灯

    1.代码: #include <reg52.h> //<reg51.h>  包含52单片机寄存器库sbit led = P1^0;    //只有地址可以被8整除的 才可以用s ...

  5. SQL Server 2012 安装

    SQL Server 2012 安装过程很漫长, 里面很多界面不一一截取了,我分别在win7 企业版 64位 和 win10专业版SP1 64位 装了SQL Server 2012 ,都没有问题. 1 ...

  6. js012-DO2和DOM3

    js012-DO2和DOM3 本章内容: DOM2和DOM3的变化 操作样式的ODM API DOM 遍历与范围 DOM2级核心:在一级核心基础上构建,为节点添加了更多方法和属性 DOM2级视图:为文 ...

  7. asp.net ListBox 移除操作的思路

    ArrayList arrRight = new ArrayList(); protected void ImageButton1_Click(object sender, ImageClickEve ...

  8. SVM松弛变量-记录毕业论文3

    上一篇博客讨论了高维映射和核函数,也通过例子说明了将特征向量映射到高维空间中可以使其线性可分.然而,很多情况下的高维映射并不能保证线性可分,这时就可以通过加入松弛变量放松约束条件.同样这次的记录仍然通 ...

  9. Git创建ssh-key

    打开git bash界面,输入: ssh-keygen -t rsa -C "yourname@email.com" 一路回车,后续保持默认值即可. 把C:\users\yourn ...

  10. C# 文件操作大全

    1.创建文件夹//using System.IO;Directory.CreateDirectory(%%1); 2.创建文件//using System.IO;File.Create(%%1); 3 ...