误差和残量

数值求解方程\(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. Compiler Theory(编译原理)、词法/语法/AST/中间代码优化在Webshell检测上的应用

    catalog . 引论 . 构建一个编译器的相关科学 . 程序设计语言基础 . 一个简单的语法制导翻译器 . 简单表达式的翻译器(源代码示例) . 词法分析 . 生成中间代码 . 词法分析器的实现 ...

  2. Node.js使用Mongoose包操作MongoDB数据库

    1. 安装Mongoose npm install mongoose 2. 使用 2.1 创建连接 var mongoose = require('mongoose'); mongoose.conne ...

  3. 一次奇怪的T-shirt展示

    因为这次的第一也是上次的第一然后顺延下来又正好跟女神并列第二,拿到了一件T-shirt.总之,还是应该继续加油.

  4. [转]vim编辑器---批量注释与反注释

    转 在使用vim编写代码的时候,经常需要用到批量注释与反注释一段代码.下面简要介绍其操作. 方法一 块选择模式 插入注释: 用v进入virtual模式 用上下键选中需要注释的行数 按Control+v ...

  5. Ubuntu学习总结-04 搭建JAVA开发环境

    JAVA开发环境是一种跨平台的程序设计语言,可以在windows.LINUX等操作系统上进行开发. 1 下载JDK 从以下地址下所需的jdk安装包 . http://www.oracle.com/te ...

  6. iOS内存管理个人总结

    一.变量,本质代表一段可以操作的内存,她使用方式无非就是内存符号化+数据类型 1.保存变量有三个区域: 1>静态存储区 2>stack 3>heap 2.变量又根据声明的位置有两种称 ...

  7. 获取jsp页面的宽和高

    var winWidth; var winHeight; function getResult() { if(window.innerWidth) { winWidth=window.innerWid ...

  8. js013-事件

    js013-事件 本章内容 理解事件流 使用时间处理程序 不同的事件类型 JS与HTML之间的交互是通过实践实现的.时间就还文档或浏览器窗口发生的一些特定的交互 瞬间.可以使用侦听器来预定事件,以便时 ...

  9. WinForm------Reflector反编译工具下载

    地址: http://www.ddooo.com/softdown/70642.htm

  10. Linq------各种查询语句大全

    查询Title列的第一个值 string str = db.Webs.Select(p => p.Title).FirstOrDefault(); 根据ID,查询Title列的第一个值 b.We ...