0:00
在这段视频中告诉你怎样为你的 Octave 程序写控制语句诸如"for" "while" "if" 这些语句并且如何定义和使用方程这是我们的 Octave 窗口我先告诉你
首先 我要将 v 值设为一个10行1列的零向量现在 我要写一个 “for" 循环让 i 等于 1 到 10写出来就是 i = 1:10让我们来看看我要设 v(i) 的值等于 2 的 i 次方循环最后结束 (end)这里的空格没关系所以我就加一些空格让缩进后的代码看起来结构更清晰但是你要知道这里的空格没有意义如果按我这样做 那么向量 v 的值就是这样一个集合 2的一次方2的二次方 依此类推于是这就是我的 i 等于 1 到 10的语句结构让 i 遍历 1 到 10的值另外 你还可以通过设置你的 indices (索引) 等于 1一直到10来做到这一点这时 indices 就是一个从1到10的序列你也可以写 i = indices
1:15
这实际上和我直接把 i 写到 1 到 10 是一样你可以写 disp(i)也能得到一样的结果所以 这就是一个 “for” 循环如果你对 “break” 和 “continue” 语句比较熟悉Octave里也有 “break” 和 “continue” 语句你也可以在 Octave环境里使用那些循环语句但是首先让我告诉你一个
的这是我的 v 向量让我们写个 while 循环i = 1 ;while i <= 5 ;让我们设置v(i) 等于 100然后 i 加 1结束 (end)所以这是什么意思呢我让 i 取值从 1 开始然后我要让 v(i) 等于 100再让 i 递增 1直到 i 大于 5停止现在来看一下结果原来的向量 v 是2的这些次方我现在已经取出了向量的前五个元素把他们用100覆盖掉这就是一个while循环的句法结构现在我们来分析另外一个例子i = 1; while true,这里我将向你展示如何使用break语句比方说 v(i) = 999然后让 i = i+1当 i 等于6的时候 break (停止循环)
2:47
结束 (end)当然这也是我们第一次使用一个 if 语句 所以我希望你们可以理解这个逻辑让 i 等于1 然后开始下面的增量循环while语句重复设置 v(i) 等于1 (此处口误 应为999 译者注)不断让i增加然后当 i 达到6做一个中止循环的命令尽管有while循环 语句也就此中止所以最后的效果是取出向量 v 的前5个元素并且把它们设置为999然后运行 的确如此我们用999覆盖了 v 的前五个元素所以 这就是if 语句和 while 语句的句法结构并且要注意 要有end这里是有两个 end 的这里的 end 结束的是 if 语句第二个 end 结束的是 while 语句现在让我告诉你使用 if-else 语句时更一般的句法结构举个例子 v(1)等于999 假设我们令 v(1) 等于2所以 让我输入if v(1) == 1, disp('The value is one');
3:56
这里出现了一个else语句或者更确切地说 这里是一个elseif语句 elseif v(1) == 2,这就是说 如果这种情况下命题为真执行 disp('The value is two');
4:13
否则(else) 执行 disp('The value is not one or two');好了 这就是一个if-else语句if-else语句 记得最后有end当然了 我们刚刚设置过v(1)等于2 所以显然显示的是 "The value is two"最后 我觉得现在提醒一件事如果你需要退出 Octave你可以键入 exit 命令然后回车就会退出 Octave或者命令 ‘quit’也可以最后 让我们来说说函数 (functions)如何定义和调用函数这是我的桌面我在桌面上存了一个预先定义的文件 名为 “squarethisnumber.m”这就是在 Octave 环境下定义的函数你需要创建一个文件用你的函数名来命名 然后以 .m 的后缀结尾当 Octave 发现这文件它知道应该在什么位置寻找 squareThisNumber.m 这个函数的定义让我们打开这个文件请注意 我使用的是微软的写字板程序来打开这个文件我只是想建议你如果你也使用微软的 Windows 系统那么可以使用写字板程序而不是记事本 来打开这些文件如果你有别的什么文本编辑器 那也可以但记事本有时会把代码的间距弄得很乱如果你只有记事本程序那也能用但最好是如果你有写字板的话我建议你用写字板或者其他可以编辑函数的文本编辑器现在我们来说如何在 Octave 里定义函数我们先来放大一点这个文件只有三行第一行写着 function y = squareThisNumber(x)这就告诉 Octave我想返回一个 y 值我想返回一个值并且返回的这个值将被存放于变量 y 里另外 它告诉了 Octave这个函数有一个参数就是参数 x还有定义的函数体也就是 y 等于 x 的平方现在让我们尝试调用这个函数SquareThisNumber(5)这实际上是行不通的Octave 说这个方程未被定义这是因为 Octave 不知道在哪里找这个文件所以像之前一样 我们使用 pwd现在不在我的目录下因此我们把路径设为 "C:\User\ang\desktop"这就是我的桌面的路径噢 打错了应该是 "Users"现在如果我键入SquareThisNumber(5)返回值是25还有一种更高级的功能这只是对那些知道“search path (搜索路径)” 这个术语的人使用的所以如果你想要修改 Octave的搜索路径你可以把下面这部分作为一个进阶知识或者选学材料仅适用于那些熟悉编程语言中搜索路径概念的同学你可以使用addpath 命令添加路径添加路径 “C:\Users\ang\desktop”将该目录添加到Octave 的搜索路径这样即使你跑到其他路径底下Octave依然知道会在 Users\ang\desktop目录下寻找函数这样 即使我现在在不同的目录下 它仍然知道在哪里可以找到 “SquareThisNumber” 这个函数明白吗?但是 如果你不熟悉搜索路径的概念不用担心只要确保在执行函数之前 先用 cd 命令设置到你函数所在的目录下实际上也是一样的效果Octave 还有一个其他许多编程语言都没有的概念那就是它可以允许你定义一个函数使得返回值是多个值或多个参数这是一个例子定义一个函数叫“SquareAndCubeThisNumber(x)” (x的平方以及x的立方)这说的就是函数返回值是两个 y1 和 y2接下来就是y1是被平方后的数 y2是被立方后的结果这就是说 函数会真的返回2个值所以 有些同学可能会根据你使用的编程语言比如你们可能熟悉的C或C++通常情况下 认为作为函数返回值只能是一个值但 Octave 的语法结构就不一样可以返回多个值现在回到 Octave 窗口如果我键入= SquareAndCubeThisNumber(5)然后a 就等于25b 就等于5的立方 125所以说如果你需要定义一个函数并且返回多个值这一点常常会带来很多方便最后 我来给大家演示一下一个更复杂一点的函数的例子比方说 我有一个数据集像这样 数据点为, ,我想做的事是定义一个 Octave 函数来计算代价函数 J(θ)就是计算不同 θ 值所对应的代价函数值 J首先让我们把数据放到 Octave 里我把我的矩阵设置为X = ;这就是我的设计矩阵 X第一列表示x0项矩阵的第一列第二列表示我的三个训练样本的 x 值现在我再来设置 y 值为就像这样 是y轴对应值现在我们设定 theta为现在我的桌面上已经有我预定义的代价函数 J如果我打开函数函数的定义应该是下面这样的所以 函数J 就写成J = costFunctionJ(X, y, theta)这里有一些注释主要用于解释输入变量接下来几步设定 m 为训练样本的数量也就是 X 的行数计算预测值 predictions预测值等于 X 乘以 theta这里是注释行是上一个注释行拐过来的部分下面就是计算平方误差 公式就是预测值减去 y 值然后取出来每一项进行平方最后就可以计算代价函数 J并且 Octave 知道J 是一个我想返回的值因为 J 出现在了我函数的定义里另外 你可以随时暂停一下视频如果你想仔细看一下这个函数的定义确保你明白了定义中的每一步现在当我在 Octave 里运行时我键入 j = costFunctionJ(x, y, theta)然后他就开始计算 噢 又打错了这里应该是大写 X它就计算出 j 等于0这是因为 如果我的数据集x 为 y 也为 然后设置 θ0 等于0θ1 等于1这给了我恰好45度的斜线这条线是可以完美拟合我的数据集的而相反地 如果我设置theta 等于那么这个假设就是0是所有的预测值和刚才一样 设置θ0 = 0θ1 也等于0然后我计算的代价函数结果是2.333实际上 他就等于1的平方也就是第一个样本的平方误差加上2的平方加上3的平方然后除以2m也就是训练样本数的两倍这就是2.33因此这也反过来验证了我们这里的函数计算出了正确的代价函数这些就是我们用简单的训练样本尝试的几次试验这也可以作为我们对定义的代价函数 J进行了完整性检查确实是可以计算出正确的代价函数的至少基于这里的 X和 y 是成立的也就是我们这几个简单的训练集至少是成立的好啦 现在你知道如何在 Octave 环境下写出正确的控制语句比如 for 循环、while 循环和 if 语句以及如何定义和使用函数在接下来的视频中我会非常快的介绍一下如何在这门课里完成和提交作业如何使用我们的提交系统在此之后在最后的 Octave 教程视频里我会讲解一下向量化这是一种可以使你的 Octave 程序运行非常快的思想