许文立,安徽大学经济学院/CIMERS,

宏观经济研学会(CIMERS)的共享网盘的文件已经转移至“量化经济分析平台”及其论坛(交流中心)()。

前面的50多期DSGE建模与编程大部分都是理论模型的相关讲解,可在公众话对话窗口回复DSGE查看往期汇总。往后,就给大家带来软件编程的一些入门级介绍。今天先给大家介绍一下Matlab入门。

Matlab入门

Matlab是Matrix Laboratory的缩写。它是一款非常流行,且功能强大的编程语言。在Matlab环境下,我们可以进行矩阵运算,函数和数据图形,算法运行,用户界面制作,以及提供其它编程语言编写的程序接口。Matlab是一款公认的功能十分强大的数学与工程软件。但是,遗憾的是,它是一款收费软件,而且价格不菲(即使这样,也难不倒千千万万聪明的中国人)。

Matlab功能虽然十分强大,但是它也有擅长和不擅长的事情:(1)它的优势在于矩阵、矩阵运算和一些线性代数运算;(2)除第一条外,其它都不擅长(当然,这是与其它编程语言相比)。学习Matlab的目的就是要充分发挥它的优势,且尽可能避免其劣势。

1、基本计算

成功安装Matlab之后,双击Matlab图标,我们会看到下列窗口:

在命令行窗口,我们可以看到光标“>>”,这意味着matlab准备好了,我们可以在此处输入指令。在光标后,我们可以输入:加“+”、减“-”、乘“*”、 除“/”、指数“” 和小括号"()"等等我们常用的数学和计算符号,函数等命令。

在matlab中,用“[]”来创建一个向量。每个元素之间用空格或者逗号“," 来隔开。每一行用分号来区分。例如

注意:(1)ans是默认的结果变量。我们也可以自定义结果变量。(2)Matlab中遵循四则运算法则。

2、矩阵运算

矩阵或数组是Matlab运算的基本元素。一个1*1矩阵就是一个标量或者单个数,而只有一行或一列的矩阵就是行向量或者列向量。例如下列两个矩阵的基本运算:

Matlab还可以执行矩阵的内积、点乘、点除和幂运算。唯一的要求是向量的长度必须相同。例如

点乘如下

3、冒号的用法

冒号“:”创建一个行向量的快捷方式。而且,冒号还可以用来查看或提取向量的某些元素。例如

注意:冒号的用法是:起始值:步长:终值。

从a1中提出第3-5个元素:

从a1中提取第2,4,6个元素:

Matlab还有强大的作图功能。

在Matlab里创建一个2D图的基本函数是plot(.)。例如,作出抛物线Y=X^2的图

得到如下图

如果想显示X的范围:

得到如下图

还可以在上图中加入图标题,X轴和Y轴的标题:

得到如下图

而作3D图形的函数为plot3(.)。其基本用法与plot相似,只是多了一个元素。例如,作出Y=(XZ)^2 的图:

得到如下图

还可以用meshgrid(.)函数作出两个变量的面:

得到如下图

还可以画出它们的等高线:

\begin{figure}[H]

\includegraphics[scale=0.5]{FIG/contours}

\end{figure}

得到如下图

\begin{figure}[H]

\includegraphics[scale=0.2]{FIG/contours1}

\end{figure}

5、Boolean表达式和循环

5.1、Boolean表达式

当我们试图在某些条件下才执行程序时,我们首先需要判断这些条件(或陈述)是否为“真”,这些条件被称为“布林表达式”。

当我们在命令窗口输入“2>1”时,Matlab会输出一个整数“0”或“1”,即告诉我们输入的表达式是否为“真”(1表示“真”,0表示“假”)。

除此之外,还有其他一些关系符号:

>=表示大于或等于;

<表示严格小于;

<=表示小于或等于;

==表示等于(注意:两个等号);

~表示“非”。

我们也可以用“&(和)”或者“|(或)”来连接几个布林表达式,例如

对于Matlab来说,循环(loop)是指只要给定的布林陈述为“真”就执行某些指定的命令集。循环包括三种类型:while循环、for循环和if循环。它们各有优势和劣势。注意:我们要尽可能的避免使用循环语句,因为循环并不是矩阵运算,它们会使得Matlab代码运行得极其缓慢。

while循环执行的是当(while)一个布林陈述为“真”时的命令集。

我们首先要输入“while”来陈述条件,然后增加需要执行的命令。当我们想要命令集停止执行时,要输入“end”。例如,求0 到10的整数之和:

在上例中

i表示一个整数变量,指代我们使用的整数;n也表示一个整数变量,指代我们求和的结果。在求和的每一步,n的值都有表达式“$n=n+i$” 来升级。那么,Matlab 如何读取while循环命令呢?

第一步,读取布林陈述的右边,n+i,然后将其值暂时储存到工作区,例如,i=0时,n=0,那么n+i=0,0这个值就会暂时储存在工作区;

第二步,创建一个新的变量,n,让新的n等于储存在工作区的临时值,例如,新创建的n要等于工作区的值,即n=0;

