循环(loop)是一种 matlab 结构,它允许我们多次执行一系列的语句。循环结构有两种基本形式:while 循环和 for 循环。两者之间的最大不同在于代码的重复是如何控制的。在while 循环中,代码的重复的次数是不能确定的,只要满足用户定义的条件,重复就进行下去。相对地,在 for 循环中,代码的重复次数是确定的,在循环开始之前,我们就知道代码重复的次数了。

1 while 循环

只要满足一定的条件,While 循环是一个重复次数不能确定的语句块。它的基本形如下 如果 expression 的值非零 (true) ,程序将执行代码块 (code block) ,然后返回到 while 语句执行。如果 expression 的值仍然非零,那么程序将会再次执行代码。直到 expression 的值变为 0 ,这个重复过程结束。当程序执行到 while 语句且 expression 的值为 0 之后,程序将会执行 end 后面的第一个语句。 我们将用 whlie 循环编写一个统计分析的程序。 1 统计分析在科学工程计算中,跟大量的数据打交道是非常平常的事,这些数据中的每一个数据都是对我们关心的一些特殊值的度量。本课程的第一次测验的成绩就是一个简单的例子。每一个成绩都对某一个学生在本课程中学到多少东西的度量。 许多的时侯,我们并不关心某一个单个数据。我们可以通过总结得到几个重要的数据,以此告诉我们数据的总体情况。例如,一组数据的平均数 ( 数学期望 )和标准差。平均数的定义如下 :

标准差的定义如下:

标准差则体现随机变量取值与其期望值的偏差。标准差的值较大,则表明该随机变量的取值与其期望值的偏差较大,反之,则表明此偏差较小。如果所有的输入数据都可以在一个数组中得到,这些数据的平均数就可以通过公式 (4.2) 直接计算出来,或应用 matlab 的内建函数 std 。本例的目的是要通过公式 4.1 4.2 计算平均数和标准差,向大家介绍 while循环的应用。我们要执行的算法是读取一个组数据,计算它们的平均数和标准差,最后输出结果。 答案 : 程序必须能读取一系列的测量值,并能够计算出这些测量值的数学期望和标准差。在进行计算之前,我们有 while 循环来读取这些测量值。 当所有的测量值输入完毕,我们必须通过一定的方法来告诉程序没有其它的数据输入了。在这里,我们假设所有测量值均为非负数,我们用一个负数来表示数据输入完毕。当一个负数输入时,程序将停止读取输入值,并开始计算这些数据的数学期望和方差。 1.陈述问题因为我们假设所有的输入数据为非负数,则合适地问题陈述为 :计算一组测量数的平均数和方差,假设所有测量值为非负数 ;假设我们事先不知道有多少个测量数。一个负数的输入值将代表测量值输入的结束。 2.定义输入值和输出值这个程序的输入是未知数目的非负数。输出为这些非负数的平均数和标准差。顺便还要打印出输入数据的数据,以便于检测程序的正确性。 3.设计算法,这个程序可分为以下三大步 : 累积输入数据, 计算平均值和标准差 写出平均值、标准差 每一大步的为读取输入值。为达此目的,我们必须提示用户输入合适的值。当数据输入完毕,我们将计算出数据的个数,它们的和与平方和。这些步骤的伪代码如下所示

将n,sum_x和sum_x2初始化为0提示用户输入第一个数字读入第一个xwhile x >=0 (当x大于等于0时)n←n+1 (n加1)sum_x←sum_x + x (sum_x加上x)sum_x2←sum_x2 + x^2 (sum_x2加上x的平方)提示用户输入下一个数字读入下一个xend(循环结束)

注意我们必须在 while 循环开始之前,我们必须读取第一个值,这样在 while 循环第一次运行中才有了检测值。下一步,我们要计算出数学期望和标准差。这个步骤的伪代码就是公式(4.1)和(4.2) 的 matlab 版本。

x_bar ← sum_x / nstd_dev ← sqrt((n*num_x2 – sum_x^2) / (n*(n-1)))

最后我们写出输出结果

写出平均值x_bar写出标准差std_dev写出输入数据点的数量n

4.将伪代码转化为相应的 matlab 语句最终的 matlab 程序如下

% 脚本文件: stats_1.m%% 目的:% 计算包含任意数量输入值的输入数据集的平均值和标准差。%% 定义变量:% n——输入样本数% std_dev——输入样本的标准差% sum_x——输入值之和% sum_x2——输入值平方的和% x——一个输入数据值% xbar——所有输入数据的平均值% 初始化求和n = 0; sum_x = 0; sum_x2 = 0;% 读入第一个值x = input('Enter first value: ');% while循环来读取输入的值。while x >= 0% 累计求和。n = n + 1; sum_x = sum_x + x; sum_x2 = sum_x2 + x ^ 2;% 读入下一个值x = input('Enter next value: '); end% 计算均值和标准差。x_bar = sum_x / n; std_dev = sqrt((n * sum_x2 - sum_x ^ 2)/(n*(n-1)));% 输出结果fprintf('This data set的平均值为: %f\n', x_bar); fprintf('标准差:%f\n', std_dev); fprintf('数据点数:%f\n', n);

5.检测程序为检测这个程序,我们将手工算出一组简单数据的平均数和标准差,然后与程序产生的结果进行比对。如果我们用三个输入值:34 和 5,那么它的平均数和标准差分别为

这个结果说明了程序的正确性。在这个例子中,我们并没有完全遵循设计过程。这个失误导致这个软件有一个致命的缺陷。你能指出来它吗” />我们的错误就在于我们没有检测程序所有可能的输入类型。请重看一遍程序。如果我们不输入数或者只输入一个数,那么上面的公式就会出现除以 0 的情况。这种除 0 错误将会在导致在命令窗口内出现 divide-by-zero 的警告,导致输出值为无穷大(NaN)。我们需要修改这个程序来解决这个问题,告诉用户这个问题是什么,并在适当的时侯停止。这个程序的修定版本为 stats_2。在运行运算之前,我们必须检查是否有足够多的输入值。如果没有,程序将打印出错误提示信息,并且跳出。你自己检测一下这个版本的程序。 注意平均数和标准差可以通过 MATLAB 的内建函数 mean std 计算得到,输入数据存储在一个向量内,并把向量作为函数的参数。

% 脚本文件: stats_2.m %% 目的:% 计算包含任意数量输入值的输入数据集的平均数和标准偏差。%% 修改记录:% 日期 程序员 修改描述% ==== ========== =============================% 12/05/97 S. J. Chapman 原始代码% 1. 12/06/97 S. J. Chapman 如果输入值为0或1,修正除以0的错误。%% 定义变量:% n——输入样本数% std_dev——输入样本的标准差% sum_x——输入值之和% sum_x2——输入值平方的和% x——一个输入数据值% xbar——所有输入数据的平均值% 初始化求和。n = 0; sum_x = 0; sum_x2 = 0;% 读入第一个值。x = input('输入第一个数: ');% while循环来读取输入的值。while x >= 0% 累计求和。n = n + 1;sum_x = sum_x + x;sum_x2 = sum_x2 + x^2;% 读入下一个值。 x = input('输入下一个数: '); end % 检查是否有足够的输入数据。if n < 2 % 不足的信息 disp('至少必须输入两个数!'); else % 输入信息充足,所以 % 计算平均值和标准偏差。 x_bar = sum_x / n;std_dev = sqrt( (n * sum_x2 - sum_x^2) / (n * (n-1)) );% 告诉用户。 fprintf('这组数据的平均数是: %f\n', x_bar);fprintf('标准偏差是:%f\n', std_dev);fprintf('数据点数为:%f\n', n); end