二分法和if ... else ... end 语句

先回顾一下二分法。要求方程\(f(x)=0\)的根。假设\(c = f(a) < 0\)和\(d = f(b) > 0\),如果\(f(x)\)是连续函数,那么方程的根\(x^*\)一定位于\(a\)和\(b\)之间。然后,我们看一下\(a\)和\(b\)中点\(x=(a+b)/2\),计算函数值\(y=f(x)\),如果函数不为0,比较\(c\)、\(d\)和\(y\)的符号,确定新的二分区间。具体来说,如果\(c\)和\(y\)同号,新的二分区间就是\([x,b]\),如果\(c\)和\(y\)异号,新的二分区间就是\([a,x]\)。如图5.1所示。



图5.1 二分法

在不同的情况下做不同的事情,在程序里,这叫做流程控制。达到这个目的,最通常的方法是通过if ... else ... end语句来实现,这个语句是我们前面讲过的if ... end语句的扩展。

误差界

二分法的一个好处是,我们一直知道方程的真实的根\(x^*\)一定位于二分区间内,这样我们就可以知道最大误差可以是多少,一定小于区间大小的一半,即

\begin{equation*}
\mid x-x^* \mid \lt \frac{b-a}{2}
\end{equation*}

其中\(x=(a+b)/2\),为区间的中点。

二分法程序如下:

function [x e] = mybisect (f,a,b,n)
% function [x e] = mybisect (f,a,b,n)
% Does n iterations of the bisection method for a function f
% Inputs : f -- an inline function
% a,b -- left and right edges of the interval
% n -- the number of bisections to do.
% Outputs : x -- the estimated solution of f(x) = 0
% e -- an upper bound on the error
format long
% evaluate at the ends and make sure there is a sign change
c = f(a); d = f(b);
if c*d > 0.0
error (’Function has same sign at both endpoints .’)
end
disp (’ x y’)
for i = 1:n
% find the middle and evaluate there
x = (a + b )/2;
y = f(x);
disp ([ x y])
if y == 0.0 % solved the equation exactly
e = 0;
break % jumps out of the for loop
end
% decide which half to keep , so that the signs at the ends differ
if c*y < 0
b=x;
else
a=x;
end
end
% set the best estimate for x and the error bound
x = (a + b )/2;
e = (b-a )/2;

此程序不仅给出了方程的近似根,还给出了最大可能误差。

二分法总是可以进行下去,而牛顿法,如果初值\(x_0\)不足够接近\(x^*\)的话,程序可能不会收敛。而二分法,每一步的区间都可以缩一半,最终想缩多小就能缩多小。

找根

二分法和牛顿法都可以用来找根的任意近似值,但都需要先给定初值。二分法需要两个初值\(a\)和\(b\),并要求真实的根位于二者之间,牛顿法只需要一个初值\(x_0\),要求不能离真实的根太远。如何确定合适的初值?看情况而定。如果你一次只解一个方程,最好先把函数画出来,通过图上的函数零点,可以很容易定出合适的初值。

有些情况下你不是一次就解一个方程,而是多次求解同一个方程,只是系数不同。当你开发某特定用途的软件的时候,常常会遇到这种情况。在这种情况下,首先你要利用问题的自然条件,比如选定的区间要符号实际情况。然后通过区间内某些点的符号,很容易就可以逐渐接近方程的真实的根了。方程的根一定位于符号相异的两点之间。下面的程序就是在一给定的区间\([a_0,b_0]\)之间找方程的根:

function [a,b] = myrootfind (f,a0 ,b0)
% function [a,b] = myrootfind (f,a0 ,b0)
% Looks for subintervals where the function changes sign
% Inputs : f -- an inline function
% a0 -- the left edge of the domain
% b0 -- the right edge of the domain
% Outputs : a -- an array , giving the left edges of subintervals
% on which f changes sign
% b -- an array , giving the right edges of the subintervals
n = 1001; % number of test points to use
a = []; % start empty array
b = [];
% split the interval into n -1 intervals and evaluate at the break points
x = linspace (a0 ,b0 ,n);
y = f(x);
% loop through the intervals
for i = 1:(n -1)
if y(i)*y(i +1) < 0 % The sign changed , record it
a = [a x(i)];
b = [b x(i +1)];
end
end
if size (a ,1) == 0
warning (’no roots were found ’)
end

如果没有任何已知信息来找方程的根,事情就比较难办,好在这种情况在工程问题里不常见。