第三步,当while循环中的布林陈述为“真”时,重复前两步,并不断升级n的值,直到求出最终的结果,例如,当i=1时,因为第二步中的n=0,所以n+i=0+1=1,1这个值就储存在工作区,然后新创建的n就等于1,重复这些步骤,最终得到n=55。

if循环执行的是“如果(if)”给定布林陈述为“真”的命令集。

其语法结构与while循环类似:以if开始,end结束。例如,我们在上述整数求和的基础上,继续求解偶数之和。

在上述偶数求和的例子中,我们在while循环中加入了if表达式。对于每一个i的值,matlab都要检验这个if表达式,如果i 是偶数,那么,执行n=n+1运算。注意:每一个布林表达式都需要在命令集结尾处加上"end"。

for循环,严格来说,它并不像while和if循环一样,只要给定的布林表达式为“真”就执行命令集。它是对于一个“指示变量”值执行给定命令集。例如,while和if循环中的整数求和,使用for循环可以使用一种更为简洁的方式来执行,即创建一个n*1阶向量。

首先,计算整数的和

然后,计算偶数的和

这里使用了冒号,我们可以回忆一下前文对冒号“:”用法的阐述。即“0:2:10”告诉Matlab创建一个从0到10的向量,步长为2,即0,2,4,6,8,10。

注:Matlab的优势在于矩阵处理,而布林表达式也可以用于矩阵。

6、自定义函数

在命令窗口直接输入命令会遇到很多问题,尤其是程序较长时。Matlab 也为我们提供了另一种代码编辑窗口——脚本窗口。脚本窗口中可以输入一系列命令,我们将这些命令保存为matlab默认文件——m文件(之所以称为m文件是因为文件的后缀为.m)。

如果m文件不需要外部输入(input),这些命令就可以运行,那么,这个文件称为脚本(scripts)文件。

另一种m文件就是函数(function)。函数文件的命令需要外部输入才能运行。

注:m 文件的名字应该与函数的名字相同。我们可能想要用自定义函数来求解DSGE 模型的稳态。

例如,定义一个简单的抛物线函数f(x)=x^2。其中,x是外部输入,函数f返回到x^2的值。

首先要新建脚本,也就是m文件:

定义函数:

要创建一个函数文件:

第一步,我们需要在第一行命令以“function” 开始,然后紧接着是该函数的输出(在上例中,y 是输出),等于函数名(例子中是“sqr”)和输入(x)。

第二步,编写出我们的相关命令。例子中就是给输出y赋值,赋值为输入x的平方。

更加复杂的函数可能有多个输入和多个输出,或者不同类型的输入和输出(例如,矩阵,字符或其它函数)。

为了调用sqr.m文件,我们只需要在matlab命令窗口输入:

此外,我们还可以利用所谓的“in-line”函数在matlab的命令窗口中直接编写简单的函数:

第一行命令就是定义函数,等号左边是函数名“sqr_inline",等号右边”@(x)”告诉Matlab,我们定义一个输入为x的函数,紧接着就是告诉Matlab该函数的返回值(输出值)x^2。例如,我们调用函数“sqr_inline", 输入为3,返回值为9。

下面,我们来编写一个更复杂的函数文件:计算前n个整数的和,整数n 是函数的输入。

保存上述文件,文件名为函数名:sum\_integers.m。现在,我们来调用这个函数,计算整数求和。

Matlab中也内置了一些常用的函数。

1、函数最小值

例如,我们想要解出使得抛物线f(x)=x^2最小的x。此时,我们可以使用Matlab内置的最小化函数“fminunc”。

上例中,第一行先定义了in-line函数f。第二行命令,用函数“fminunc” 来解出使函数f最小的x值。函数“fminunc”有两个输入元素:最小化目标函数f}和x的初始猜测值1。

更多关于函数“fminunc”的信息,请查看帮助文件或在线资源。Matlab中更多的最优化函数请参见Matlab的帮助文档或在线资源。

2、求根问题

另一个常用的函数就是求根问题,即解方程的根——找到x的值使得函数f(x)=0。常用的求根函数是“fsolve”:例如,求解函数f(x)=x^2-2 的根

需要注意的是,通用目的的函数运算并不是矩阵运算,因此,Matlab并不善于此。但是,Matlab比较善于做线性运算,因此,如果我们能将非线性方程转化为线性方程,那么,matlab还是可以很好的胜任。例如,上例中,虽然我们要求解f(x)=x^2-2的根,但是matlab求解x-\sqrt{2}=0的根,因此,我们看到最后的结果输出只有1.4142。

当然,为了求解线性方程的根,Matlab还内置了许多其它的求根函数,请参见Matlab的帮助文档或在线资源。

7、读取数据

上面,我们已经尝试了一些创建数据文件的命令。但是,在实践中,我们通常需要直接读取外部数据文件,尤其是非m文件和mat文件。例如,我们要读取最常见的excel文件。幸运的是,Matlab可以直接读取excel 文件。

例如,我们的excel文件名为“template.xlsx”,用matlab读取该文件

其中,Y表示读入文件所保存的变量名称,xlsread表示excel文件读取函数,template.xlsx (或者filename.xls)表示excel数据文件。需要注意的是,数据文件要用英文字符下的单引号括起来。

更多信息可持续关注“量化经济分析平台”及其论坛(交流中心)。