GNU Octave 流程控制

GNU Octave 流程控制


我们知道在C语言、C++等高级编程语言中必要的一类语句是流程控制,诸如:"for"、“while”、"if"这些语句,并且如何定义和使用方程。

for循环

下面先来看"for"循环
要先要将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到10是一样的。

你也可以写disp(i),也能得到一样的结果,实际上都是一个"for"循环。

如果你对"break"和"continue"语句比较熟悉,Octave里也有"break"和"continue",你也可以在Octave环境里使用那些训练语句。

while循环

在此之前先来看一下在一个while循环中是如何工作的?


出现这个结果要怎么理解呢?这里让i取值从1开始,然后我要让v(i)等于100,再让i递增1,直到i大于5时停止。

现在来看一下结果,我现在已经取出了向量的前五个元素,把他们用100覆盖掉,这就是一个while循环的句法结构。

break和continue

现在我们来分析另外一个例子。

这里我将向你展示如何使用break语句。比方说v(i) = 999,然后让i=i+1,当等于6的时候break(停止循环),结束(end)。

上面使用了一个if语句,这里的逻辑是,让i等于1,然后开始下面的增量训练,while语句重复设置v(i)等于999,不断让i增加,然后当i达到6,做一个中止循环的命令,尽管有while循环,语句也就此中止。所以最后的结果是取出向量v的前5个元素,并且把他们设置为999。

所以这就是if语句和while语句的句法结构。并且要注意要有end,上面的例子里第一个end结束的是if语句,第二个end结束的是while语句。

if语句

下面我们来看if-else语句。

这里需要提醒的一件事是:如果你需要退出Octave,你可以输入exit命令然后回车就会退出Octave,或者命令quit也可以。

定义和调用函数

最后让我们来说说函数(functions),如果定义和调用函数。
这里通过命令在桌面上预先定义的文件名为“squarethisnumber.m”,这就是在Octave环境下定义的函数。

由于是在linux环境下,因此这里使用gedit文本编辑器进行编辑。
下面我们开始在Octave下进行定义函数:


该文件第一行写着function y = squareThisNumber(x),这就告诉Octave,我想返回一个值,并且返回的这个值将被存放于变量y中里。
另外,它还告诉了Octave这个函数有一个参数,就是参数x,还有定义的函数体,也就是y等于x的平方。

还有一种更高级的功能,这只是对那些知道"search path(搜索路径)"这个术语的人使用的。
所以如果你想要修改Octave的搜索路劲,你可以把下面这部分作为一个进阶知识,或者选学材料,仅适用于那些熟悉编程语言中搜索路径概念的同学。

你还可以使用addpath命令添加路径,添加当前工作路径将该目录添加到Octave的搜索路径,这样即使你跑到其他路径底下,Octave依然知道会在该目录下寻找函数。
这样,即使你在不同的目录下,它仍然知道在哪里可以找到"SquareThisNumber"这个函数。

但如果你部署需搜索路径这个概念也不用担心,只要确保在执行函数之前,先用cd命令设置到你函数所在的目录下,实际上也是一样的效果。

Octave还有一个其他许多编程语言都没有的概念,那就是它可以允许你定义一个函数,使得返回值是多个值或多个参数。

这里就是一个例子,定义一个函数叫:"SquareAndCubeThisNumber(x)"(x的平方以及x的立方)
这说的就是函数返回值是两个:y1和y2,接下来就是y1是被平方后的结果,y2是被立方后的结果,这就是说,函数会返回两个值。

有些同学可能会根据你使用的编程语言,比如你们可能熟悉的C或C++,通常情况下,认为作为函数返回值只能是一个值,但Octave的语法结构就不一样,可以返回多个值。

这时如果我们输入[a,b] = SquareAndCubeThisNumber(5),然后a就等于25,b就等于5的立方125.

所以说如果你需要定义一个函数并且返回多个值,这一点常常会带来很多方便。
最后,我来给大家演示一下一个更复杂啊一点的函数的例子。

比方说,我有一个数据集,像这样,数据点[1,1],[2,2],[3,3],下面想做的事是定义一个Octave函数来计算代价函数j(O),就是计算不同的O值所对应的代价函数J。
首先让我们把数据放到Octave里,我把我的矩阵设置为X=[1 1; 1 2; 1 3];

下面请仔细看一下这个函数的定义,确保你明白了定义中的每一步。

现在当我在Octave里运行时,我输入J = costFunctionJ(X,y,theta),它就计算出J等于0,这是因为如果你的数据集x为[1;2;3],y也为[1;2;3]然后设置theta0等于0,
theta1等于1,这给了我们恰好45度的斜线,这条线是完美拟合这个数据集的。

而相反地,如果我设置theta等于[0:0],那么这个假设就是0是所有的预测值,和刚才一样,设置theta0=0,theta1也等于0,然后计算的代价函数,结果是2.333.实际上,他就等于1的平方,
也就是第一个样本的平方误差,加上2的平方,加上3的平方,然后除以2m,也就是训练样本数的两倍,这就是2.33。

因此这也反过来验证了我们这里的函数,计算出了正确的代价函数。
这些就是我们用简单的训练样本尝试的几个试验,这也可以作为我们对定义的代价函数J进行完善性检查,确实是可以计算出正确的代价函数的。
至少基于这里的x和y是成立的。也就是我们这几个简单的训练集,至少是成立的。

posted @ 2022-02-01 10:58  Xu_Lin  阅读(122)  评论(0编辑  收藏  举报