一旦确定出根所在的区间\([a, b]\),\(a\)和\(b\)就可以作为二分法和割线法(见下一讲)的初值。对于牛顿法,初值\(x_0\)一个明显的选法是\(x_0 = (a + b)/2\)。一个更好的选法是利用割线法选\(x_0\)。

练习

1 修改程序mybisect,在给定公差下解方程。应用你的程序,求解方程\(f(x) = 2x^3 + 3x − 1=0\)的根,初始区间是\([0,1]\),公差为\(10^{-8}\)。程序需要运行多少步能达到公差的要求?最终残量有多大?

2 用纸和计算器对于函数\(f(x) = x^3 − 4\)和初始区间\([1,3]\)进行3步二分法迭代,计算每步结果的误差和相对误差,并与第3讲练习3的结果比较。

Todd's Matlab讲义第5讲:二分法和找根的更多相关文章

  1. Todd's Matlab讲义第4讲:控制误差和条件语句

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

  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. 二分法和牛顿迭代实现开根号函数:OC的实现

    最近有人贴出BAT的面试题,题目链接. 就是实现系统的开根号的操作,并且要求一定的误差,其实这类题就是两种方法,二分法和牛顿迭代,现在用OC的方法实现如下: 第一:二分法实现 -(double)sqr ...

  7. Python实现二分法和黄金分割法

    运筹学课上,首先介绍了非线性规划算法中的无约束规划算法.二分法和黄金分割法是属于无约束规划算法的一维搜索法中的代表. 二分法:$$x_{1}^{(k+1)}=\frac{1}{2}(x_{R}^{(k ...

  8. Flow construction SGU - 176 有源汇有上下界最小流 二分法和回流法

    /** 题目:Flow construction SGU - 176 链接:https://vjudge.net/problem/SGU-176 题意: 有源汇有上下界的最小流. 给定n个点,m个管道 ...

  9. Matlab 之meshgrid, interp, griddata 用法和实例

    http://blog.sina.com.cn/s/blog_67f37e760101bu4e.html 实例结果http://wenku.baidu.com/link?url=SiGsFZIxuS1 ...

随机推荐

  1. Bzoj2118 墨墨的等式

    Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1488  Solved: 578 Description 墨墨突然对等式很感兴趣,他正在研究a1x1+ ...

  2. bzoj2765[JLOI2010]铁人双项比赛

    题意:铁人双项比赛由长跑和骑自行车组成,参赛选手必须先完成k公里的长跑,然后完成r公里的骑车,才能到达终点.参赛选手有的擅长长跑,有的擅长骑车. 如果总赛程s=k+r一定,那么K越大,对擅长长跑的选手 ...

  3. MyCCL特征码定位原理学习

    这段时间学习WEB方面的技术,遇到了木马免杀特征码定位的问题,这里做一下学习笔记. 这里对MyCCL的分块原理做一下探究 对指定文件生成10个切块 对指定的木马进行切块后,文件列表是这样的. 注意这里 ...

  4. python反射

    python反射 python的反射是基于字符串的形式去对象(模块)中操作其成员.此操作是动态的,常用于web开发中url参数中对应模块或者函数的反射. 下面开始具体说明: 场景需求: 我的pytho ...

  5. Hackerrank Going to the Office

    传送门 Problem Statement Ms.Kox enjoys her job, but she does not like to waste extra time traveling to ...

  6. mysql 某周的起始和结束日期

    转自:http://bbs.csdn.net/topics/370096126 t_table有数据如下:year    Week2011    22011    32011    42011     ...

  7. linux 学习基础7之脚本的练习

    练习:传递一个用户名参数给脚本,判断此用户的用户名跟其基本组的组名是否一致,并将结果显示出来.写一个脚本:#!/bin/bashUSER=$1if [ !  $# -eq 1 ];then  echo ...

  8. photoshop切图介绍

    第一部分:界面设置 1.点击“文件-新建”(或者ctrl+n)打开一个新建对话框.名称可随意填写.“预设”设置为自定,“宽度”一般选择1920,“单位”选为像素.“高度”可选择为2000,“单位”选为 ...

  9. 深入理解javascript中执行环境(作用域)与作用域链

    深入理解javascript中执行环境(作用域)与作用域链 相信很多初学者对与javascript中的执行环境与作用域链不能很好的理解,这里,我会按照自己的理解同大家一起分享. 一般情况下,我们把执行 ...

  10. oneM2M

    http://www.ccsa.org.cn/organization/intro.php?org=oneM2M 一.成立背景 随着物联网技术研发及市场推广的不断深入,全球各通信标准化组织都在加强物联 ...